I have a TestListener
class, which implements ITestListener
, which is responsible for taking pictures and saving the html if a selenium test fails.
My selenium tests have a parent class BaseTest
, which helps do common tasks, like initiating each driver.
The content of each important area:
TestListener
public class TestListener implements ITestListener {
WebDriver driver=null;
ITestContext context = null;
String filePath = "artifacts/";
@Override
public void onTestFailure(ITestResult result) {
ITestContext context = result.getTestContext();
driver = (WebDriver) context.getAttribute("WebDriver");
System.out.println("***** Error "+result.getName()+" test has failed *****");
String methodName=result.getName().toString().trim();
String currentTime = getCurrentTime();
saveScreenShot(methodName, currentTime);
savePageSource(methodName, currentTime);
saveConsoleLog(methodName, currentTime);
}
...
BaseTest
(each test calls this separately)
private void testngSetup(ITestContext context){
context.setAttribute("WebDriver", driver);
TestRunner runner = (TestRunner) context;
runner.setOutputDirectory(artifactLocation);
}
pom.xml
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="esm4hpc">
<listeners>
<listener class-name="selenium.listeners.TestListener"/>
</listeners>
<test name="sample-Test" verbose="2" parallel = "classes">
<packages>
<package name=".*"/>
</packages>
</test>
</suite>
I have found this thread (How to get the current class driver in ItestListener), which suggested to change getting the driver in ITestListener
the following way: (WebDriver)result.getTestClass().getRealClass().getDeclaredField("driver").get(result.getInstance())
, but it throw java.lang.NoSuchFieldException : driver
public class TestListener implements ITestListener {
WebDriver driver=null;
ITestContext context = null;
String filePath = "artifacts/";
@Override
public void onTestFailure(ITestResult result) {
ITestContext context = result.getTestContext();
driver = (WebDriver)result.getTestClass().getRealClass().getDeclaredField("driver").get(result.getInstance());
System.out.println("***** Error "+result.getName()+" test has failed *****");
String methodName=result.getName().toString().trim();
String currentTime = getCurrentTime();
saveScreenShot(methodName, currentTime);
savePageSource(methodName, currentTime);
saveConsoleLog(methodName, currentTime);
}
...
I have also tried to set the parallel
tag in testng.xml
to false, but did not seem to help.
I also tried to list each testing class separately, but it also gave back wrong pictures.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="esm4hpc">
<listeners>
<listener class-name="selenium.listeners.TestListener"/>
</listeners>
<test name="sample-Test" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.AuthenticationTest"/>
<class name="selenium.esm4hpc.FileEditorTest"/>
<class name="selenium.esm4hpc.FileManagerTest"/>
<class name="selenium.esm4hpc.JobTest"/>
<class name="selenium.esm4hpc.ProjectTest"/>
</classes>
</test>
</suite>
The only thing seemed to help is to move each test class into different test-cases:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="esm4hpc">
<listeners>
<listener class-name="selenium.listeners.TestListener"/>
</listeners>
<test name="AuthenticationTest" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.AuthenticationTest"/>
</classes>
</test>
<test name="FileEditorTest" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.FileEditorTest"/>
</classes>
</test>
<test name="FileManagerTest" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.FileManagerTest"/>
</classes>
</test>
<test name="JobTest" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.JobTest"/>
</classes>
</test>
<test name="ProjectTest" verbose="2" parallel = "false">
<classes>
<class name="selenium.esm4hpc.ProjectTest"/>
</classes>
</test>
</suite>
But this causes the result files to be generated separately, which makes it cumbersome to debug failed cases.