Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(options): add option to pass on size missmatch #174

Merged
merged 1 commit into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ See [the examples](./examples/README.md) for more detailed usage or read about a
* `blur`: (default `0`) Applies Gaussian Blur on compared images, accepts radius in pixels as value. Useful when you have noise after scaling images per different resolutions on your target website, usually setting its value to 1-2 should be enough to solve that problem.
* `runInProcess`: (default `false`) Runs the diff in process without spawning a child process.
* `dumpDiffToConsole`: (default `false`) Will output base64 string of a diff image to console in case of failed tests (in addition to creating a diff image). This string can be copy-pasted to a browser address string to preview the diff for a failed test.
* `allowSizeMismatch`: (default `false`) If set to true, the build will not fail when the screenshots to compare have different sizes.

```javascript
it('should demonstrate this matcher`s usage with a custom pixelmatch config', () => {
Expand Down
38 changes: 38 additions & 0 deletions __tests__/diff-snapshot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,44 @@ describe('diff-snapshot', () => {
expect(result.diffRatio).toBe(0.025);
});

it('should pass with allowSizeMismatch: true if image passed is a different size but <= failureThreshold pixel', () => {
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 250 });
const result = diffImageToSnapshot({
receivedImageBuffer: mockBigImageBuffer,
snapshotIdentifier: mockSnapshotIdentifier,
snapshotsDir: mockSnapshotsDir,
diffDir: mockDiffDir,
updateSnapshot: false,
failureThreshold: 250,
failureThresholdType: 'pixel',
allowSizeMismatch: true,
});

expect(result.pass).toBe(true);
expect(result.diffSize).toBe(true);
expect(result.diffPixelCount).toBe(250);
expect(result.diffRatio).toBe(0.1 / 9);
});

it('should fail with allowSizeMismatch: true if image passed is a different size but > failureThreshold pixel', () => {
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 250 });
const result = diffImageToSnapshot({
receivedImageBuffer: mockBigImageBuffer,
snapshotIdentifier: mockSnapshotIdentifier,
snapshotsDir: mockSnapshotsDir,
diffDir: mockDiffDir,
updateSnapshot: false,
failureThreshold: 0,
failureThresholdType: 'pixel',
allowSizeMismatch: true,
});

expect(result.pass).toBe(false);
expect(result.diffSize).toBe(true);
expect(result.diffPixelCount).toBe(250);
expect(result.diffRatio).toBe(0.1 / 9);
});

it('should pass = image checksums', () => {
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 0 });
const result = diffImageToSnapshot({
Expand Down
62 changes: 47 additions & 15 deletions src/diff-snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,38 @@ const shouldUpdate = ({ pass, updateSnapshot, updatePassedSnapshot }) => (
(!pass && updateSnapshot) || (pass && updatePassedSnapshot)
);

const shouldFail = ({
totalPixels,
diffPixelCount,
hasSizeMismatch,
allowSizeMismatch,
failureThresholdType,
failureThreshold,
}) => {
let pass = false;
let diffSize = false;
const diffRatio = diffPixelCount / totalPixels;
if (hasSizeMismatch) {
// do not fail if allowSizeMismatch is set
pass = allowSizeMismatch;
diffSize = true;
}
if (!diffSize || pass === true) {
if (failureThresholdType === 'pixel') {
pass = diffPixelCount <= failureThreshold;
} else if (failureThresholdType === 'percent') {
pass = diffRatio <= failureThreshold;
} else {
throw new Error(`Unknown failureThresholdType: ${failureThresholdType}. Valid options are "pixel" or "percent".`);
}
}
return {
pass,
diffSize,
diffRatio,
};
};

function diffImageToSnapshot(options) {
const {
receivedImageBuffer,
Expand All @@ -96,6 +128,7 @@ function diffImageToSnapshot(options) {
failureThreshold,
failureThresholdType,
blur,
allowSizeMismatch = false,
} = options;

let result = {};
Expand Down Expand Up @@ -140,9 +173,6 @@ function diffImageToSnapshot(options) {

const diffImage = new PNG({ width: imageWidth, height: imageHeight });

let pass = false;
let diffSize = false;
let diffRatio = 0;
let diffPixelCount = 0;

diffPixelCount = pixelmatch(
Expand All @@ -155,18 +185,19 @@ function diffImageToSnapshot(options) {
);

const totalPixels = imageWidth * imageHeight;
diffRatio = diffPixelCount / totalPixels;
// Always fail test on image size mismatch
if (hasSizeMismatch) {
pass = false;
diffSize = true;
} else if (failureThresholdType === 'pixel') {
pass = diffPixelCount <= failureThreshold;
} else if (failureThresholdType === 'percent') {
pass = diffRatio <= failureThreshold;
} else {
throw new Error(`Unknown failureThresholdType: ${failureThresholdType}. Valid options are "pixel" or "percent".`);
}

const {
pass,
diffSize,
diffRatio,
} = shouldFail({
totalPixels,
diffPixelCount,
hasSizeMismatch,
allowSizeMismatch,
failureThresholdType,
failureThreshold,
});

if (isFailure({ pass, updateSnapshot })) {
mkdirp.sync(diffDir);
Expand Down Expand Up @@ -213,6 +244,7 @@ function diffImageToSnapshot(options) {
} else {
result = {
pass,
diffSize,
diffRatio,
diffPixelCount,
diffOutputPath,
Expand Down