Screenshots in Selenium with Cucumber, TestNG
- Purpose: To analyze or de-bug or trace the test execution (or to analyze a bug)
- Generally, used with failed scenarios/tests
- Very handy when executing tests in Non GUI environments such as Jenkins, AzureDevOps and etc.
- In cucumber, write the screenshots code in After hook
- Ensure to quit the driver immediately after taking the screenshot
- If screenshot and quit has to go in two different methods use order for the After hook.
- For instance, give order=0 for quit the driver and give order=1 to take the screenshot.
Example
Screenshot is implemented based on my previous example on page factory codebase.
Refer this post on page factory and in the Hooks.java class update the code of After hooks namely
@After(order=0) and @After(order=1)
Refer this post on page factory and in the Hooks.java class update the code of After hooks namely
@After(order=0) and @After(order=1)
Download Screenshots source code from GitHub OR
click this to download as a Zip
- In the order=0 After hook section, quit the driver and in the order=1 hook section take the screenshot.
- Use the attach method of scenario object
(NOTE: This example is based on io.cucumber 7.1.0 and it doesn't support embed method) - isFailed() identifies the failed scenario , for instance in the DirectoryPageFactory.java file (refer the code from previous example above) xpath for the searchButtonLocator is deliberately updated to a bad entry so this produces an error in validation.
// Search button locator @FindBy(xpath = "//*[@id=\"searchBtnBAD\"]") public WebElement searchButtonLocator;
package com.sadakar.common; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.chrome.ChromeDriver; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.Scenario; public class Hooks extends BasePage { @Before //Cucumber Before Hook public void setupDriver() throws InterruptedException { System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe"); driver = new ChromeDriver(); driver.manage().window().maximize(); driver.get("https://opensource-demo.orangehrmlive.com/index.php/auth/login"); } @After(order=0) // Cucumber After hook with order 0 public void quitDriver() throws Exception { driver.quit(); } @After(order = 1) // Cucumber After Hook with order 1 public void takeScreenShotOnFailedScenario(Scenario scenario) { System.out.println("This is from After hook, order=1"); if ((scenario.isFailed())) { final byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); scenario.attach(screenshot, "image/png", scenario.getName()); } } }
Where does screenshots get stored ?
The code above is a cucumber based screenshot in the Hooks so eventually the screenshots get stored in the cucumber related reports.For instance, below is the cucumber report folder in the target
As the cucumberreport.html is opened, we can see the screenshot appended at the end of the scenario.
What if the order of After hooks for quit is 1 and
for screenshot is 0
We end up with the following error message:
org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()?
org.openqa.selenium.NoSuchSessionException: Session ID is null. Using WebDriver after calling quit()? Build info: version: '4.3.0', revision: 'a4995e2c09*' System info: host: 'SADAKARP', ip: '136.144.2.8', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '16.0.2' Driver info: org.openqa.selenium.chrome.ChromeDriver Command: [null, screenshot {}] Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 103.0.5060.134, chrome: {chromedriverVersion: 103.0.5060.53 (a1711811edd7..., userDataDir: C:\Users\sadakarp\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:64648}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: WINDOWS, proxy: Proxy(), se:cdp: ws://localhost:64648/devtoo..., se:cdpVersion: 103.0.5060.134, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true} at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:145) at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:167) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:142) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:569) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:624) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:628) at org.openqa.selenium.remote.RemoteWebDriver.getScreenshotAs(RemoteWebDriver.java:353) at com.sadakar.common.Hooks.takeScreenShotOnFailedScenario(Hooks.java:29)
No comments:
Post a Comment