10f. Advanced WebDriver – Taking a Screenshot

Hiya Champs! Screenshot. another frequently heard term on the crowded streets of Software Testing. What good is a test if you cannot prove with a screenshot when a bug appears in your environment but not in development! So, it’s high time that we understand how to grab one using Selenium WebDriver.

I know you have a few questions springing up to your mind. The most important one being, “If it was a manual test, then I could have just hit the ‘PrntScr’ button on my keyboard and have a beautiful screenshot to treasure. But when I automate, how do I achieve the same result?”

And guess what, it is laughably simple! Just follow 3 steps, and you have a screenshot at your disposal. If you are like me, you are probably anxious to see how this works in code. I aim to please, so without further delay…

Step 1:

Use the ‘TakesScreenshot’ interface provided by Selenium WebDriver. Cast the WebDriver object to TakesScreenshot type.

When you see a squiggly line below TakesScreenshot, just click on import org.openqa.selenium.TakesScreenshot; package and you will be free of errors.

// Cast driver object to TakesScreenshot
TakesScreenshot screenshot = (TakesScreenshot) driver;

Step 2:

To get the screenshot as an image file, call the ‘getScreenshotAs’ method.

Squiggly lines? – click on:

import org.openqa.selenium.OutputType;
import java.io.File;
// Get the screenshot as an image File
File src = screenshot.getScreenshotAs(OutputType.FILE);

Step 3:

Copy the generated image file to a destination location of your choice.  This can be easily done using the copyFile method of FileUtils class. It is important to note that this method throws IOException. Hence as a good practice, wrap this code in a try-catch block.

More squiggly lines? – click on:

import java.io.IOException;
import org.apache.commons.io.FileUtils;
import java.text.SimpleDateFormat;
import java.util.Date;

Make sure to import the packages exactly as specified. Mostly you might have to download org.apache.commons.io jar (download location at the time of writing this article) and add it to the build path of the project. We have seen this procedure numerous times before and hence I am not re-iterating it (Refer to Step 3 of this article).

Also, note that we are saving the image as a .jpg file in our code. It can be saved as .png file as well.

It can be as simple as,

// Copy the screenshot to destination
FileUtils.copyFile(src, new File(“\\screenshot\\test.jpg”));

Or as complicated as,

try {
    // Specify the destination where the image will be saved
    File dest = new File("\\Selenium\\screenshots\\" + testCaseName + "_" + timestamp() + ".jpg");
    // Copy the screenshot to destination
    FileUtils.copyFile(src, dest);
} catch (IOException ex) {
    System.out.println(ex.getMessage());
}

public static String timestamp() {
    // Timestamp to make each screenshot name unique
    return new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date());
}

In our example, we will be using the complicated version. Because we are going to put all the screenshot related code in a separate method (in a new class) and call it every time we wish to capture a screenshot. Otherwise, we will have to do the same song and dance for each and every scenario.

Overall picture

Create a new class named, ‘SaveScreenshot.java’ with two methods.

  1.  public static void capture(String testCaseName, WebDriver driver) – has all the code to take the screenshot and save it to the desired location.
  2.  public static String timestamp() – used to generate a timestamp and provide it to the above method to make every saved screenshot unique.

Sample Scenario

  1. Open Firefox browser.
  2. Navigate to google account creation page
  3. Locate first name text box by id
  4. Enter ‘fname01’ as the first name
  5. Locate last name text box by name
  6. Enter ‘lname01’ as the last name
  7. Take a screenshot of the page and save it to a location.

JUnit code:

  1. SaveScreenshot.java class

package com.blog.junitTests;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

public class SaveScreenshot {

  public static void capture(String testCaseName, WebDriver driver) {
    // Cast driver object to TakesScreenshot
    TakesScreenshot screenshot = (TakesScreenshot) driver;
    // Get the screenshot as an image File
    File src = screenshot.getScreenshotAs(OutputType.FILE);
    try {
      // Specify the destination where the image will be saved
      File dest = new File("\\Selenium\\screenshots\\" + testCaseName + "_" + timestamp() + ".jpg");
      // Copy the screenshot to destination
      FileUtils.copyFile(src, dest);
    } catch (IOException ex) {
      System.out.println(ex.getMessage());
    }
  }

  public static String timestamp() {
    // Timestamp to make each screenshot name unique
    return new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(new Date());
  }

}

2. ScreenshotTest.java class (Implements the steps detailed in sample scenario section)

package com.blog.junitTests;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class ScreenshotTest {
  //Declaring variables
  private WebDriver driver; 
  private String baseUrl;
  private String testCaseName = "ScreenshotTest";

  @Before
  public void setUp() throws Exception{
    // Selenium version 3 beta releases require system property set up
    System.setProperty("webdriver.gecko.driver", "E:\\Softwares\\"
        + "Selenium\\geckodriver-v0.10.0-win64\\geckodriver.exe");
    // Create a new instance for the class FirefoxDriver
    // that implements WebDriver interface
    driver = new FirefoxDriver();
    // Implicit wait for 5 seconds
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    // Assign the URL to be invoked to a String variable
    baseUrl = "https://accounts.google.com/SignUp";
  }
  
  @Test
  public void testPageTitle() throws Exception{
    // Open baseUrl in Firefox browser window
    driver.get(baseUrl);
    // Locate First Name text box by id and
    // assign it to a variable of type WebElement
    WebElement firstName = driver.findElement(By.id("firstName"));
    // Clear the default placeholder or any value present
    firstName.clear();
    // Enter/type the value to the text box
    firstName.sendKeys("fname01");
    // Locate last name text box by name
    WebElement lastName = driver.findElement(By.name("lastName"));
    // Clear and enter a value
    lastName.clear();
    lastName.sendKeys("lname01");
    //Take a screenshot
    SaveScreenshot.capture(testCaseName, driver);
  }
  
   @After
    public void tearDown() throws Exception{
    // Close the Firefox browser
    driver.close();
  }
}

Comments are provided for each line of code and hence it is self-explanatory.

Eclipse output

In Eclipse IDE, JUnit pane clearly shows that the test case ‘ScreenshotTest.java’ has passed and the console has no errors.

As specified in the code, the screenshot is saved in “E:/Selenium/screenshots” path with the name in the mentioned format.

Saved Screenshot

This was the captured screenshot,

Captured Screenshot

Now it is time for you to implement this in your testing journey and visualize the magic for yourself.

Happy photographing the screen 😉

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.