Advance Level Screenshot capturing using Selenium Webdriver and TestNG Listners
In my opinion, you should avoid the following:
- using static drivers (because using static variables is a bad practice)
- using static methods for taking screenshots (because using static methods is a bad practice)
- taking screenshots in the test methods (because you will duplicate code in lots of tests)
- taking screenshots in the @After methods (because you dont need to do this)
I prefer to take the screenshots using a TestNG listener as follows.
- create a class for taking the screenshots
Every time you need to take a screenshot, create an object for this class and use the capture method.
The capture method will take the screenshot and save it in the screenshots folder.
- package framework;
- import java.io.File;
- import java.io.FileOutputStream;
- import org.openqa.selenium.OutputType;
- import org.openqa.selenium.TakesScreenshot;
- import org.openqa.selenium.WebDriver;
- public class Screenshot {
- private WebDriver driver;
- private final String folderPath = "./src/test/resources/screenshots/";
- public Screenshot(WebDriver driver) {
- this.driver = driver;
- validateFolderExists();
- }
- private void validateFolderExists() {
- File folder = new File(folderPath);
- if (!folder.exists())
- folder.mkdir();
- }
- public void capture(String fileName) {
- try {
- String name = folderPath + fileName + ".png";
- FileOutputStream file = new FileOutputStream(name);
- file.write(
- ((TakesScreenshot) driver)
- .getScreenshotAs(OutputType.BYTES));
- file.close();
- }
- catch (Exception ex) {
- throw new RuntimeException("cannot create screenshot;", ex);
- }
- }
- }
2. Create a TestNG listener that takes the screenshot if the test method fails or is skipped
The listener gets the driver object from the test class through reflection.
- package framework;
- import java.lang.reflect.Field;
- import org.openqa.selenium.WebDriver;
- import org.testng.ITestContext;
- import org.testng.ITestListener;
- import org.testng.ITestResult;
- import org.testng.Reporter;
- import framework.BrowserDriver;
- import framework.Screenshot;
- public class CustomTestListener implements ITestListener {
- @Override
- public void onTestFailure(ITestResult result) {
- String fileName = "failed_" + result.getName();
- new Screenshot(driver(result)).capture(fileName);
- }
- @Override
- public void onTestSkipped(ITestResult result) {
- String fileName = "skipped_" + result.getName();
- new Screenshot(driver(result)).capture(fileName);
- }
- @SuppressWarnings("unchecked")
- private WebDriver driver(ITestResult testResult)
- {
- BrowserDriver browserDriver = null;
- try {
- Classextends ITestResult> testClass =
- (Class extends ITestResult>)
- testResult.getInstance().getClass();
- Field driverField = testClass.getDeclaredField("driver");
- browserDriver = (BrowserDriver)driverField
- .get(testResult.getInstance());
- }
- catch (SecurityException |
- NoSuchFieldException |
- IllegalArgumentException |
- IllegalAccessException e) {
- throw new RuntimeException(
- "couldnt get the driver from the test class!");
- }
- return browserDriver.wrappedDriver();
- }
- @Override
- public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
- }
- @Override
- public void onStart(ITestContext context) {
- }
- @Override
- public void onFinish(ITestContext context) {
- }
- @Override
- public void onTestStart(ITestResult result) {
- }
- @Override
- public void onTestSuccess(ITestResult result) {
- }
- }
3. add the listener to the test class using the Listener annotation
- @Listeners(CustomTestListener.class)
- public class SiteTests {
- public BrowserDriver driver;
- …………………………………..
Advantages of this approach:
- no static driver
- no static methods for taking the screenshot
- no “take screenshot” code in the test methods
- no “take screenshot” code in the @After methods
Disadvantages:
- using reflection to get the driver; complicated code for this purpose
- using null in the test listener
GUEST AUTHOR
Alex Siminiuc
Follow Us
Feel free to ask queries or share your thoughts in comments or email us.
Comments
Post a Comment