Tadas Sasnauskas Tech/Engineering Blog

Taking screenshots of failed Protractor test cases on Travis CI

So. You got a Protractor test suite doing amazing tricks via browser running under xvfb. And then it ocassionally fails, on remote environment like Travis CI only. Now what? Take a screenshot!

Protractor uses Jasmine and it has a quick and easy reporter API. Which you can define and add within protractor.conf.js:

{
  // ... rest of Protractor conf ...

  onPrepare: function() {
    var FailureScreenshotReporter = function() {
      // ... skipped ...
    };

    jasmine.getEnv().addReporter(new FailureScreenshotReporter());
  }
}

The screenshot reporter itself:

var FailureScreenshotReporter = function() {
  this.specDone = function(spec) {
    if(spec.status === 'failed') {
      var fileName = [];

      try { fs.mkdirSync('.tmp/shots'); } catch(e) {}

      fileName.push('.tmp/shots/');

      if(process.env.TRAVIS_BUILD_ID) {
        fileName.push('BUILD-');
        fileName.push(process.env.TRAVIS_BUILD_ID);
        fileName.push('_');
      }

      if(process.env.TRAVIS_PULL_REQUEST) {
        fileName.push('PR-');
        fileName.push(process.env.TRAVIS_PULL_REQUEST);
        fileName.push('_');
      }

      fileName.push(spec.fullName.toLowerCase().replace(/[^a-z0-9\s]/g, '').replace(/\s+/g, '_'));
      fileName.push('.png');

      console.info('Left a screenshot of failed spec at ' + fileName.join(''));

      browser.takeScreenshot().then(function(png) {
        var stream = fs.createWriteStream(fileName.join(''));
        stream.write(new Buffer(png, 'base64'));
        stream.end();
      });
    }
  };
};

This will create a screenshot with Travis build/PR identifier and spec, for example PR-123_this_and_that_button_opens_a_popup.png.

Next step would be collecting those screenshots since Travis environments are discarded immediately after the build. Probably easiest solution is to upload those to S3. That can be by adding the following to project’s .travis.yml:

before_install:
- pip install --user awscli
- export PATH=$PATH:$HOME/.local/bin

after_script:
- aws s3 cp .tmp/shots s3://my-automated-tests/my-project/ --recursive --exclude="*" --include="*.png"

That of course requires your S3 credentials in environment variables.