Construct unique safe filenames in TestNG

Posted: October 22nd, 2009 | Author: Dave | Filed under: Examples | Tags: , , | No Comments »

In order to save files for investigating failures from within TestNG it’s important to have a safe filename that is unique to the test – otherwise you may overwrite important files. I have written the following simple method in Java that is called from a listener with an ITestResult parameter to construct a unique file name that should be safe on most file systems.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static String fileNameFrom(ITestResult result, String fileExtension) {
  List<String> parts = new ArrayList<String>();
  parts.add(result.getTestClass().getName());
  parts.add(result.getMethod().getMethodName());
 
  //add parameters
  Object[] parameters = result.getParameters();
  for (Object parameter: parameters)
    parts.add(parameter != null ? parameter.toString() : NULL_PARAMETER_VALUE);
 
  String fileName = StringUtils.join(parts.toArray(new String[parts.size()]), ".");
  fileName = fileName.replaceAll("[\\^\\\\.\\-:;#_]", "_");
  return fileName + "." + fileExtension;
}

Capturing screenshots from remote Selenium RC

Posted: October 16th, 2009 | Author: Dave | Filed under: Examples | Tags: , , , | 14 Comments »

Despite the name, the Selenium RC (Remote Control) server is often run on the same machine as the testing framework, which makes saving screenshots to disk quite easy. If however you are running Selenium RC on a separate machine, or are using Selenium Grid it can become more difficult as the screenshots are also saved on the remote machines.

To solve this you can use the captureScreenshotToString and captureEntirePageScreenshotToString commands, which return a Base64 encoded String of the screenshot, which you can then decode and save to disk on your testrunner machine.

The following demonstrates the latter command (entire screenshot) in Java. I have added this to a TestNG afterInvocation listener for failed tests so that I have a screenshot of the page that resulted in the failure, which can be very valuable for diagnosing issues.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void afterInvocation(IInvokedMethod method, ITestResult result) {
  if (!result.isSuccess()) {
    String imageName = "screenshot.png";
    String imagePath = outputDirectory + separator + imageName;
    try {
      String base64Screenshot = session().captureEntirePageScreenshotToString("");
      byte[] decodedScreenshot = Base64.decodeBase64(base64Screenshot.getBytes());
      FileOutputStream fos = new FileOutputStream(new File(imagePath));
      fos.write(decodedScreenshot);
      fos.close();
      Reporter.log("<a href=\"file:///" + imagePath + "\">Screenshot</a>");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Notes:

  • This example uses org.apache.commons.codec.binary.Base64
  • In this example, outputDirectory is set in a onStart listener from the ITestContext parameter’s getOutputDirectory method
  • In reality you’d want to construct imageName from the test method name so that it is unique for each test
  • The captureEntireScreenshot* commands have limited browser support. Currently I only capture these screenshots if the browser is Firefox