I would like to take a screenshot every single time test fails or if multiple tests then multiple screenshots of course.
So far I understand that I can just wrap my single test with a try catch
block and proceed taking a screenshot, however I would not want to wrap it in every test I have. I want it to apply to all of them without wrapping each one, do I have to do that in my setup?
public class WebDriverSettings { protected WebDriver driver; protected String TARGET_URL; @BeforeEach public void setUp() { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(new ChromeOptions().addArguments("window-size=1920x1480")); driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); loginToEnvironment(); } } public class LoginServiceTest extends WebDriverSettings { private LoginModal loginModal; private AccountApi accountApi; private Credentials credentials; @BeforeEach public void setUp() { super.setUp(); credentials = new SignUp(); accountApi = new AccountApi(credentials); accountApi.createAccount(); loginModal = new HomePage(driver).acceptCookies().clickOnMyAccountTab().switchToLoginTab(); } @Test public void shouldSuccessfullyLogin() { try { accountApi.createAccount(); assertFalse(loginModal.login(credentials).getMyAccountName().getText().isEmpty()); } catch (Exception e) { try { File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenshotFile, new File("path")); } catch (IOException ioException) { ioException.printStackTrace(); } accountApi.closeAccount(); } } }
Solution advised by Jeff
So creating Util package and adding a class that would be responsible for creating a screenshot also it would generate random name but needs to be refactored i just made it quickly to make it work
public class ScreenShotCreator { public static void takeScreenShot(WebDriver driver) { try { File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(screenshotFile, new File(fileNameGenerator())); } catch (IOException e) { throw new RuntimeException("Could not make a screenshot"); } } // creating this for test purposes , need to use string builder instead to append it instead of adding it private static String fileNameGenerator() { SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy-HH:mm"); String path = "....."; return path + "screenshot" + formatter.format(new Date()) + " " + RandomStringUtils.randomAlphanumeric(10) + ".png"; }
Then before closing it down just call the created method
@AfterEach public void tearDown() { ScreenShotCreator.takeScreenShot(driver); driver.manage().deleteAllCookies(); driver.close(); driver.quit(); }
Advertisement
Answer
What I would suggest is
Create a method to take a screenshot and put that in a Utils class and call it when you want to take a screenshot. This will make taking a screenshot a lot easier because all the code lives in one place and can be easily called from anywhere.
Create a
tearDown()
method, if you don’t have one already. Looks like it would go in theWebDriverSettings
class from your currently posted code. Mark it with an@AfterEach
annotation and then detect a failed test case and if it failed, take a screenshot.If you aren’t sure how to do that, there’s a class in JUnit 4.9 and later called
TestWatcher
that you can use. There are lots of examples on the web on how to use it.