Skip to content

Commit

Permalink
feat(options): add option to pass on size missmatch (#174)
Browse files Browse the repository at this point in the history
if the option `allowSizeMismatch` is set, a build will not always fail on
images with different sizes. Missing or Added Pixel will be counted as a
mismatch and respected by the set threshold.

Related #83, #85
  • Loading branch information
adrianjost authored Apr 17, 2020
1 parent eb761e9 commit cee46b1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 15 deletions.
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

0 comments on commit cee46b1

Please sign in to comment.