I don't really blog anymore. Click here to go to my main website.

muhuk's blog

Nature, to Be Commanded, Must Be Obeyed

February 21, 2012

How to take a screenshot at the end of your Selenium WebDriver tests?

When you run Selenium headless on the server, debugging failures with just the standard outputs can be challenging. A screenshot of the last state of the browser helps in this case. This little tutorial explains how to take such a screenshot and save it as an artifact in Jenkins. I will be using junit as the test framework.

Step 0: Getting the name of the current test

You probably want to include the name of the test class and the name of the current test method in the filename. Here is how you find it out:

import org.junit.After;
import org.junit.Rule;
import org.junit.rules.TestName;


public abstract class Test {
    @Rule public TestName testName = new TestName();

    @After public void tearDown() {
        String className = this.getClass().getSimpleName();
        String methodName = this.testName.getMethodName();
        System.err.println("Finished test " +
                           className + "." + methodName + "()");
    }
}

The code above is just a simple demonstration of how you use TestName. However it is a good idea to produce a simple output like above in the beginning and the end of each test.

Step 1: Taking the screenshot

Selenium documentation suggests the following:

import org.junit.After;
import java.io.File;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;


public abstract class Test {
    @After public void tearDown() {
        // driver is your WebDriver
        File screenshot = ((TakesScreenshot) driver)
                                .getScreenshotAs(OutputType.FILE);
    }
}

Example code in the official documentation is a little more terse, I left out everything but the essentials.

Step 2: Saving the image

getScreenshotAs() method saves the output in a temporary location. I took the advice here and used FileUtils.copyFile() to copy this temporary file back inside my workspace.

import org.junit.After;
import java.io.IOException;
import org.apache.commons.io.FileUtils;


public abstract class Test {
    @After public void tearDown() {
        // screenshot is the file we have acquired
        // fileName is the name of the image file
        try {
            FileUtils.copyFile(screenshot, new File(fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

To give a concrete example, if your fileName is "screenshot-TestClass-testName.png", it will be copied to $WORKSPACE/screenshot-TestClass-testName.png.

Step 3: Archiving the screenshot as an artifact

In Post-build Actions section enable Archive the artifacts and enter the appropriate glob in the textbox below. Your screenshots will appear in the Build Artifacts in build details page and also in Last Successful Artifacts in the project details page. Look for the icon below:

package icon

I am no Java expert. If you know how to do this better please share it in the comments. I just hope this makes someone’s life easier.

If you have any questions, suggestions or corrections feel free to drop me a line.