Making screenshots from Selenium with JUnit @Rule's

Albert Sikkema

When running Selenium tests from JUnit it's very useful to be able to capture screenshots when something fails. Especially when you run it in a Continuous Integration environment which you aren't monitoring. A screenshot combined with the stacktrace makes identifying and fixing the error easier. When you combine this with a JUnit @Rule you can make it transparant and use it for every testcase

Implementing the @Rule
For implementing rules you need to implement the MethodRule interface and implement the apply method. The base.evaluate method invokes the unittest. The screenshot is made in case of any exception which is re-thrown as a RuntimeException so that your testcase will fail. This class extends the SeleneseTestBase which helps you writing selenium unit tests. Capturing screenshots is a feature of selenium and is very easy. You might want to store the file differently, but that should be easy.

public class CapturingSelenium extends SeleneseTestBase implements MethodRule {

    @Override
    public Statement apply(final Statement base, FrameworkMethod method, Object target) {
        return new Statement() {

            @Override
            public void evaluate() throws Throwable {
                try {
                    setUp("http://localhost:8080/", "*firefox");
                    base.evaluate();
                }
                catch (Exception e) {
                    selenium.captureEntirePageScreenshot("/tmp/selenium-error-" + new UUID().toString() + ".PNG", "");
                    throw new RuntimeException(e);
                }
            }
        };
}

That's it. Now you can just use the CapturingSelenium class and annotate it with @Rule. When any test fails with an exception the rule catches it and captures a screenshot of the browser at the time of the exception. Here's a basic example:
Usage:

public class SeleniumTest {

    @Rule
    private CapturingSelenium selenium = new CapturingSelenium();

    @Test(expected=RuntimeException.class)
    public void shouldCaptureScreenshotWhenFailing() throws Exception {
        selenium.open("http://localhost/myapp/home");
        selenium.click("some-button-which-is-not-there");
        //...
    }
}

Comments (4)

  1. raveman - Reply

    June 17, 2010 at 10:22 am

    great idea 🙂

  2. Jae Kim - Reply

    January 12, 2011 at 6:30 pm

    Is it working? I tried to execute this code but selenium doesn't have the open and click functions.

  3. Tobi - Reply

    July 13, 2011 at 1:26 pm

    Yes I have the same problem.
    eclipse says for example by selenium.open: The method open(String) is undefined for the type CapturingSelenium.
    So it dosent works ; (
    Now i try to reslove this or i have to use a diffrent way to take screenshots at an ERROR .
    Somebody has an idea?

  4. BludShoT - Reply

    June 30, 2016 at 8:53 am

    If you are using WebDriver instance, instead of DefaulSelenium used in the example above, then :

    Replace selenium.open with
    driver.get("http://www.yoursite.com/xyz");

    and replace selenium.click with
    driver.findElement(By.xpath("//yourxpath")).click();

    where driver is an instance of WebDriver and instantiated according to your need.

Add a Comment