-
-
Save richard-flosi/8a5d2e10b6609ab9d06a to your computer and use it in GitHub Desktop.
// 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(); | |
} | |
}; |
So I have question, I should copy assertions-compareScreenshot.js and commands-compareScreenshot.js to specific folder? if so where?
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!
This was super helpful! Thanks very much!
Thanks so much for this! This is a perfect baseline for what I need to accomplish!
Thanks for sharing! I've created a PR to nighwatchjs to make it possible to add the screenshots to the report.
Any suggestions on how best to mask portions of the page you don't want to be included in the page 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.
I Used the code for nightwatch-cucumber framework . It worked except that if the images do not match, the message is received correctly but the test case is still marked as passed. how can we fix this? Also has anyone tried visual regression in browserstack? Any pointers would be appreciated.
It's wonderful. Thank you so much Richard.