Visual Regression Testing (VRT) is a useful method to guard yourself against unwanted layout and visual changes that can occur with new version of a Graphical User Interface (GUI).
AskUI is not a testing tool in the original sense but an automation tool for all GUIs that is platform-independent. Wouldn't it be nice to combine VRT with AskUI, so you do not have to maintain two different projects.
Luckily you can do this because Jest - AskUIs favourite runner - can be extended to provide VRT, while AskUI delivers the screenshots to test on.
In this blog you will learn how to use AskUI in combination with Jest and the package jest-image-snapshot
to include a visual regression test in your AskUI runs.
Prerequisites
Setup jest-image-snapshot
First you need to install the package that provides the VRT capabilities: jest-image-snapshot.
Installation
Install it as a dev dependency:
npm install --save-dev jest-image-snapshot
Integration
The package provides a function toMatchImageSnapshot
which implements Jest's Matchers<R>
interface making it a Jest matcher that can be used with Jest's expect()
.
We have to add this matcher to Jest with expect.extend
like this in your workflow file (See the docs):
const { toMatchImageSnapshot } = require('jest-image-snapshot');
expect.extend({ toMatchImageSnapshot });
Now the only thing you have to provide for a regression test in your workflows is an image to the function expect()
as Buffer
:
expect(imageBuffer).toMatchImageSnapshot();
You can use AskUI to get the screenshot as a base64
encoded string
. The string is in the format of a data URL. So you have to strip the scheme data:[<mediatype>][;base64],
away because it is not a valid image with the scheme. Here is the full code:
const annotate = await aui.annotate();
const imageBase64 = annotate.image;
// Strip away this: data:image/png;base64,
// Not valid png -> Only if used as a data URL
let imageBuffer = Buffer.from(
imageBase64.split('base64,')[1], 'base64');
expect(imageBuffer).toMatchImageSnapshot();
How to Get it to work with TypeScript
When you run this you will get an error:
FAIL test/my-first-askui-test-suite.test.ts
● Test suite failed to run
test/my-first-askui-test-suite.test.ts:16:25 - error TS2551: Property 'toMatchImageSnapshot' does not exist on type 'JestMatchers<Buffer>'. Did you mean 'toMatchSnapshot'?
16 expect(imageBuffer).toMatchImageSnapshot();
~~~~~~~~~~~~~~~~~~~~
node_modules/@types/jest/index.d.ts:1111:9
1111 toMatchSnapshot<U extends { [P in keyof T]: any }>(propertyMatchers: Partial<U>, snapshotName?: string): R;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'toMatchSnapshot' is declared here.
This is because Jest's typings in jest.d.ts
do not include toMatchImageSnapshot
.
Luckily TypeScript has a mechanism called Declaration Merging. When we create a file jest.d.ts
in our project and declare our matcher there, TypeScript will pick it up.
declare namespace jest {
interface Matchers<R> {
toMatchImageSnapshot(): CustomMatcherResult;
}
}
When you rerun it you will get no error 🥳.
How jest-image-snapshot
Works
From the repository:
Given an image (Buffer instance with PNG image data) the toMatchImageSnapshot() matcher will create a image_snapshots directory in the directory the test is in and will store the baseline snapshot image there on the first run. Note that if the customSnapshotsDir option is given then it will store baseline snapshot there instead.
On subsequent test runs the matcher will compare the image being passed against the stored snapshot.
To update the stored image snapshot run Jest with --updateSnapshot or -u argument. All this works the same way as Jest snapshots.
You also want to check out the options you can provide to toMatchImageSnapshot()
to fine-tune the behaviour. For example you might want to set a threshold for a mismatch so that minimal differences do not fail a run:
expect(image).toMatchImageSnapshot({
failureThreshold: 0.01,
failureThresholdType: 'percent'
});
Conclusion
You can use AskUI in combination with a Visual Regression Testing library that integrates with Jest like jest-image-snapshot.
With this you can validate your GUI's final state and ensure it is the one you expected 🥳.
Top comments (0)