Wednesday, April 13, 2011

Making Your Cukes More Awesomer With Screenshots

In my last post about Cucumber, I alluded to using watir-webdriver instead of using native watir. There was one very surprising advantage I discovered with watir-webdriver's use of selenium as a backend: Awesome Screenshot API.

Here's how we setup our Cucumber suite to take screenshots (and html/txt "screenshots") using watir-webdriver and celerity.  First, set your tests up to write an error when a test fails:

In this hook, we're passing in an environment, the scenario and the browser object we setup in the prior post.  The environment is really handy since QA folks might be running tests against different regions and would want to pass that information back to the developers to recreate problems.  The TEST_SERVER environment variable is already used to pick this during test startup.

The ErrorWriter module is next.

Several things are going on here.  The write errors message is simple enough.  It creates a directory for the errors to be written, and dumps the context of the browser's text and html representations to file.  What's more interesting are the scenario_name and file_name methods.

The scenario_name method does some interesting things.  We want to name our files by the name of the scenario that fails.  In the else clause, you see how dashes and white space are replaced by a single white space character.  But, in the if clause, we're testing to see if we have an ExampleRow.  These are the Examples in a Cucumber Scenario Outline.  If the scenario is an ExampleRow, we lose the name of the Scenario itself.  Fortunately, the ExampleRow knows what ScenarioOutline it belongs to.  We can get the name of the ScenarioOutline, perform the same transform on the name, and then append the example that is actually running to it's name.

The file_name method simply concatenates the region, time of failure and the scenario name together for the filename to be written to.

This can result in some very long file names, however, their descriptiveness wins overall.  You don't have to open a file to find out what failed.  A simple reading of the directory containing the files lets anyone find the test that they need to examine quickly.

The write_errors method did one other thing. Call capture_screenshot to grab an image of the browser.  When using Watir, you had to do some fancy things with the Win32 API to make the capture work.  We had a lot of issues using it with our QA folks who had SnagIT installed.  So how refreshing it was to have watir-webdriver just work with so little code:

We have another little trick, where in our prior example, we setup a WEBDRIVER variable to determine if we could take a screenshot.  If we're running on Celerity, no harm, no foul, but no screenshot.

Granted, it's really selenium that we're using here, but we get really nice and small png files, which only contain the contents of the browser.  No title bar, no toolbars, nothing. Just the contents of the window.  Our only issue is that IE causes problems on our CI box, but just having Firefox able to run there is an outstanding step forward.

Hopefully this is helpful, please let me know if it is.

No comments: