Allure report screenshots is not taken when test got failed - java

I have made an TestListener and implement method which should make screenshot when test got failed. But if test got failed screenshot is not taken but I don't know why. If method takeScreenshot() is called the screenshot is not saved in allure results. Below I post code of TestListener and TestBase:
public class TestListener extends TestBase implements ITestListener {
#Override
public void onTestFailure(ITestResult result) {
Object testClass = result.getInstance();
driver = ((TestBase) testClass).getTestDriver();
if(driver != null) {
takeScreenshot();
}
}
#Override
public void onTestSkipped(ITestResult result) {
}
#Attachment(value = "Page screenshot", type = "image/png")
public byte[] takeScreenshot() {
setThisDriver(driver);
return ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
}
public class TestBase {
public WebDriver driver;
public static Properties prop;
public static String env;
public static String url;
public TestBase() {
try {
this.prop = new Properties();
FileInputStream ip = new FileInputStream(
"src/main/java/config/env.properties");
this.prop.load(ip);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void initialization() {
System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver");
System.setProperty("http.agent", "Mozilla/5.0");
FirefoxBinary firefoxBinary = new FirefoxBinary();
File downloadsDir = new File("src/main/documents/");
//firefoxBinary.addCommandLineOptions("--headless");
FirefoxOptions options = new FirefoxOptions();
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.folderList", 2);
profile.setPreference("browser.download.dir", downloadsDir.getAbsolutePath());
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
"application/msword, application/csv, application/ris, text/csv, image/png, application/pdf, text/html, text/plain, application/zip, application/x-zip, application/x-zip-compressed, application/download, application/octet-stream");
profile.setPreference("browser.download.manager.showWhenStarting", false);
profile.setPreference("browser.download.manager.focusWhenStarting", false);
profile.setPreference("browser.download.useDownloadDir", true);
profile.setPreference("browser.helperApps.alwaysAsk.force", false);
profile.setPreference("browser.download.manager.alertOnEXEOpen", false);
profile.setPreference("browser.download.manager.closeWhenDone", true);
profile.setPreference("browser.download.manager.showAlertOnComplete", false);
profile.setPreference("browser.download.manager.useWindow", false);
profile.setPreference("services.sync.prefs.sync.browser.download.manager.showWhenStarting", false);
profile.setPreference("pdfjs.disabled", true);
//options.setHeadless(true);
options.setBinary(firefoxBinary);
//options.setProfile(profile);
this.driver = new FirefoxDriver(options);
try {
this.driver.manage().window().maximize();
this.driver.manage().deleteAllCookies();
}
catch (WebDriverException e) {
System.out.println(e.toString());
this.driver.quit();
}
}
public WebDriver getTestDriver() {
return this.driver;
}
public void setThisDriver(WebDriver webDriver) {
this.driver = webDriver;
}
public String getCurrentDate() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(
Calendar.getInstance().getTime());
return timeStamp;
}
public void captureScreenshots(String result) {
try {
TakesScreenshot ts = (TakesScreenshot) driver;
File source = ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("src/screenshots/" + getCurrentDate() + ".png"));
System.out.println("Takes screenshot");
} catch (Exception e) {
System.out.println("Exception" + e.getMessage());
}
}

Ok, if someone have the same problem here is an answer. Configuration was ok but if we want generate report with screenshots we should run tests from command line using: ./gradlew clean test and ./gradlew allureReport to generate report.

Related

NullPointerException at "new RemoteWebDriver(srvc.getUrl(), options)"

I have Three Classes as below:
And When I run the test as TestNG from 'Tests.java' I get java.lang.NullPointerException exception:
NOTE:
-It picks the browser name 'chrome' successfully from the .properties file.
-If I discard the 'Tests.java' class and move the #Test method to 'LaunchBrowserTemp.java' class and add remaining corresponding tags (i.e. BeforeClass, BeforeMethod, AfterClass, AfterMethod) to corresponding methods in 'LaunchBrowserTemp.java' it works fine. It fails only when I keep the testng annotations to the 'Tests.java' class.
src\main\java\utilities\LaunchBrowserTemp.java
public class LaunchBrowserTemp {
private static ChromeDriverService srvc;
private static WebDriver driver;
private static String browser = getProperties("selenium.browser");
private static final String baseBrowserPath = "src\\main\\resources\\drivers\\";
private static ChromeOptions options;
public static void initBrowser() throws Exception {
switch (browser.toLowerCase()){
case "chrome":
options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-extensions");
options.setAcceptInsecureCerts(true);
srvc = new ChromeDriverService.Builder()
.usingDriverExecutable(new File(baseBrowserPath + "chromedriver.exe"))
.usingAnyFreePort()
.build();
srvc.start();
break;
default:
throw new Exception("Browser Not handled in code!");
}
}
public static void stopDriverService() {
srvc.stop();
}
public void startDriver() {
driver = new RemoteWebDriver(srvc.getUrl(), options);
}
public void endDriver() {
driver.quit();
}
public static WebDriver driver() {
return driver;
}
}
src\main\java\utilities\LoadProperties.java
public class LoadProperties {
public static String getProperties(String propName) {
Properties prop = new Properties();
try {
FileInputStream fis = new FileInputStream("src/main/resources/config.properties");
prop.load(fis);
} catch (Exception e){}
return prop.getProperty(propName);
}
}
src\test\java\Tests.java
public class Tests {
LaunchBrowserTemp obj = new LaunchBrowserTemp();
#BeforeClass
public void init() throws Exception{
LaunchBrowserTemp.initBrowser();
}
#BeforeTest
public void start(){
obj.startDriver();
}
#Test
public void openUrl(){
driver().get("https://www.google.com");
}
#AfterTest
public void teardown(){
obj.endDriver();
}
#AfterClass
public void terminate() {
LaunchBrowserTemp.stopDriverService();
}
}
Error Screenshot

Error -> cucumber.runtime.CucumberException: Failed to instantiate class <class> - this class doesn't have an empty or a page enabled constructor"

I am using the FirefoxDriverInstance as the singleton for calling driver. Also, using a firefox profile to bypass 2-factor-authentication.
public class FirefoxDriverInstance {
public static WebDriver Instance = null;
public static void Initialize() {
if (Instance == null) {
System.out.println("Initializing Firefox Driver!!!");
System.setProperty("webdriver.gecko.driver","./src/test/resources/driver/geckodriver2.exe");
ProfilesIni profile = new ProfilesIni();
FirefoxOptions options = new FirefoxOptions();
options.setProfile(profile.getProfile("SeleniumTester"));
Instance = new FirefoxDriver(options);
}
Instance.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
Instance.manage().window().maximize();
}
public static void close() {
System.out.println("Closing Browser!!!");
Instance.close();
Instance = null;
}
public static void quit() {
System.out.println("Quitting Browser!!!");
Instance.quit();
Instance = null;
}
}
Below is my login code using cucumber-selenium-webdriver. I have used the same driver instance.
public class TC01_Login {
#BeforeMethod
public void openbrowser() throws IOException {
FirefoxDriverInstance.Initialize();
}
public Properties propertyFileReader() throws Exception {
Properties obj = new Properties();
FileInputStream objfile = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\resources\\testdata\\application.properties");
obj.load(objfile);
return obj;
}
WebDriverWait wait = new WebDriverWait(FirefoxDriverInstance.Instance, 150);
#Given("^user has entered the required URL$")
public void user_has_entered_the_required_URL() throws Throwable {
Properties obj = propertyFileReader();
System.out.println("In the First Loop!!");
FirefoxDriverInstance.Instance.get(obj.getProperty("baseUrl"));
String actualTitle = FirefoxDriverInstance.Instance.getTitle();
System.out.println("Actual Title :" + actualTitle);
if (actualTitle.contains("test")){
System.out.println("INFO : Title is being displayed as expected.");
}
else {
System.out.println("ERROR : Title is NOT being displayed as expected."); }
}
}
Unable to understand how to bypass this error.
Try to put below code in constructor :
FirefoxDriverInstance.Initialize();
Example:
public class TC01_Login {
public TC01_Login (){
FirefoxDriverInstance.Initialize();
}
}
Remove it from BeforeMethod

Can't make Actions.class methods work unless driver instance declared in #Test

I'm new to Selenium & new to Java as well. So maybe I'm missing something obvious, but I’m spinning on this for a while now, can't move forward & totally desperate. Please help!
Here is my set-up:
My custom Driver class implements WebDriver & sets property:
public class Driver implements WebDriver {
private WebDriver driver;
private String browserName;
public Driver(String browserName) throws Exception {
this.browserName = browserName;
if(browserName.equalsIgnoreCase("chrome")) {
System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver");
this.driver = new ChromeDriver();
}
else if(browserName.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.gecko.driver", "src/test/resources/geckodriver");
this.driver = new FirefoxDriver();
}
else {
throw new Exception("Browser is not correct");
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
<...>
}
BaseTest class gets property & creates new instance of the Driver inside #BeforeClass method (browser name passed with a maven command when running the test):
String browserName = getParamater("browser");
driver = new Driver(browserName);
In the Test class inside the #Test I create new Actions & pass there the driver from BaseTest:
Actions builder = new Actions(driver);
Action mouseOverHome = builder
.moveToElement(pb.testGoodle)
.build();
mouseOverHome.perform();
And this code doesn’t work -> no Actions performed (no mouse over or anything), no errors too.
However if I create & define new WebDriver inside the #Test itself:
System.setProperty("webdriver.gecko.driver", "src/test/resources/geckodriver");
WebDriver driver = new FirefoxDriver();
Actions perfectly working.
Any ideas or hints very appreciated!
Resolved! Resolved! The problem was in messed Actions declaration in Page Object! Here how things look in the Page Object:
protected Driver driver;
public static Actions act;
public PlanBuilder(Driver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
this.act = new Actions(driver);
}
public void rightClick (WebElement element) throws InterruptedException {
// Actions builder = new Actions(basedriver);
Action openContextMenu = driver.act
.contextClick(element)
.build();
openContextMenu.perform();
Thread.sleep(4000);
}
public class BasePage
{
public static IWebDriver driver;
public static JObject jobject;
public static JArray jarray;
public static void SeleniumInit()
{
BasePage.ReadJsonObject("InitData.json");
string browser = jobject.SelectToken("browser").Value<string>();
string Headless = jobject.SelectToken("Headless").Value<string>();
if (browser == "Chrome")
{
ChromeOptions options = new ChromeOptions();
options.AddArguments("-start-maximized");
if (Headless == "True")
{
options.AddArguments("-headless");
}
driver = new ChromeDriver(options);
}
else if (browser == "Firefox")
{
FirefoxOptions options = new FirefoxOptions();
options.AddArguments("-start-maximized");
if (Headless == "True")
{
options.AddArguments("-headless");
}
driver = new FirefoxDriver(options);
}
else
{
EdgeOptions options = new EdgeOptions();
options.AddArguments("-start-maximized");
if (Headless == "True")
{
options.AddArguments("-headless");
}
driver = new EdgeDriver(options);
}
}
public static void Write(By by, string user)
{
try
{
driver.FindElement(by).SendKeys(user);
TakeScreenshot(Status.Pass, "Write " + user);
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Write Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void Click(By by)
{
try
{
driver.FindElement(by).Click();
TakeScreenshot(Status.Pass, "Click");
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Click Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void OpenUrl(string url)
{
try
{
driver.Url = url;
TakeScreenshot(Status.Pass, "Open url: " + url);
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Open Url Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void Clear(By by)
{
try
{
driver.FindElement(by).Clear();
TakeScreenshot(Status.Pass, "Clear Text: " );
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Clear Text Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void ClickRadio(By by)
{
try
{
Actions actions = new Actions(driver);
IWebElement radioLocator = driver.FindElement(by);
actions.Click(radioLocator).Build().Perform();
TakeScreenshot(Status.Pass, "Click Radio Button");
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Radio Button Click Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void SelectOption(By by, string value)
{
try
{
var dropdown = driver.FindElement(by);
var selectDropdown = new SelectElement(dropdown);
selectDropdown.SelectByValue(value);
TakeScreenshot(Status.Pass, "Select Option from Dropdown Menu");
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Select Option Failed: " + ex.ToString());
Assert.Fail();
}
}
public static string GetElementText(By by)
{
string text;
try
{
text = driver.FindElement(by).Text;
}
catch
{
try
{
text = driver.FindElement(by).GetAttribute("value");
}
catch
{
text = driver.FindElement(by).GetAttribute("innerHTML");
}
}
return text;
}
public static void Assertion(By by, string assertText)
{
try {
string Text = GetElementText(by);
Assert.AreEqual(assertText, Text);
TakeScreenshot(Status.Pass, "Assertion Passed");
}
catch (Exception ex)
{
TakeScreenshot(Status.Fail, "Assertion Failed: " + ex.ToString());
Assert.Fail();
}
}
public static void sleep()
{
Thread.Sleep(10000);
}
public static string GetElementState(By by)
{
string elementState = driver.FindElement(by).GetAttribute("Disabled");
if (elementState == null)
{
elementState = "enabled";
}
else if (elementState == "true")
{
elementState = "disabled";
}
return elementState;
}
public static void ExplicitWait(By by)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(by));
//wait.Until(Driver => IsPageReady(Driver) == true && IsElementVisible(by) == true && IsClickable(by) == true);
//wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
//wait.Until(driver => IsElementVisible(driver, By.Id("username")) == true);
}
public static void ImplicitWait()
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);
}
public static void FluentWait()
{
DefaultWait<IWebDriver> fluentWait = new DefaultWait<IWebDriver>(driver);
fluentWait.Timeout = TimeSpan.FromSeconds(60);
fluentWait.PollingInterval = TimeSpan.FromMilliseconds(250);
/* Ignore the exception - NoSuchElementException that indicates that the element is not present */
fluentWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
fluentWait.Message = "Element to be searched not found";
}
public static void scrollDown()
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("window.scrollTo(0, document." + "Body" + ".scrollHeight);");
}
public static void switchWindow()
{
driver.SwitchTo().Window(driver.WindowHandles[1]);
}
public static void TakeScreenshot(Status status, string stepDetail)
{
string path = #"C:\ExtentReports\" + "TestExecLog_" + DateTime.Now.ToString("yyyyMMddHHmmss");
Screenshot image = ((ITakesScreenshot)driver).GetScreenshot();
image.SaveAsFile(path + ".png", ScreenshotImageFormat.Png);
ExtentReport.exChildTest.Log(status, stepDetail, MediaEntityBuilder.CreateScreenCaptureFromPath(path + ".png").Build());
}
public static void ReadJson(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jarray = JArray.Parse(myJsonString);
}
public static void ReadJsonObject(string filename)
{
string myJsonString = File.ReadAllText(#"..\\..\\..\\" + filename);
jobject = JObject.Parse(myJsonString);
}
}

Selenium Grid (RemoteWebDriver) usage with Cucumber jvm SharedDriver

I implemented cucumber-jvm picocontainer with SharedDriver and works well locally. I would like to use Selenium Grid which has been configured well but I don't know how should I modify Shareddriver class in order to use RemoteWebDriver instead of WebDriver and connect to Selenium GRID.
new RemoteWebDriver(new("http://..../wd/hub"), capability); doesn't work because I need to throw MalFormedException and REAL_DRIVER is a static field.
Any idea? Thanks!
public class SharedDriver extends EventFiringWebDriver {
private static final WebDriver REAL_DRIVER = WebDriverFactory.internetExplorerWebDriver();
private static final Thread CLOSE_THREAD = new Thread() {
#Override
public void run() {
REAL_DRIVER.close();
}
};
static {
Runtime.getRuntime().addShutdownHook(CLOSE_THREAD);
}
public SharedDriver() {
super(REAL_DRIVER);
}
#Override
public void close() {
if(Thread.currentThread() != CLOSE_THREAD) {
throw new UnsupportedOperationException(
"WebDriver should not close!"
);
}
super.close();
}
#Before
public void deleteAllCookies() {
manage().deleteAllCookies();
}
#After
public void embedScreenshot(Scenario scenario) {
...
}
}
WebDriverFactory:
class WebDriverFactory {
static {
System.setProperty("webdriver.ie.driver", "src/test/resources/webDrivers/IEDriverServer.exe");
}
static WebDriver internetExplorerWebDriver() {
DesiredCapabilities returnCapabilities = DesiredCapabilities.internetExplorer();
System.setProperty("webdriver.ie.driver", "src/test/resources/webDrivers/IEDriverServer.exe");
returnCapabilities.setCapability("requireWindowFocus", true);
returnCapabilities.setCapability(InternetExplorerDriver.ENABLE_PERSISTENT_HOVERING, false);
returnCapabilities.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, true);
returnCapabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
returnCapabilities.setCapability("ignoreZoomSetting", true);
return new InternetExplorerDriver(returnCapabilities);
}
You can wrap the return statement into a try..catch block and return null in case of exception is being thrown.
class WebDriverFactory {
static {
System.setProperty("webdriver.ie.driver", "src/test/resources/webDrivers/IEDriverServer.exe");
}
static WebDriver internetExplorerWebDriver() {
DesiredCapabilities returnCapabilities = DesiredCapabilities.internetExplorer();
System.setProperty("webdriver.ie.driver", "src/test/resources/webDrivers/IEDriverServer.exe");
returnCapabilities.setCapability("requireWindowFocus", true);
returnCapabilities.setCapability(InternetExplorerDriver.ENABLE_PERSISTENT_HOVERING, false);
returnCapabilities.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, true);
returnCapabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
returnCapabilities.setCapability("ignoreZoomSetting", true);
try {
return new RemoteWebDriver(new URL("http://www.google.com"), returnCapabilities);
} catch (MalformedURLException e) {
return null;
}
}
then, check that the REAL_DRIVER value is not null.

Appium:I hv 2 class, ClassA & ClassB.I am executing these 2 class using testng.xml file.I want to know dat for ClassB do I need to put #Beforeclass?

Class1:
public class LaunchApp {
AndroidDriver<WebElement> driver;
#BeforeTest
public void Test1() throws MalformedURLException {
DesiredCapabilities capability = new DesiredCapabilities();
capability.setCapability("deviceName", "Android");
capability.setCapability("platformName", "Android");
capability.setCapability("platformVersion", "5.1.1");
capability.setCapability("deviceName", "Samsung Galaxy On5");
capability.setCapability("app",
"D:\\whatsapp.apk");
capability.setCapability("PackageName",
"com.movocado.socialbostonsports");
capability.setCapability("ActivityName",
"com.movocado.socialbostonsports.Activity.LogInSceen");
try {
driver = new AndroidDriver<WebElement>(new URL(
"http://127.0.0.1:4723/wd/hub"), capability);
} catch (MalformedURLException e) {
e.printStackTrace();
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
Class2:
public class DrawerMenuTest {
AndroidDriver<WebElement> driver;
#Test(priority = 1)
public void DrawerMenuIcon() {
WebElement drawerMenu = driver.findElement(By
.id("com.movocado.socialbostonsports:id/rel_drawer"));
try {
drawerMenu.click();
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
Problem:
Second class is showing NullPointerException. Suggest me a solution.
You are initializing AndroidDriver into LaunchApp but does not pass this driver reference into DrawerMenuTest where you are creating only refrence variable of AndroidDriver with null that's causes of NullPointerException.
To overcome it you should create separate singlton class which will give single instance of AndroidDriver to each and every class as below :-
public class DriverInit {
private AndroidDriver<WebElement> driver;
private static DriverInit driverInit = null;
public static DriverInit getInstance() {
if (driverInit == null) {
driverInit = new DriverInit();
}
return driverInit;
}
private DriverInit() {
DesiredCapabilities capability = new DesiredCapabilities();
capability.setCapability("deviceName", "Android");
capability.setCapability("platformName", "Android");
capability.setCapability("platformVersion", "5.1.1");
capability.setCapability("deviceName", "Samsung Galaxy On5");
capability.setCapability("app", "D:\\whatsapp.apk");
capability.setCapability("PackageName", "com.movocado.socialbostonsports");
capability.setCapability("ActivityName", "com.movocado.socialbostonsports.Activity.LogInSceen");
this.driver = new AndroidDriver<WebElement>(new URL(
"http://127.0.0.1:4723/wd/hub"), capability);
this.driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
public WebDriver getDriver() {
return this.driver;
}
}
Now you can use this into LaunchApp class as below :-
public class LaunchApp {
AndroidDriver<WebElement> driver;
#BeforeTest
public void Test1() throws MalformedURLException {
driver = DriverInit.getInstance().getDriver();
//now do your stuff with this driver
}
}
And use in DrawerMenuTest class as below :-
public class DrawerMenuTest {
AndroidDriver<WebElement> driver;
#Test(priority = 1)
public void DrawerMenuIcon() {
//get driver instance first
driver = DriverInit.getInstance().getDriver();
WebElement drawerMenu = driver.findElement(By
.id("com.movocado.socialbostonsports:id/rel_drawer"));
try {
drawerMenu.click();
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
}
}
Hope it helps..:)

Categories