This was regressed awhile ago.
In v1.17 we shipped the following code: 30e15ad36f/packages/playwright-test/src/matchers/golden.ts (L122-L131)
`toMatchSnapshot` should fallback to text comparator in case of
unknown extension and string data.
Fixes #12862
This commit is contained in:
parent
c090a55828
commit
0093e8a753
|
|
@ -31,7 +31,7 @@ import { Progress, ProgressController } from './progress';
|
||||||
import { assert, isError } from '../utils/utils';
|
import { assert, isError } from '../utils/utils';
|
||||||
import { ManualPromise } from '../utils/async';
|
import { ManualPromise } from '../utils/async';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
import { mimeTypeToComparator, ImageComparatorOptions, ComparatorResult } from '../utils/comparators';
|
import { getComparator, ImageComparatorOptions, ComparatorResult } from '../utils/comparators';
|
||||||
import { SelectorInfo, Selectors } from './selectors';
|
import { SelectorInfo, Selectors } from './selectors';
|
||||||
import { CallMetadata, SdkObject } from './instrumentation';
|
import { CallMetadata, SdkObject } from './instrumentation';
|
||||||
import { Artifact } from './artifact';
|
import { Artifact } from './artifact';
|
||||||
|
|
@ -447,7 +447,7 @@ export class Page extends SdkObject {
|
||||||
return await this._screenshotter.screenshotPage(progress, options.screenshotOptions || {});
|
return await this._screenshotter.screenshotPage(progress, options.screenshotOptions || {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const comparator = mimeTypeToComparator['image/png'];
|
const comparator = getComparator('image/png');
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
const isGeneratingNewScreenshot = !options.expected;
|
const isGeneratingNewScreenshot = !options.expected;
|
||||||
if (isGeneratingNewScreenshot && options.isNot)
|
if (isGeneratingNewScreenshot && options.isNot)
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,16 @@ const { PNG } = require(require.resolve('pngjs', { paths: [require.resolve('pixe
|
||||||
export type ImageComparatorOptions = { threshold?: number, maxDiffPixels?: number, maxDiffPixelRatio?: number };
|
export type ImageComparatorOptions = { threshold?: number, maxDiffPixels?: number, maxDiffPixelRatio?: number };
|
||||||
export type ComparatorResult = { diff?: Buffer; errorMessage?: string; } | null;
|
export type ComparatorResult = { diff?: Buffer; errorMessage?: string; } | null;
|
||||||
export type Comparator = (actualBuffer: Buffer | string, expectedBuffer: Buffer, options?: any) => ComparatorResult;
|
export type Comparator = (actualBuffer: Buffer | string, expectedBuffer: Buffer, options?: any) => ComparatorResult;
|
||||||
export const mimeTypeToComparator: { [key: string]: Comparator } = {
|
|
||||||
'application/octet-string': compareBuffersOrStrings,
|
export function getComparator(mimeType: string): Comparator {
|
||||||
'image/png': compareImages.bind(null, 'image/png'),
|
if (mimeType === 'image/png')
|
||||||
'image/jpeg': compareImages.bind(null, 'image/jpeg'),
|
return compareImages.bind(null, 'image/png');
|
||||||
'text/plain': compareText,
|
if (mimeType === 'image/jpeg')
|
||||||
};
|
return compareImages.bind(null, 'image/jpeg');
|
||||||
|
if (mimeType === 'text/plain')
|
||||||
|
return compareText;
|
||||||
|
return compareBuffersOrStrings;
|
||||||
|
}
|
||||||
|
|
||||||
function compareBuffersOrStrings(actualBuffer: Buffer | string, expectedBuffer: Buffer): ComparatorResult {
|
function compareBuffersOrStrings(actualBuffer: Buffer | string, expectedBuffer: Buffer): ComparatorResult {
|
||||||
if (typeof actualBuffer === 'string')
|
if (typeof actualBuffer === 'string')
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
import type { Expect } from '../types';
|
import type { Expect } from '../types';
|
||||||
import { currentTestInfo } from '../globals';
|
import { currentTestInfo } from '../globals';
|
||||||
import { mimeTypeToComparator, ImageComparatorOptions, Comparator } from 'playwright-core/lib/utils/comparators';
|
import { getComparator, ImageComparatorOptions, Comparator } from 'playwright-core/lib/utils/comparators';
|
||||||
import { addSuffixToFilePath, serializeError, sanitizeForFilePath, trimLongString, callLogText } from '../util';
|
import { addSuffixToFilePath, serializeError, sanitizeForFilePath, trimLongString, callLogText } from '../util';
|
||||||
import { UpdateSnapshots } from '../types';
|
import { UpdateSnapshots } from '../types';
|
||||||
import colors from 'colors/safe';
|
import colors from 'colors/safe';
|
||||||
|
|
@ -44,6 +44,7 @@ class SnapshotHelper<T extends ImageComparatorOptions> {
|
||||||
readonly kind: 'Screenshot'|'Snapshot';
|
readonly kind: 'Screenshot'|'Snapshot';
|
||||||
readonly updateSnapshots: UpdateSnapshots;
|
readonly updateSnapshots: UpdateSnapshots;
|
||||||
readonly comparatorOptions: ImageComparatorOptions;
|
readonly comparatorOptions: ImageComparatorOptions;
|
||||||
|
readonly comparator: Comparator;
|
||||||
readonly allOptions: T;
|
readonly allOptions: T;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|
@ -95,10 +96,7 @@ class SnapshotHelper<T extends ImageComparatorOptions> {
|
||||||
if (updateSnapshots === 'missing' && testInfo.retry < testInfo.project.retries)
|
if (updateSnapshots === 'missing' && testInfo.retry < testInfo.project.retries)
|
||||||
updateSnapshots = 'none';
|
updateSnapshots = 'none';
|
||||||
const mimeType = mime.getType(path.basename(snapshotPath)) ?? 'application/octet-string';
|
const mimeType = mime.getType(path.basename(snapshotPath)) ?? 'application/octet-string';
|
||||||
const comparator: Comparator = mimeTypeToComparator[mimeType];
|
this.comparator = getComparator(mimeType);
|
||||||
if (!comparator)
|
|
||||||
throw new Error('Failed to find comparator with type ' + mimeType + ': ' + snapshotPath);
|
|
||||||
|
|
||||||
this.testInfo = testInfo;
|
this.testInfo = testInfo;
|
||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
this.actualPath = actualPath;
|
this.actualPath = actualPath;
|
||||||
|
|
@ -215,14 +213,11 @@ export function toMatchSnapshot(
|
||||||
testInfo, determineFileExtension(received),
|
testInfo, determineFileExtension(received),
|
||||||
testInfo.project.expect?.toMatchSnapshot || {},
|
testInfo.project.expect?.toMatchSnapshot || {},
|
||||||
nameOrOptions, optOptions);
|
nameOrOptions, optOptions);
|
||||||
const comparator: Comparator = mimeTypeToComparator[helper.mimeType];
|
|
||||||
if (!comparator)
|
|
||||||
throw new Error('Failed to find comparator with type ' + helper.mimeType + ': ' + helper.snapshotPath);
|
|
||||||
|
|
||||||
if (this.isNot) {
|
if (this.isNot) {
|
||||||
if (!fs.existsSync(helper.snapshotPath))
|
if (!fs.existsSync(helper.snapshotPath))
|
||||||
return helper.handleMissingNegated();
|
return helper.handleMissingNegated();
|
||||||
const isDifferent = !!comparator(received, fs.readFileSync(helper.snapshotPath), helper.comparatorOptions);
|
const isDifferent = !!helper.comparator(received, fs.readFileSync(helper.snapshotPath), helper.comparatorOptions);
|
||||||
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
|
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,7 +225,7 @@ export function toMatchSnapshot(
|
||||||
return helper.handleMissing(received);
|
return helper.handleMissing(received);
|
||||||
|
|
||||||
const expected = fs.readFileSync(helper.snapshotPath);
|
const expected = fs.readFileSync(helper.snapshotPath);
|
||||||
const result = comparator(received, expected, helper.comparatorOptions);
|
const result = helper.comparator(received, expected, helper.comparatorOptions);
|
||||||
if (!result)
|
if (!result)
|
||||||
return helper.handleMatching();
|
return helper.handleMatching();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,22 @@ test('should support golden', async ({ runInlineTest }) => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with non-txt extensions', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
...files,
|
||||||
|
'a.spec.js-snapshots/snapshot.csv': `1,2,3`,
|
||||||
|
'a.spec.js': `
|
||||||
|
const { test } = require('./helper');
|
||||||
|
test('is a test', ({}) => {
|
||||||
|
expect('1,2,4').toMatchSnapshot('snapshot.csv');
|
||||||
|
});
|
||||||
|
`
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(stripAnsi(result.output)).toContain(`1,2,34`);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
test('should generate default name', async ({ runInlineTest }, testInfo) => {
|
test('should generate default name', async ({ runInlineTest }, testInfo) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
...files,
|
...files,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue