Skip to content

Instantly share code, notes, and snippets.

@nydame
Created January 10, 2019 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nydame/11f93f713e59df8e98f840365f03c883 to your computer and use it in GitHub Desktop.
Save nydame/11f93f713e59df8e98f840365f03c883 to your computer and use it in GitHub Desktop.
Visual diffing script
/*
### How to use [Puppeteer](https://github.com/GoogleChrome/puppeteer) for visual diffing
#### Install the following NPM packages: puppeteer, pixemmatch, fs-extra and pngjs (first time only) in the directory where you want to keep your tests
```npm install --save-dev puppeteer pixelmatch fs-extra pngjs```
#### Create your testing script (first time only); what follows is a simplified example that tests only 2 pages
```
*/
const puppeteer = require('puppeteer');
const pixelmatch = require('pixelmatch');
const fs = require('fs-extra');
const PNG = require('pngjs').PNG;
const testNum = 0; // EDIT before each individual test
const dPath = 'pacbio.test-20180704'; // EDIT before each set of tests
const filenameBase = 'pacbio-test';
const pathBase = dPath + testNum + '/' + filenameBase;
(async () => {
await fs.ensureDir(dPath + testNum);
const phoneWidth = 320;
const phoneHeight = 480;
const tabletWidth = 780;
const tabletHeight = 1024;
const laptopWidth = 1200;
const laptopHeight = 600;
const browser = await puppeteer.launch();
const testpage = await browser.newPage();
testpage.setDefaultNavigationTimeout(2400000); // default is 30000
// (1) Home
await testpage.goto('http://pacbio.local', { waitUntil: 'networkidle2' });
// start taking pictures at different screen sizes
await testpage.setViewport({ width: phoneWidth, height: phoneHeight });
await testpage.screenshot({
path: pathBase + '01.phone.png',
fullPage: true,
});
if (testNum > 0) {
await compareScreenshots(0, testNum, filenameBase + '01.phone.png');
}
await testpage.setViewport({ width: tabletWidth, height: tabletHeight });
await testpage.screenshot({
path: pathBase + '01.tablet.png',
fullPage: true,
});
if (testNum > 0) {
await compareScreenshots(0, testNum, filenameBase + '01.tablet.png');
}
await testpage.setViewport({ width: laptopWidth, height: laptopHeight });
await testpage.waitFor(8000); // give video time to load
await testpage.screenshot({
path: pathBase + '01.laptop.png',
fullPage: true,
});
if (testNum > 0) {
await compareScreenshots(0, testNum, filenameBase + '01.laptop.png');
}
// Click one of the tabs to make sure they're still working
await testpage.click('#hero-menu .SMRT');
await testpage.screenshot({
path: pathBase + '01.clicked.laptop.png',
fullPage: false,
});
if (testNum > 0) {
await compareScreenshots(
0,
testNum,
filenameBase + '01.clicked.laptop.png'
);
}
// (2) Research Focus, Human
await testpage.goto('http://pacbio.local/research-focus/human', {
waitUntil: 'networkidle2',
});
await testpage.setViewport({ width: laptopWidth, height: laptopHeight });
await testpage.waitFor(4000);
await testpage.screenshot({
path: pathBase + '02.laptop.png',
fullPage: true,
});
if (testNum > 0) {
await compareScreenshots(0, testNum, filenameBase + '02.laptop.png');
}
await browser.close();
})();
function compareScreenshots(num1, num2, filename) {
var img1 = fs
.createReadStream(dPath + num1 + '/' + filename)
.pipe(new PNG())
.on('parsed', doneReading),
img2 = fs
.createReadStream(dPath + num2 + '/' + filename)
.pipe(new PNG())
.on('parsed', doneReading),
filesRead = 0;
function doneReading() {
if (++filesRead < 2) return;
var diff = new PNG({ width: img1.width, height: img1.height });
// NOTE: The default threshold for PixelMatch is 0.1
pixelmatch(img1.data, img2.data, diff.data, img1.width, img1.height, {
threshold: 0.2,
});
diff.pack().pipe(
fs.createWriteStream(dPath + num2 + '/' + filename + '-diff.png')
);
}
}
/*
```
#### Edit the script
*dPath* -- decide what to call the new sub-directories where the screenshots and diff images will be placed
*testNum* -- set to 0
provide all the calls to goto() with the desired test URL
#### Run the script
```node test.js```
#### Edit the script again, but only to increase testNum by 1
#### Run the script again to set a baseline
#### DO UPDATES
#### Edit the script again (testNum++)
#### Run the script again to collect data. Check the diff files in *dPath-testNum* and ensure that there are no unexpected changes. Beware of false positives due to videos, animation etc. Repeat cycle (do updates, testNum++, run the script, examine the diffs) as needed.
#### Enjoy all the time you just saved :)
Credit: I drew heavily from [this blog article](https://meowni.ca/posts/2017-puppeteer-tests/) to incorporate the use of Pixelmatch into my code.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment