Method | Arguments | description |
---|---|---|
launchBrowser /launch |
Object puppeteer.launch options |
Launches a browser instance |
connectBrowser /connect |
Object puppeteer.connect options |
Attaches to an existing browser instance |
init |
TestOptions | Configure and prepare differencify to operate based on TestOptions |
cleanup |
no argument | Closes browser instance if it is not closed already |
Method | Arguments | description |
---|---|---|
toMatchSnapshot |
image or image, callback or callback |
Pass an image object to compare it to the snapshot. Optionally, pass a callback to receive details from the comparison. Alternatively, just pass a callback to receive details of the snapshot currently in the chain. |
result |
Object |
A function that returns response object of previous step when on chained mode |
launch |
Object puppeteer.launch options |
launches new browser and returns browser object |
connect |
Object puppeteer.connect options |
Attaches to an existing browser instance and returns browser object |
freezeImage |
string |
Selector name of a <img> tag containing animated image to be freezed before taking screenshot |
mockRequests |
Object |
Runs chrome headless browser in isolation using Mockeer |
Differencify matches Puppeteer's API completely. Here are some examples of how to use it.
(async () => {
await differencify.launchBrowser();
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.waitFor(1000)
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
await differencify.cleanup();
})();
In this example, differencify will launch a browser instance and continues on others steps
(async () => {
await differencify.launchBrowser();
const target = differencify.init({ testName: 'Differencify simple unchained', chain: false });
const page = await target.newPage();
await page.goto('https://github.com/NimaSoroush/differencify');
await page.setViewport({ width: 1600, height: 1200 });
await page.waitFor(1000);
const image = await page.screenshot();
const result = await target.toMatchSnapshot(image);
await page.close();
console.log(result) // True or False
await differencify.cleanup();
})();
In this example, differencify will launch a browser instance and unchain steps. differencify.init().newPage()
will return a puppeteer
page instance which with all supported methods on that page
(async () => {
await differencify
.init()
.launch()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.waitFor(1000)
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
})();
In this example, differencify will launch a browser instance and continues on others steps and on close()
it will close both page and browser
(async () => {
const target = differencify.init({ testName: 'Differencify simple unchained', chain: false });
await target.launch();
const page = await target.newPage();
await page.goto('https://github.com/NimaSoroush/differencify');
await page.setViewport({ width: 1600, height: 1200 });
await page.waitFor(1000);
const image = await page.screenshot();
const result = await target.toMatchSnapshot(image);
await page.close();
await target.close();
console.log(result) // True or False
})();
In this example, differencify will launch a browser instance and unchain steps. differencify.init().newPage()
will return a puppeteer
page instance which with all supported methods on that page
(async () => {
await differencify.launchBrowser();
await differencify
.init({ testName: 'test1' })
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.wait(3000)
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
await differencify
.init({ testName: 'test2' })
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.wait(3000)
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
await differencify.cleanup();
})();
In this example, differencify will launch a browser instance and share same browser instance with all following tests and on cleanup()
it will close the browser
(async () => {
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.title()
.result((title) => {
console.log(title)
})
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
})();
In this example, after calling result
function it will return the previous step result as an object.
For programmatic use cases where more information is required than simply whether or not
a test passed, a callback function may be passed to toMatchSnapshot
which will be invoked
after the test and passed additional details.
(async () => {
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://github.com/NimaSoroush/differencify')
.screenshot()
.toMatchSnapshot((resultDetail) => {
console.log(resultDetail);
/*
Example output:
{
testConfig: {
chain: false,
testNameProvided: true,
testName: 'TestName',
'testId': 2,
'isUpdate': false,
'isJest': false,
'newWindow': true
},
testResult: {
diffPath: '/parent/__image_snapshots__/__differencified_output__/test.differencified.png',
matched: false,
diffPercent: 0.02,
distance: 0,
snapshotPath: '/parent/__image_snapshots__/test.snap.png',
}
}
*/
})
.close()
.end();
})();
Similarly, the callback may be passed as a second argument when unchained:
(async () => {
const target = differencify.init({ chain: false });
await target.launch();
const page = await target.newPage();
await page.goto('https://github.com/NimaSoroush/differencify');
await page.setViewport({ width: 1600, height: 1200 });
await page.waitFor(1000);
const image = await page.screenshot();
await target.toMatchSnapshot(image, (resultDetail) => {
console.log(resultDetail);
/*
Example output:
{
testConfig: {
chain: false,
testNameProvided: true,
testName: 'TestName',
'testId': 2,
'isUpdate': false,
'isJest': false,
'newWindow': true
},
testResult: {
diffPath: '/parent/__image_snapshots__/__differencified_output__/test.differencified.png',
matched: false,
diffPercent: 0.02,
distance: 0,
snapshotPath: '/parent/__image_snapshots__/test.snap.png',
}
}
*/
});
await page.close();
await target.close();
})();
(async () => {
await differencify
.init()
.newPage()
.tracing
.start({ path: 'trace.json' })
.page
.setViewport({ width: 1600, height: 1200 })
.goto('https://nimasoroush.github.io/differencify/')
.waitFor(1000)
.keyboard
.press('Space')
.tracing
.stop()
.page
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
})();
In this example, differencify will launch a browser instance and opens a new tab and starts tracing, goto url, mouse click, stop tracing and finally closes the tab. All steps are running on page
context unless you switch to one of the following context:
'page',
'keyboard',
'mouse',
'touchscreen',
'tracing',
If you do so, you need to come back to page
context by calling it.
(async () => {
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://nimasoroush.github.io/differencify/')
.on('console', msg => {
for (let i = 0; i < msg.args.length; ++i) {
console.log(`${i}: ${msg.args[i]}`); // JSHandle:hello
}
});
.evaluate(() => console.log('hello', 5, { foo: 'bar' }))
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
})();
In this example, differencify will call on()
method of Puppeteer asynchronously. same logic should apply for other specific methods of Puppeteer like:
on('dialog', async dialog => { console.log(dialog.message()) };
evaluate(() => console.log('hello', 5, {foo: 'bar'}));
$$eval('div', divs => divs.length);
evaluateHandle(() => document.body);
...
Another example
(async () => {
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://nimasoroush.github.io/differencify/')
.on('dialog', async (dialog) => {
console.log(dialog.message()); // 1
await dialog.dismiss();
})
.evaluate(() => alert('1'))
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result) // True or False
})
.close()
.end();
})();
(async () => {
await differencify
.init()
.newPage()
.goto('https://github.com/NimaSoroush/differencify')
.mainFrame()
.then
.url()
.result((url) => {
console.log(url); // https://github.com/NimaSoroush/differencify
})
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result); // True or False
})
.close()
.end();
})();
In this example, differencify will get the mainFrame
of page and continues by then
to get childFrame
of that frame and finally prints the url
of the childFrame.
(async () => {
await differencify
.init()
.newPage()
.goto('https://nimasoroush.github.io/differencify/')
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result); // True or False
})
.goto('https://nimasoroush.github.io/differencify/')
.screenshot()
.toMatchSnapshot()
.result((result) => {
console.log(result); // True or False
})
.close()
.end();
})();
In this example, differencify will got to different pages and compare screenshots with reference screenshots.
(async () => {
const target = differencify.init({ chain: false });
const page = await target.newPage();
await page.goto('https://nimasoroush.github.io/differencify/');
await page.setViewport({ width: 1600, height: 1200 });
await page.waitFor(1000);
const image = await page.screenshot();
const result = await target.toMatchSnapshot(image);
await page.goto('https://github.com/NimaSoroush/differencify#about');
await page.setViewport({ width: 1600, height: 1200 });
await page.waitFor(1000);
const image2 = await page.screenshot();
const result2 = await target.toMatchSnapshot(image2);
await page.close();
console.log(result); // True or False
console.log(result2); // True or False
})();
In this example, differencify will got to different pages and compare screenshots with reference screenshots.
(async () => {
const differencify = new Differencify({ imageSnapshotPath: './custom_test_path' });
const target = differencify.init({ chain: false });
await target.launch();
const page = await target.newPage();
await page.setViewport({ width: 1600, height: 1200 });
await page.goto('http://example.com/');
await page.waitFor(1000);
const image = await page.screenshot();
const result = await target.toMatchSnapshot(image);
await page.close();
console.log(result); // True or False
console.log(result2); // True or False
})();
In this example, you can specify the custom path for storing images.
(async () => {
await differencify
.init()
.newPage()
.setViewport({ width: 1600, height: 1200 })
.goto('https://i.giphy.com/media/xTiTnoUnHxVaaVNWhO/giphy.webp')
.waitFor('body > img')
.freezeImage('body > img')
.screenshot()
.toMatchSnapshot()
.close()
.end();
})();
In this example, you can freeze an image by specifying the selector path.
(async () => {
await differencify
.init()
.newPage()
.goto('https://nimasoroush.github.io/differencify/')
.waitFor(2000)
.click('[id=js-repo-pjax-container] div nav a')
.waitFor(2000)
.url()
.result((url) => {
expect(url).toContain('pulls');
})
.screenshot()
.toMatchSnapshot()
.close()
.end();
})();
In this example an element is clicked on that performs navigation, and the url checked to see it has been successful.