Skip to content

Commit cee46b1

Browse files
authored
feat(options): add option to pass on size missmatch (#174)
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
1 parent eb761e9 commit cee46b1

File tree

3 files changed

+86
-15
lines changed

3 files changed

+86
-15
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ See [the examples](./examples/README.md) for more detailed usage or read about a
114114
* `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.
115115
* `runInProcess`: (default `false`) Runs the diff in process without spawning a child process.
116116
* `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.
117+
* `allowSizeMismatch`: (default `false`) If set to true, the build will not fail when the screenshots to compare have different sizes.
117118

118119
```javascript
119120
it('should demonstrate this matcher`s usage with a custom pixelmatch config', () => {

__tests__/diff-snapshot.spec.js

+38
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,44 @@ describe('diff-snapshot', () => {
244244
expect(result.diffRatio).toBe(0.025);
245245
});
246246

247+
it('should pass with allowSizeMismatch: true if image passed is a different size but <= failureThreshold pixel', () => {
248+
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 250 });
249+
const result = diffImageToSnapshot({
250+
receivedImageBuffer: mockBigImageBuffer,
251+
snapshotIdentifier: mockSnapshotIdentifier,
252+
snapshotsDir: mockSnapshotsDir,
253+
diffDir: mockDiffDir,
254+
updateSnapshot: false,
255+
failureThreshold: 250,
256+
failureThresholdType: 'pixel',
257+
allowSizeMismatch: true,
258+
});
259+
260+
expect(result.pass).toBe(true);
261+
expect(result.diffSize).toBe(true);
262+
expect(result.diffPixelCount).toBe(250);
263+
expect(result.diffRatio).toBe(0.1 / 9);
264+
});
265+
266+
it('should fail with allowSizeMismatch: true if image passed is a different size but > failureThreshold pixel', () => {
267+
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 250 });
268+
const result = diffImageToSnapshot({
269+
receivedImageBuffer: mockBigImageBuffer,
270+
snapshotIdentifier: mockSnapshotIdentifier,
271+
snapshotsDir: mockSnapshotsDir,
272+
diffDir: mockDiffDir,
273+
updateSnapshot: false,
274+
failureThreshold: 0,
275+
failureThresholdType: 'pixel',
276+
allowSizeMismatch: true,
277+
});
278+
279+
expect(result.pass).toBe(false);
280+
expect(result.diffSize).toBe(true);
281+
expect(result.diffPixelCount).toBe(250);
282+
expect(result.diffRatio).toBe(0.1 / 9);
283+
});
284+
247285
it('should pass = image checksums', () => {
248286
const diffImageToSnapshot = setupTest({ snapshotExists: true, pixelmatchResult: 0 });
249287
const result = diffImageToSnapshot({

src/diff-snapshot.js

+47-15
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,38 @@ const shouldUpdate = ({ pass, updateSnapshot, updatePassedSnapshot }) => (
8383
(!pass && updateSnapshot) || (pass && updatePassedSnapshot)
8484
);
8585

86+
const shouldFail = ({
87+
totalPixels,
88+
diffPixelCount,
89+
hasSizeMismatch,
90+
allowSizeMismatch,
91+
failureThresholdType,
92+
failureThreshold,
93+
}) => {
94+
let pass = false;
95+
let diffSize = false;
96+
const diffRatio = diffPixelCount / totalPixels;
97+
if (hasSizeMismatch) {
98+
// do not fail if allowSizeMismatch is set
99+
pass = allowSizeMismatch;
100+
diffSize = true;
101+
}
102+
if (!diffSize || pass === true) {
103+
if (failureThresholdType === 'pixel') {
104+
pass = diffPixelCount <= failureThreshold;
105+
} else if (failureThresholdType === 'percent') {
106+
pass = diffRatio <= failureThreshold;
107+
} else {
108+
throw new Error(`Unknown failureThresholdType: ${failureThresholdType}. Valid options are "pixel" or "percent".`);
109+
}
110+
}
111+
return {
112+
pass,
113+
diffSize,
114+
diffRatio,
115+
};
116+
};
117+
86118
function diffImageToSnapshot(options) {
87119
const {
88120
receivedImageBuffer,
@@ -96,6 +128,7 @@ function diffImageToSnapshot(options) {
96128
failureThreshold,
97129
failureThresholdType,
98130
blur,
131+
allowSizeMismatch = false,
99132
} = options;
100133

101134
let result = {};
@@ -140,9 +173,6 @@ function diffImageToSnapshot(options) {
140173

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

143-
let pass = false;
144-
let diffSize = false;
145-
let diffRatio = 0;
146176
let diffPixelCount = 0;
147177

148178
diffPixelCount = pixelmatch(
@@ -155,18 +185,19 @@ function diffImageToSnapshot(options) {
155185
);
156186

157187
const totalPixels = imageWidth * imageHeight;
158-
diffRatio = diffPixelCount / totalPixels;
159-
// Always fail test on image size mismatch
160-
if (hasSizeMismatch) {
161-
pass = false;
162-
diffSize = true;
163-
} else if (failureThresholdType === 'pixel') {
164-
pass = diffPixelCount <= failureThreshold;
165-
} else if (failureThresholdType === 'percent') {
166-
pass = diffRatio <= failureThreshold;
167-
} else {
168-
throw new Error(`Unknown failureThresholdType: ${failureThresholdType}. Valid options are "pixel" or "percent".`);
169-
}
188+
189+
const {
190+
pass,
191+
diffSize,
192+
diffRatio,
193+
} = shouldFail({
194+
totalPixels,
195+
diffPixelCount,
196+
hasSizeMismatch,
197+
allowSizeMismatch,
198+
failureThresholdType,
199+
failureThreshold,
200+
});
170201

171202
if (isFailure({ pass, updateSnapshot })) {
172203
mkdirp.sync(diffDir);
@@ -213,6 +244,7 @@ function diffImageToSnapshot(options) {
213244
} else {
214245
result = {
215246
pass,
247+
diffSize,
216248
diffRatio,
217249
diffPixelCount,
218250
diffOutputPath,

0 commit comments

Comments
 (0)