Skip to content

Commit 27194da

Browse files
authored
fix(toHaveScreenshot): nice error when rebasing with bad expectation (microsoft#37243)
1 parent 981bcd5 commit 27194da

3 files changed

Lines changed: 33 additions & 10 deletions

File tree

packages/playwright-core/src/server/utils/comparators.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,11 @@ function validateBuffer(buffer: Buffer, mimeType: string): void {
9898
if (mimeType === 'image/png') {
9999
const pngMagicNumber = [137, 80, 78, 71, 13, 10, 26, 10];
100100
if (buffer.length < pngMagicNumber.length || !pngMagicNumber.every((byte, index) => buffer[index] === byte))
101-
throw new Error('could not decode image as PNG.');
101+
throw new Error('Could not decode expected image as PNG.');
102102
} else if (mimeType === 'image/jpeg') {
103103
const jpegMagicNumber = [255, 216];
104104
if (buffer.length < jpegMagicNumber.length || !jpegMagicNumber.every((byte, index) => buffer[index] === byte))
105-
throw new Error('could not decode image as JPEG.');
105+
throw new Error('Could not decode expected image as JPEG.');
106106
}
107107
}
108108

packages/playwright/src/matchers/toMatchSnapshot.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,9 @@ export async function toHaveScreenshot(
398398
expectScreenshotOptions.expected = helper.updateSnapshots === 'all' ? undefined : expected;
399399

400400
const { actual, previous, diff, errorMessage, log, timedOut } = await page._expectScreenshot(expectScreenshotOptions);
401-
const writeFiles = () => {
402-
writeFileSync(helper.expectedPath, actual!);
403-
writeFileSync(helper.actualPath, actual!);
401+
const writeFiles = (actualBuffer: Buffer) => {
402+
writeFileSync(helper.expectedPath, actualBuffer);
403+
writeFileSync(helper.actualPath, actualBuffer);
404404
/* eslint-disable no-console */
405405
console.log(helper.expectedPath + ' is re-generated, writing actual.');
406406
return helper.createMatcherResult(helper.expectedPath + ' running with --update-snapshots, writing actual.', true);
@@ -410,13 +410,18 @@ export async function toHaveScreenshot(
410410
// Screenshot is matching, but is not necessarily the same as the expected.
411411
if (helper.updateSnapshots === 'all' && actual && compareBuffersOrStrings(actual, expected)) {
412412
console.log(helper.expectedPath + ' is re-generated, writing actual.');
413-
return writeFiles();
413+
return writeFiles(actual);
414414
}
415415
return helper.handleMatching();
416416
}
417417

418-
if (helper.updateSnapshots === 'changed' || helper.updateSnapshots === 'all')
419-
return writeFiles();
418+
if (helper.updateSnapshots === 'changed' || helper.updateSnapshots === 'all') {
419+
if (actual)
420+
return writeFiles(actual);
421+
let header = matcherHint(this, undefined, 'toHaveScreenshot', receiver, undefined, undefined, timedOut ? timeout : undefined);
422+
header += ' Failed to re-generate expected.\n';
423+
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo);
424+
}
420425

421426
const header = matcherHint(this, undefined, 'toHaveScreenshot', receiver, undefined, undefined, timedOut ? timeout : undefined);
422427
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo);

tests/playwright-test/to-have-screenshot.spec.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,8 +1350,26 @@ test('should throw pretty error if expected PNG file is not a PNG', async ({ run
13501350
`,
13511351
});
13521352
expect(result.exitCode).toBe(1);
1353-
expect(result.output).toContain('could not decode image as PNG.');
1354-
expect(result.output).toContain('could not decode image as JPEG.');
1353+
expect(result.output).toContain('Could not decode expected image as PNG.');
1354+
expect(result.output).toContain('Could not decode expected image as JPEG.');
1355+
});
1356+
1357+
test('should throw pretty error if expected PNG file is not a PNG while rebasing', async ({ runInlineTest }) => {
1358+
const result = await runInlineTest({
1359+
...playwrightConfig({
1360+
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
1361+
}),
1362+
'__screenshots__/a.spec.js/snapshot.png': 'not a png',
1363+
'a.spec.js': `
1364+
const { test, expect } = require('@playwright/test');
1365+
test('png', async ({ page }) => {
1366+
await expect(page).toHaveScreenshot('snapshot.png');
1367+
});
1368+
`,
1369+
}, { 'update-snapshots': true });
1370+
expect(result.exitCode).toBe(1);
1371+
expect(result.output).toContain('Failed to re-generate expected.');
1372+
expect(result.output).toContain('Could not decode expected image as PNG.');
13551373
});
13561374

13571375
test('should support maskColor option', async ({ runInlineTest }) => {

0 commit comments

Comments
 (0)