I'm working on automating some tests at work and want to add the ability to take a screenshot in case of a failed test. I know this can easily be done in a clean way with TestNG but all of our unit/integration tests are using jUnit so I'll have to stick to that.
I have the logic/code for it almost ready and it's working but I'm running into a conflict because the @Rule is executed after the @After tearDown() method and by that time the webDriver doesn't exist anymore so it doesn't have anything to take the screenshot from.
Here's my code:
@Rule
public TestRule testWatcher = new TestWatcher() {
@Override
protected void failed(Throwable e, Description description) {
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
String scrFilename = "Screenshot_"+ DateUtils.now().getTime()+".png";
File outputFile = new File(screenshotPath, scrFilename);
try {
LOGGER.info("Saving screenshot of failed test...");
FileUtils.copyFile(scrFile, outputFile);
} catch (IOException ioe) {
LOGGER.warn("Error taking screenshot");
}
}
};
And this is the tearDown method:
@After
public void tearDown() {
LOGGER.info("Quitting browser");
driver.quit();
LOGGER.info("Stopping Chrome Driver Service");
chromeDriverService.stop();
}
The error I'm getting as it is now is this:
org.openqa.selenium.remote.SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?
Which is of course what's happening. It's trying to call the code to take a screenshot after calling driver.quit()
and chromeDriverService.stop()
. If I comment those 2 lines then the screenshot is correctly saved.
What would be the proper way to handle this? Is there any way I can set it so the @Rule runs first then the @After?