diff --git a/README.md b/README.md index 81028a0a..633f8494 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,16 @@ You can control where snapshots should be located by setting two environment var The `actual` directory always points to the configured screenshot directory. + +**Configure snapshot generation** + +You can control if diff images are generated for successful tests by setting the following environment variable: + +| Variable | Description | +|----------------------|---------------------------| +| ALWAYS_GENERATE_DIFF | Boolean, defaults to true | + + ## To Use Add `cy.compareSnapshot('home');` in your tests specs whenever you want to test for visual regressions, making sure to replace `home` with a relevant name. You can also add an optional error threshold: Value can range from 0.00 (no difference) to 1.00 (every pixel is different). So, if you enter an error threshold of 0.51, the test would fail only if > 51% of pixels are different. diff --git a/src/command.js b/src/command.js index 1c0243c0..cbb33e67 100644 --- a/src/command.js +++ b/src/command.js @@ -9,6 +9,7 @@ function compareSnapshotCommand(defaultScreenshotOptions) { (subject, name, params = {}) => { const SNAPSHOT_BASE_DIRECTORY = Cypress.env('SNAPSHOT_BASE_DIRECTORY'); const SNAPSHOT_DIFF_DIRECTORY = Cypress.env('SNAPSHOT_DIFF_DIRECTORY'); + const ALWAYS_GENERATE_DIFF = Cypress.env('ALWAYS_GENERATE_DIFF'); let screenshotOptions = defaultScreenshotOptions; let errorThreshold = 0.0; @@ -51,17 +52,13 @@ function compareSnapshotCommand(defaultScreenshotOptions) { specDirectory: Cypress.spec.name, baseDir: SNAPSHOT_BASE_DIRECTORY, diffDir: SNAPSHOT_DIFF_DIRECTORY, + keepDiff: ALWAYS_GENERATE_DIFF, + errorThreshold, }; cy.task('compareSnapshotsPlugin', options).then((results) => { if (results.error) { throw deserializeError(results.error); } - - if (results.percentage > errorThreshold) { - throw new Error( - `The "${name}" image is different. Threshold limit exceeded! \nExpected: ${errorThreshold} \nActual: ${results.percentage}` - ); - } }); } } diff --git a/src/plugin.js b/src/plugin.js index f6456d9f..930f116c 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -15,6 +15,7 @@ const { let SNAPSHOT_BASE_DIRECTORY; let SNAPSHOT_DIFF_DIRECTORY; let CYPRESS_SCREENSHOT_DIR; +let ALWAYS_GENERATE_DIFF; function setupScreenshotPath(config) { // use cypress default path as fallback @@ -30,6 +31,11 @@ function setupSnapshotPaths(args) { args.diffDir || path.join(process.cwd(), 'cypress', 'snapshots', 'diff'); } +function setupDiffImageGeneration(args) { + ALWAYS_GENERATE_DIFF = true; + if (args.keepDiff === false) ALWAYS_GENERATE_DIFF = false; +} + function visualRegressionCopy(args) { setupSnapshotPaths(args); const baseDir = path.join(SNAPSHOT_BASE_DIRECTORY, args.specName); @@ -48,6 +54,7 @@ function visualRegressionCopy(args) { async function compareSnapshotsPlugin(args) { setupSnapshotPaths(args); + setupDiffImageGeneration(args); const fileName = sanitize(args.fileName); @@ -73,8 +80,6 @@ async function compareSnapshotsPlugin(args) { let percentage = 0; try { await createFolder(SNAPSHOT_DIFF_DIRECTORY, args.failSilently); - const specFolder = path.join(SNAPSHOT_DIFF_DIRECTORY, args.specDirectory); - await createFolder(specFolder, args.failSilently); const imgExpected = await parseImage(options.expectedImage); const imgActual = await parseImage(options.actualImage); const diff = new PNG({ @@ -103,7 +108,18 @@ async function compareSnapshotsPlugin(args) { ); percentage = (mismatchedPixels / diff.width / diff.height) ** 0.5; - diff.pack().pipe(fs.createWriteStream(options.diffImage)); + if (percentage > args.errorThreshold) { + const specFolder = path.join(SNAPSHOT_DIFF_DIRECTORY, args.specDirectory); + await createFolder(specFolder, args.failSilently); + diff.pack().pipe(fs.createWriteStream(options.diffImage)); + throw new Error( + `The "${fileName}" image is different. Threshold limit exceeded! \nExpected: ${args.errorThreshold} \nActual: ${percentage}` + ); + } else if (ALWAYS_GENERATE_DIFF) { + const specFolder = path.join(SNAPSHOT_DIFF_DIRECTORY, args.specDirectory); + await createFolder(specFolder, args.failSilently); + diff.pack().pipe(fs.createWriteStream(options.diffImage)); + } } catch (error) { return { error: errorSerialize(error) }; }