Non-static driver and screenshot listener in TestNG

I have a test file that will call the driver as a non-stationary variable. I also added a screenshot listener in my test case. When the test fails, the control is automatically sent to the screenshot listener ... however, since my driver is a UNSTEADY variable, it could not be accessed in the screenshot listener. Therefore, I get a nullpointer exception.

Is there a way to globally access a non-stationary driver in a screenshot listener?

My test case:

@Test public void testCase() { //non-static driver is initialized } 

My screenshot listener:

 public class ScreenshotListener extends TestListenerAdapter { @Override public void onTestFailure(ITestResult testResult) { //driver needs to be accessed here } } 
+4
source share
4 answers

You do not need to skip the driver or cause a test failure during the test (this means that it hits the point of the listeners of the test);

Below are screenshots in listeners without passing the driver;

  • All test classes should extend a simple base test class;

     public asbtract baseTestCase() { private WebDriver driver; public WebDriver getDriver() { return driver; } @BeforeMethod public void createDriver() { Webdriver driver=XXXXDriver(); } @AfterMethod public void tearDownDriver() { if (driver != null) { try { driver.quit(); } catch (WebDriverException e) { System.out.println("***** CAUGHT EXCEPTION IN DRIVER TEARDOWN *****"); System.out.println(e); } } } 
  • In your listener, you need to access the base class;

Public class ScreenshotListener extends TestListenerAdapter {

 @Override public void onTestFailure(ITestResult result) { Object currentClass = result.getInstance(); WebDriver webDriver = ((BaseTest) currentClass).getDriver(); if (webDriver != null) { File f = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE); //etc. } } 

Now your test does not realize that screenshots are even captured and can be controlled by adding a listener.

+9
source

If you need something to access your driver, you need to pass a link to the driver as an argument wherever the execution thread goes,

 // i assume onTestFailure method has been called explicitly. @Test public void testCase() { Webdriver driver=XXXXDriver(); try { // your tests } catch(Exception e) { onTestFailure(new ITestResult (),driver) } public class ScreenshotListener extends TestListenerAdapter { @Override public void onTestFailure(ITestResult testResult,Webdriver driver) { // you can access your driver here } } 
0
source

I was about to go for the solution provided by Robbie, but wanted to avoid binding my base class. Since I used Guice to inject my WebDriver provider, I decided to pass the instance through the TestNG attribute, connecting it once in the installation test class as follows:

 public class Setup { @Inject WebDriver driver; @BeforeSuite public void onStart(ITestContext testContext) { testContext.setAttribute("WebDriver", this.driver); } } 

Then in my listener I just pulled it out:

 @Override public void onTestFailure(ITestResult result) { Object webDriverAttribute = result.getTestContext().getAttribute("WebDriver"); // test, cast, and use... 

I was hoped for the best way that did not require casting, but had not yet found it.

0
source

If you want to access the driver everywhere in the project, then define wedDriver, as shown below, in the browser settings class, for example

 public class BrowserSetup{ private WebDriver driver; public WebDriver getDriver() { return driver; } use rest of code } 

And use the following code in a test listener

 public class TestNgListener extends BrowserSetup implements ITestListener, ISuiteListener, IInvokedMethodListener{ WebDriver driver =null; @Override public void onTestFailure(ITestResult arg0) { Object currentClass = arg0.getInstance(); WebDriver driver = ((BrowserSetup) currentClass).getDriver(); //this.driver = ((BrowserSetup)currentClass).getDriver; // This is calling the printTestResults method try { getScreenshot(arg0.getTestName(), driver); System.out.println("Screenshot taken"); } catch (Exception e) { // TODO Auto-generated catch block System.out.println("Exception while takescreenshot "+e.getMessage()); //e.printStackTrace(); } printTestResults(arg0); } 
0
source

Source: https://habr.com/ru/post/1491031/


All Articles