How to refer to the Webdriver object in selenium without making it static to take screenshot through Testng listeners

191 views
Skip to first unread message

Kasun Herath

unread,
May 2, 2023, 1:38:55 AM5/2/23
to testng-users

Hi Im stuck in a situation where I have declared my driver object in the test class and I have some wrappers developed in another class , all the respective variables are not static including the driver object , so now I want to take a screenshot on failure using testng listerners (I have created a custom listener class implementing to ITestListener) and when I refer to the driver object it throws a null exception probably due to driver not been static , how can I still achieve to take a screenshot without making the driver static , any testng related work around will also be helpful

this is the code line in my custom listenerclass

onTestFailure(){ bufferImage = driver.getScreenshot(); //throws null , getScreesnshot comes from my wrapper class }

⇜Krishnan Mahadevan⇝

unread,
May 3, 2023, 10:32:21 AM5/3/23
to testng...@googlegroups.com
From within your "@Test" method, you could basically try to set the WebDriver instance as an attribute to your "ITestResult" object and then you can query it from within any of the TestNG listeners (Please ensure you are working with the latest released version i.e., 7.7.1)

Here's a sample that shows what am talking about (I have intentionally not used any webdriver stuff but the sample should conceptually demonstrate what I am hinting at )

Java
import com.rationaleemotions.threadsafe.TestClassExample.ExampleListener;
import java.util.Objects;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
import org.testng.Assert;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(ExampleListener.class)
public class TestClassExample {

  private static final String ATTRIBUTE = "test.data";

  @BeforeMethod
  public void beforeMethod(ITestResult itr) {
    //Replace this with your webdriver instantiation logic
    Data data = new Data(UUID.randomUUID().toString());
    itr.setAttribute(ATTRIBUTE, data);
    ExampleListener.prettyPrint("BeforeMethod", itr);
  }

  @Test
  public void passingTest() {
    ITestResult itr = Reporter.getCurrentTestResult();
    ExampleListener.prettyPrint("TestCase", itr);
  }

  @Test
  public void failingTest() {
    ITestResult itr = Reporter.getCurrentTestResult();
    ExampleListener.prettyPrint("TestCase", itr);
    Assert.fail("Simulating a failure");
  }

  public static class ExampleListener implements ITestListener {

    @Override
    public void onTestSuccess(ITestResult result) {
      Data data = prettyPrint("onTestSuccess", result);
      // The close() method is similar to you doing driver.quit()
      data.close();
    }

    @Override
    public void onTestFailure(ITestResult result) {
      Data data = prettyPrint("onTestFailure", result);
      // The close() method is similar to you doing driver.quit()      
      data.close();
    }

    public static Data prettyPrint(String prefix, ITestResult itr) {
      Data data = (Data) itr.getAttribute(ATTRIBUTE);
      Objects.requireNonNull(data, "Should have had a valid data object");
      String msg = String.format("[%s] %s() ==> %s", prefix, itr.getMethod().getQualifiedName(), data);
      System.err.println( msg);
      return data;
    }
  }

  @AllArgsConstructor
  @Getter
  @ToString
  public static class Data {

    private final String content;

    public void close() {
      System.err.println("Simulating a close operation");
    }
  }
}


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/testng-users/5bd6048c-765a-410a-bd1b-92497f5a7119n%40googlegroups.com.

Kasun Herath

unread,
May 11, 2023, 3:39:52 AM5/11/23
to testng-users
Thank you for your prompt response , actually this approach is working , but my requirement is still not achieved 

Context : I brought up this question using Selenium and Java to make the problem more clear , but actually what I'm using is Playwright Java 

Question :  I'm using Playwright with Java to develop a wrapper framework and I have created a custom listener class implementing ITestListener to take screenshot on failure using playwright methods, I only use one Page object in my test class which I overrides with new pages as wanted , but the ItestContext page reference does not get overridden by the latest page value I have set in my test method , how can I achieve ItestContext.setAttribute to update the latest page value on run time, as per my @Test Method line 3

Code :
@BeforeClass
    public void init(ITestContext iTestContext) {
        iTestContext.setAttribute("Page_Reference", page);    //page comes from my inherited BaseClass
    }

@Test(description = "Testing Screenshot by Overriding Practice")
    public void navDishLandPage() {
        page.goTo("https://github.com/");            //page reference comes from my base class - 1
        Page originalPage = page;                      //stores page reference to later access - 2
        page = getPage("User");                       //Overrides the previous page reference by new Page ; getPage("Key") is a wrapper method -3
        page.goTo("https://github.com/cbeust/testng/issues/2905");
        page = originalPage;                         //switching back to the stored page reference
        System.out.println(page.getTitle());
        Assert.assertEquals(page.getTitle(), "TTT");
    }

Inside My onTestFailureMethod
        Page page = (Page) iTestResult.getTestContext().getAttribute("Page_Reference");
        byte[] bufferImage=page.screenShot();



Kindly looking forward for a possible solution.

Thank You!

⇜Krishnan Mahadevan⇝

unread,
May 11, 2023, 5:01:27 AM5/11/23
to testng...@googlegroups.com
I have responded to your Stackoverflow question. Please take a look.


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Kasun Herath

unread,
May 11, 2023, 8:51:54 AM5/11/23
to testng-users
Thank you for the solution! :)

Kasun Herath

unread,
May 12, 2023, 4:35:03 AM5/12/23
to testng-users
Hello Everyone , 

Requesting support for below issue which is relating to my previous questions raised ,  thanks in advance :) 

Regards
Kasun Herath

Reply all
Reply to author
Forward
0 new messages