Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Nightwatch with Visual Regression testing
// assertions/compareScreenshot.js
var resemble = require('resemble'),
fs = require('fs');
exports.assertion = function(filename, expected) {
var screenshotPath = 'test/screenshots/',
baselinePath = screenshotPath + 'baseline/' + filename,
resultPath = screenshotPath + 'results/' + filename,
diffPath = screenshotPath + 'diffs/' + filename;
this.message = 'Unexpected compareScreenshot error.';
this.expected = expected || 0; // misMatchPercentage tolerance default 0%
this.command = function(callback) {
// create new baseline photo if none exists
if (!fs.existsSync(baselinePath)) {
console.log('WARNING: Baseline Photo does NOT exist.');
console.log('Creating Baseline Photo from Result: ' + baselinePath);
fs.writeFileSync(baselinePath, fs.readFileSync(resultPath));
}
resemble
.resemble(baselinePath)
.compareTo(resultPath)
.ignoreAntialiasing()
.onComplete(callback); // calls this.value with the result
return this;
};
this.value = function(result) {
var diff = new Buffer(result.getImageDataUrl().replace(/data:image\/png;base64,/,''), 'base64');
fs.writeFileSync(diffPath, diff);
return parseFloat(result.misMatchPercentage, 10); // value this.pass is called with
};
this.pass = function(value) {
var pass = value <= this.expected;
if (pass) {
this.message = 'Screenshots Matched for ' + filename +
' with a tolerance of ' + this.expected + '%.';
} else {
this.message = 'Screenshots Match Failed for ' + filename +
' with a tolerance of ' + this.expected + '%.\n' +
' Screenshots at:\n' +
' Baseline: ' + baselinePath + '\n' +
' Result: ' + resultPath + '\n' +
' Diff: ' + diffPath + '\n' +
' Open ' + diffPath + ' to see how the screenshot has changed.\n' +
' If the Result Screenshot is correct you can use it to update the Baseline Screenshot and re-run your test:\n' +
' cp ' + resultPath + ' ' + baselinePath;
}
return pass;
};
};
// commands/compareScreenshot.js
exports.command = function(filename, expected, callback) {
var self = this,
screenshotPath = 'test/screenshots/',
resultPath = screenshotPath + 'results/' + filename;
self.saveScreenshot(resultPath, function(response) {
self.assert.compareScreenshot(filename, expected, function(result) {
if (typeof callback === 'function') {
callback.call(self, result);
}
});
});
return this; // allows the command to be chained.
};
module.exports = {
'My Test': function(browser) {
browser
.url('http://www.google.com')
.compareScreenshot('compare-google-screenshot.png')
.end();
}
};
@nhufinney

This comment has been minimized.

Show comment Hide comment
@nhufinney

nhufinney Dec 11, 2015

It's wonderful. Thank you so much Richard.

It's wonderful. Thank you so much Richard.

@kavimukh

This comment has been minimized.

Show comment Hide comment
@kavimukh

kavimukh May 24, 2016

So I have question, I should copy assertions-compareScreenshot.js and commands-compareScreenshot.js to specific folder? if so where?

So I have question, I should copy assertions-compareScreenshot.js and commands-compareScreenshot.js to specific folder? if so where?

@eric314

This comment has been minimized.

Show comment Hide comment
@eric314

eric314 May 25, 2016

Thank you for putting this together. It serves as a great starting point for a larger design delta automation regression suite using Resemble and Nightwatch!

eric314 commented May 25, 2016

Thank you for putting this together. It serves as a great starting point for a larger design delta automation regression suite using Resemble and Nightwatch!

@tryenc

This comment has been minimized.

Show comment Hide comment
@tryenc

tryenc Dec 1, 2017

This was super helpful! Thanks very much!

tryenc commented Dec 1, 2017

This was super helpful! Thanks very much!

@gkemp94

This comment has been minimized.

Show comment Hide comment
@gkemp94

gkemp94 Jan 5, 2018

Thanks so much for this! This is a perfect baseline for what I need to accomplish!

gkemp94 commented Jan 5, 2018

Thanks so much for this! This is a perfect baseline for what I need to accomplish!

@kontrollanten

This comment has been minimized.

Show comment Hide comment
@kontrollanten

kontrollanten Jan 14, 2018

Thanks for sharing! I've created a PR to nighwatchjs to make it possible to add the screenshots to the report.

Thanks for sharing! I've created a PR to nighwatchjs to make it possible to add the screenshots to the report.

@JoshuaMorris

This comment has been minimized.

Show comment Hide comment
@JoshuaMorris

JoshuaMorris Jan 18, 2018

Any suggestions on how best to mask portions of the page you don't want to be included in the page capture and compare?

Any suggestions on how best to mask portions of the page you don't want to be included in the page capture and compare?

@markyvon2k

This comment has been minimized.

Show comment Hide comment
@markyvon2k

markyvon2k Jan 24, 2018

@JoshuaMorris I've used nightwatch's .execute() to programmatically set elements' visibility to hidden to maintain page layout while masking dynamic content (dates/usernames etc) that shouldn't be included in capture and compare.

@JoshuaMorris I've used nightwatch's .execute() to programmatically set elements' visibility to hidden to maintain page layout while masking dynamic content (dates/usernames etc) that shouldn't be included in capture and compare.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment