Skip to content
New issue

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

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

Already on GitHub? # to your account

Allow customizing snapshot subdirectory #158

Closed
wants to merge 2 commits into from
Closed
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
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# cypress-image-snapshot

## 4.0.1
### Patch Changes


### Patch Changes

- [`17f7927`](https://github.com/jaredpalmer/cypress-image-snapshot/commit/17f7927384bfdbd6cbb65d344c8337d32926b691) Thanks [@jaredpalmer](https://github.com/jaredpalmer)! - When using native retries that come in Cypress v5+ real image failures are marked as passed on the retries because cypress names the snapshots as 'filename (attempt X).png (and there is no configuration option to change this). The fix just removes the ' (attempt X)' suffix from the filename.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Cypress Image Snapshot


Cypress Image Snapshot binds [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot)'s image diffing logic to [Cypress.io](https://cypress.io) commands. **The goal is to catch visual regressions during integration tests.**

[![Discord](https://img.shields.io/discord/769256827007139912?label=%F0%9F%92%AC%20%20join%20us%20on%20discord&style=plastic)](https://discord.com/invite/RevdZTYMzr)
Expand Down Expand Up @@ -177,6 +176,25 @@ addMatchImageSnapshotCommand({
});
```

## Plugin options

- `getSpecSnapshotFolder`: a function that allows customizing sub directory within snapshots folder.

`getSpecSnapshotFolder` is particularly useful to make paths to snapshots consistent.
Because of [the existing behaviour](https://github.com/cypress-io/cypress/issues/1586) of Cypress,
`cy.screenshot` in the Interactive mode puts screenshots in different sub directories.

If you want to store all your snapshots in the root of snapshots folder, you may override the spec folder like that:

```
const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin');

module.exports = (on, config) => {
const getSpecSnapshotFolder = (specScreenshotFolder) => '';
addMatchImageSnapshotPlugin(on, config, {getSpecSnapshotFolder});
};
```

## How it works

We really enjoy the diffing workflow of jest-image-snapshot and wanted to have a similar workflow when using Cypress. Because of this, under the hood we use some of jest-image-snapshot's internals and simply bind them to Cypress's commands and plugins APIs.
Expand Down
34 changes: 33 additions & 1 deletion __tests__/plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('plugin', () => {

matchImageSnapshotOptions()(options);

const result = matchImageSnapshotPlugin({
const result = matchImageSnapshotPlugin()({
path: '/cypress/screenshots/path/to/cheese',
});
expect(result).toEqual({
Expand All @@ -53,4 +53,36 @@ describe('plugin', () => {

process.cwd = originalCwd;
});

it('should map spec screenshot folder to a custom one', () => {
const originalCwd = process.cwd;
process.cwd = () => '';

const options = {
screenshotsFolder: '/cypress/screenshots',
updateSnapshots: true,
};

matchImageSnapshotOptions()(options);

const result = matchImageSnapshotPlugin({
getSpecSnapshotFolder: () => '',
})({
path: '/cypress/screenshots/path/to/cheese',
});
expect(result).toEqual({
path: '/cypress/snapshots/__diff_output__/cheese.diff.png',
});
expect(diffImageToSnapshot).toHaveBeenCalledWith({
snapshotsDir: '/cypress/snapshots',
diffDir: '/cypress/snapshots/__diff_output__',
updateSnapshot: true,
receivedImageBuffer: 'cheese',
snapshotIdentifier: 'cheese',
failureThreshold: 0,
failureThresholdType: 'pixel',
});

process.cwd = originalCwd;
});
});
29 changes: 18 additions & 11 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const kebabSnap = '-snap.png';
const dotSnap = '.snap.png';
const dotDiff = '.diff.png';

const defaultGetSpecSnapshotFolder = specScreenshotDir => specScreenshotDir;

export const cachePath = path.join(
pkgDir.sync(process.cwd()),
'cypress',
Expand Down Expand Up @@ -49,7 +51,12 @@ export function matchImageSnapshotResult() {
};
}

export function matchImageSnapshotPlugin({ path: screenshotPath }) {
export const matchImageSnapshotPlugin = (pluginOptions = {}) => ({
path: screenshotPath,
}) => {
const {
getSpecSnapshotFolder = defaultGetSpecSnapshotFolder,
} = pluginOptions;
if (!snapshotRunning) {
return null;
}
Expand All @@ -69,17 +76,17 @@ export function matchImageSnapshotPlugin({ path: screenshotPath }) {
const receivedImageBuffer = fs.readFileSync(screenshotPath);
fs.removeSync(screenshotPath);

const { dir: screenshotDir, name } = path.parse(
screenshotPath
);
const { dir: screenshotDir, name } = path.parse(screenshotPath);

// remove the cypress v5+ native retries suffix from the file name
const snapshotIdentifier = name.replace(/ \(attempt [0-9]+\)/, '');

const relativePath = path.relative(screenshotsFolder, screenshotDir);
const specSnapshotDir = getSpecSnapshotFolder(
path.relative(screenshotsFolder, screenshotDir)
);
const snapshotsDir = customSnapshotsDir
? path.join(process.cwd(), customSnapshotsDir, relativePath)
: path.join(screenshotsFolder, '..', 'snapshots', relativePath);
? path.join(process.cwd(), customSnapshotsDir, specSnapshotDir)
: path.join(screenshotsFolder, '..', 'snapshots', specSnapshotDir);

const snapshotKebabPath = path.join(
snapshotsDir,
Expand All @@ -91,7 +98,7 @@ export function matchImageSnapshotPlugin({ path: screenshotPath }) {
);

const diffDir = customDiffDir
? path.join(process.cwd(), customDiffDir, relativePath)
? path.join(process.cwd(), customDiffDir, specSnapshotDir)
: path.join(snapshotsDir, '__diff_output__');
const diffDotPath = path.join(diffDir, `${snapshotIdentifier}${dotDiff}`);

Expand Down Expand Up @@ -130,12 +137,12 @@ export function matchImageSnapshotPlugin({ path: screenshotPath }) {
return {
path: snapshotDotPath,
};
}
};

export function addMatchImageSnapshotPlugin(on, config) {
export function addMatchImageSnapshotPlugin(on, config, pluginOptions) {
on('task', {
[MATCH]: matchImageSnapshotOptions(config),
[RECORD]: matchImageSnapshotResult(config),
});
on('after:screenshot', matchImageSnapshotPlugin);
on('after:screenshot', matchImageSnapshotPlugin(pluginOptions));
}