From 6b687b6d69103686ac05fcd841952dd31dafce06 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Mon, 5 Jun 2023 14:57:06 -0700 Subject: [PATCH] fix(toHaveScreenshot): attach newly created missing expectations (#23528) Fixes #23090. --- .../src/matchers/toMatchSnapshot.ts | 1 + .../to-have-screenshot.spec.ts | 25 +++++++++++++++++-- tests/playwright-test/ui-mode-trace.spec.ts | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/playwright-test/src/matchers/toMatchSnapshot.ts b/packages/playwright-test/src/matchers/toMatchSnapshot.ts index 7380a56f92..b3aafb1404 100644 --- a/packages/playwright-test/src/matchers/toMatchSnapshot.ts +++ b/packages/playwright-test/src/matchers/toMatchSnapshot.ts @@ -179,6 +179,7 @@ class SnapshotHelper { if (isWriteMissingMode) { writeFileSync(this.snapshotPath, actual); writeFileSync(this.actualPath, actual); + this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-actual'), contentType: this.mimeType, path: this.actualPath }); } const message = `A snapshot doesn't exist at ${this.snapshotPath}${isWriteMissingMode ? ', writing actual.' : '.'}`; if (this.updateSnapshots === 'all') { diff --git a/tests/playwright-test/to-have-screenshot.spec.ts b/tests/playwright-test/to-have-screenshot.spec.ts index a5a46758e7..fe8e78cf3c 100644 --- a/tests/playwright-test/to-have-screenshot.spec.ts +++ b/tests/playwright-test/to-have-screenshot.spec.ts @@ -213,7 +213,9 @@ test('should report toHaveScreenshot step with expectation name in title', async `end browserContext.newPage`, `end fixture: page`, `end Before Hooks`, + `end attach "foo-actual.png"`, `end expect.toHaveScreenshot(foo.png)`, + `end attach "is-a-test-1-actual.png"`, `end expect.toHaveScreenshot(is-a-test-1.png)`, `end fixture: page`, `end fixture: context`, @@ -564,7 +566,7 @@ test('should not fail if --ignore-snapshots is passed', async ({ runInlineTest } expect(result.exitCode).toBe(0); }); -test('should write missing expectations locally twice and continue', async ({ runInlineTest }, testInfo) => { +test('should write missing expectations locally twice and attach them', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ ...playwrightConfig({ snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', @@ -576,7 +578,10 @@ test('should write missing expectations locally twice and continue', async ({ ru await expect(page).toHaveScreenshot('snapshot2.png'); console.log('Here we are!'); }); - ` + test.afterEach(async ({}, testInfo) => { + console.log('\\n%%' + JSON.stringify(testInfo.attachments)); + }); + `, }); expect(result.exitCode).toBe(1); @@ -595,6 +600,22 @@ test('should write missing expectations locally twice and continue', async ({ ru const stackLines = result.output.split('\n').filter(line => line.includes(' at ')).filter(line => !line.includes(testInfo.outputPath())); expect(result.output).toContain('a.spec.js:5'); expect(stackLines.length).toBe(0); + + const attachments = result.outputLines.map(l => JSON.parse(l))[0]; + for (const attachment of attachments) + attachment.path = attachment.path.replace(/\\/g, '/').replace(/.*test-results\//, ''); + expect(attachments).toEqual([ + { + name: 'snapshot-actual.png', + contentType: 'image/png', + path: 'a-is-a-test/snapshot-actual.png' + }, + { + name: 'snapshot2-actual.png', + contentType: 'image/png', + path: 'a-is-a-test/snapshot2-actual.png' + }, + ]); }); test('shouldn\'t write missing expectations locally for negated matcher', async ({ runInlineTest }, testInfo) => { diff --git a/tests/playwright-test/ui-mode-trace.spec.ts b/tests/playwright-test/ui-mode-trace.spec.ts index 3ddc15cf59..fa919d5dc7 100644 --- a/tests/playwright-test/ui-mode-trace.spec.ts +++ b/tests/playwright-test/ui-mode-trace.spec.ts @@ -99,6 +99,7 @@ test('should merge screenshot assertions', async ({ runUITest }, testInfo) => { /Before Hooks[\d.]+m?s/, /page.setContent[\d.]+m?s/, /expect.toHaveScreenshot[\d.]+m?s/, + /attach "trace-test-1-actual\.png"[\d.]+m?s/, /After Hooks[\d.]+m?s/, /fixture: page[\d.]+m?s/, /fixture: context[\d.]+m?s/,