Skip to content

Commit

Permalink
feat: inline images support (#244)
Browse files Browse the repository at this point in the history
Co-authored-by: Marcus R. Brown <[email protected]>
  • Loading branch information
LukeChannings and marcusrbrown authored Dec 16, 2020
1 parent 07765f5 commit b82b068
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,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.
* `dumpInlineDiffToConsole`: (default `false`) Will output the image to the terminal using iTerm's [Inline Images Protocol](https://iterm2.com/documentation-images.html). If the term is not compatible, it does the same thing as `dumpDiffToConsole`.
* `allowSizeMismatch`: (default `false`) If set to true, the build will not fail when the screenshots to compare have different sizes.

```javascript
Expand Down
25 changes: 25 additions & 0 deletions __tests__/__snapshots__/index.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,31 @@ exports[`toMatchImageSnapshot dumpDiffToConsole imgSrcString is not added to con
See diff for details: path/to/result.png"
`;

exports[`toMatchImageSnapshot dumpInlineDiffToConsole falls back to dumpDiffToConsole if the terminal is unsupported 2`] = `
"Expected image to match or be a close match to snapshot but was 80% different from snapshot (600 differing pixels).
See diff for details: path/to/result.png
Or paste below image diff string to your browser\`s URL bar.
pretendthisisanimagebase64string"
`;

exports[`toMatchImageSnapshot dumpInlineDiffToConsole uses Inline Image Protocol in iTerm 2`] = `
"Expected image to match or be a close match to snapshot but was 80% different from snapshot (600 differing pixels).
See diff for details: path/to/result.png
]1337;File=name=cGF0aC90by9yZXN1bHQucG5n;inline=1;width=40:pretendthisisanimagebase64string
"
`;

exports[`toMatchImageSnapshot dumpInlineDiffToConsole uses Inline Image Protocol when ENABLE_INLINE_DIFF is set 2`] = `
"Expected image to match or be a close match to snapshot but was 80% different from snapshot (600 differing pixels).
See diff for details: path/to/result.png
]1337;File=name=cGF0aC90by9yZXN1bHQucG5n;inline=1;width=40:pretendthisisanimagebase64string
"
`;

exports[`toMatchImageSnapshot passes diffImageToSnapshot everything it needs to create a snapshot and compare if needed 1`] = `
Object {
"allowSizeMismatch": false,
Expand Down
80 changes: 80 additions & 0 deletions __tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,86 @@ describe('toMatchImageSnapshot', () => {
.toThrowErrorMatchingSnapshot();
});
});

describe('dumpInlineDiffToConsole', () => {
const { TERM_PROGRAM } = process.env;

afterEach(() => { process.env.TERM_PROGRAM = TERM_PROGRAM; });

it('falls back to dumpDiffToConsole if the terminal is unsupported', () => {
const mockDiffResult = {
pass: false,
diffOutputPath: 'path/to/result.png',
diffRatio: 0.8,
diffPixelCount: 600,
imgSrcString: 'pretendthisisanimagebase64string',
};
setupMock(mockDiffResult);
const { toMatchImageSnapshot } = require('../src/index');
expect.extend({ toMatchImageSnapshot });

jest.doMock('chalk', () => ({
constructor: ChalkMock,
}));

process.env.TERM_PROGRAM = 'xterm';

expect(() => expect('pretendthisisanimagebuffer').toMatchImageSnapshot({ dumpInlineDiffToConsole: true }))
.toThrowErrorMatchingSnapshot();
});

it('uses Inline Image Protocol in iTerm', () => {
const mockDiffResult = {
pass: false,
diffOutputPath: 'path/to/result.png',
diffRatio: 0.8,
diffPixelCount: 600,
imgSrcString: 'pretendthisisanimagebase64string',
imageDimensions: {
receivedHeight: 100,
receivedWidth: 200,
},
};
setupMock(mockDiffResult);
const { toMatchImageSnapshot } = require('../src/index');
expect.extend({ toMatchImageSnapshot });

jest.doMock('chalk', () => ({
constructor: ChalkMock,
}));

process.env.TERM_PROGRAM = 'iTerm.app';

expect(() => expect('pretendthisisanimagebuffer').toMatchImageSnapshot({ dumpInlineDiffToConsole: true }))
.toThrowErrorMatchingSnapshot();
});

it('uses Inline Image Protocol when ENABLE_INLINE_DIFF is set', () => {
const mockDiffResult = {
pass: false,
diffOutputPath: 'path/to/result.png',
diffRatio: 0.8,
diffPixelCount: 600,
imgSrcString: 'pretendthisisanimagebase64string',
imageDimensions: {
receivedHeight: 100,
receivedWidth: 200,
},
};
setupMock(mockDiffResult);
const { toMatchImageSnapshot } = require('../src/index');
expect.extend({ toMatchImageSnapshot });

jest.doMock('chalk', () => ({
constructor: ChalkMock,
}));

process.env.ENABLE_INLINE_DIFF = true;

expect(() => expect('pretendthisisanimagebuffer').toMatchImageSnapshot({ dumpInlineDiffToConsole: true }))
.toThrowErrorMatchingSnapshot();
});
});
});

describe('updateSnapshotState', () => {
Expand Down
13 changes: 12 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function checkResult({
snapshotIdentifier,
chalk,
dumpDiffToConsole,
dumpInlineDiffToConsole,
allowSizeMismatch,
}) {
let pass = true;
Expand Down Expand Up @@ -75,7 +76,14 @@ function checkResult({

failure += `${chalk.bold.red('See diff for details:')} ${chalk.red(result.diffOutputPath)}`;

if (dumpDiffToConsole) {
const supportedInlineTerms = [
'iTerm.app',
'WezTerm',
];

if (dumpInlineDiffToConsole && (supportedInlineTerms.includes(process.env.TERM_PROGRAM) || 'ENABLE_INLINE_DIFF' in process.env)) {
failure += `\n\n\t\x1b]1337;File=name=${Buffer.from(result.diffOutputPath).toString('base64')};inline=1;width=40:${result.imgSrcString.replace('data:image/png;base64,', '')}\x07\x1b\n\n`;
} else if (dumpDiffToConsole || dumpInlineDiffToConsole) {
failure += `\n${chalk.bold.red('Or paste below image diff string to your browser`s URL bar.')}\n ${result.imgSrcString}`;
}

Expand Down Expand Up @@ -136,6 +144,7 @@ function configureToMatchImageSnapshot({
blur: commonBlur = 0,
runInProcess: commonRunInProcess = false,
dumpDiffToConsole: commonDumpDiffToConsole = false,
dumpInlineDiffToConsole: commonDumpInlineDiffToConsole = false,
allowSizeMismatch: commonAllowSizeMismatch = false,
comparisonMethod: commonComparisonMethod = 'pixelmatch',
} = {}) {
Expand All @@ -152,6 +161,7 @@ function configureToMatchImageSnapshot({
blur = commonBlur,
runInProcess = commonRunInProcess,
dumpDiffToConsole = commonDumpDiffToConsole,
dumpInlineDiffToConsole = commonDumpInlineDiffToConsole,
allowSizeMismatch = commonAllowSizeMismatch,
comparisonMethod = commonComparisonMethod,
} = {}) {
Expand Down Expand Up @@ -218,6 +228,7 @@ function configureToMatchImageSnapshot({
snapshotIdentifier,
chalk,
dumpDiffToConsole,
dumpInlineDiffToConsole,
allowSizeMismatch,
});
};
Expand Down

0 comments on commit b82b068

Please sign in to comment.