We have discussed about simple way of taking a screen shot earlier. Now in this tutorial, we will see how to take screen shot ONLY for failed tests.
To do this, first we need to create a class and then implement TestNG 'ITestListener'. We will have a method called 'onTestFailure'. We need to add the code to take the screen shot in this method. Instead of just taking the screen shot, we will get the Test method name and take a screen shot with test name and place it is destination folder.
How to get the driver object in the TestListener class using TestNG?
To take a screenshot in Selenium, we need to to have a driver object. We can get the driver from the ITestContext (this should be set in the base setup where we create our driver instance)
NOTE: - If you are using latest version of selenium, please check this updated article Take Screenshot using FileHandler class
package com.pack.listeners;
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import com.pack.sample.TestBase;
public class TestListener implements ITestListener {
WebDriver driver=null;
String filePath = "D:\\SCREENSHOTS";
@Override
public void onTestFailure(ITestResult result) {
System.out.println("***** Error "+result.getName()+" test has failed *****");
String methodName=result.getName().toString().trim();
ITestContext context = result.getTestContext();
WebDriver driver = (WebDriver)context.getAttribute("driver");
takeScreenShot(methodName, driver);
}
public void takeScreenShot(String methodName, WebDriver driver) {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//The below method will save the screen shot in d drive with test method name
try {
FileUtils.copyFile(scrFile, new File(filePath+methodName+".png"));
System.out.println("***Placed screen shot in "+filePath+" ***");
} catch (IOException e) {
e.printStackTrace();
}
}
public void onFinish(ITestContext context) {}
public void onTestStart(ITestResult result) { }
public void onTestSuccess(ITestResult result) { }
public void onTestSkipped(ITestResult result) { }
public void onTestFailedButWithinSuccessPercentage(ITestResult result) { }
public void onStart(ITestContext context) { }
}
Before executing the above program, we need to add TestListener class in testng.xml file as below:
<listeners>
<listener class-name="com.pack.listeners.TestListener"/>
</listeners>
In the Next tutorial, we will try to extend the way of taking the screen shot and placing it by creating a folder with Test Class name and Screens shots of that particular test class as shown in below screen shot. Click here for example on Take Screenshot and place it in a folder with Test Class name
Comments
I have two questions:
I have two questions:
I don't understand where this is being imported from: import com.pack.sample.TestBase;
Also, is it possible to make the screenshot path dynamic to maybe be set via a parameter so the listener can be reused and the test can save the screenshot to a specific location?
Thanks!
First you need to get the
First you need to get the driver, there are multiple ways in getting the driver. Above one is just an example
Second, yes we should always set a dynamic path using file Separator, and we also need to make sure that works in different Os windows/mac etc.
Hi, TestBase class has been
Hi, TestBase class has been imported to call function with name getDriver() which would return driver initialization. Yes you can set screenshot location dymanic by simply passing a string in method and call string in your test script.
How to get driver object reference
Here you have specified you need to get the driver, but how it will be done??
Issue with Listener when thread-count="2"
I have implemented the listener as above for taking screenshots for failed tests, but when i am working with parallel tests
ex: parallel="tests" thread-count="2"
and i have 2 tests both are going to fail, then my Listener is failed to take screen shots, it also not able to close the browser for one of the test.
If i run it thread-count="1" then it is working fine and taking failed screenshots for both the tests.
please suggest me the solution???
issue with parameterized Testing
I have implemented parameterized testing , i am running same tests in different browsers using test suite . Screenshot taking is working fine but the problem is if test fails in any one of the browser , how to get browser name in the screenshot so that it would be easy to understand .
if it fails in multiple browsers same screenshot is overwritten since same method is failed in both the browsers .
can you please tell me a workaround for this .... ?
issue with parameterized Testing
I have implemented parameterized testing , i am running same tests in different browsers using test suite . Screenshot taking is working fine but the problem is if test fails in any one of the browser , how to get browser name in the screenshot so that it would be easy to understand .
if it fails in multiple browsers same screenshot is overwritten since same method is failed in both the browsers .
can you please tell me a workaround for this .... ?
getting driver instance
The code above implies getDriver() is a static method, but that's usual an instance method that returns the current browser. Any suggestions on how to grab that?
excellent
thanks for help
Screenshot of an element
Can we screenshot element that cause failure in onTestFailure?
Thanks
Add new comment