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.