diff --git a/packages/playwright-test/src/matchers/comparators.ts b/packages/playwright-test/src/matchers/comparators.ts new file mode 100644 index 0000000000..b234f7950e --- /dev/null +++ b/packages/playwright-test/src/matchers/comparators.ts @@ -0,0 +1,114 @@ +/** + * Copyright 2017 Google Inc. All rights reserved. + * Modifications copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import colors from 'colors/safe'; +import jpeg from 'jpeg-js'; +import pixelmatch from 'pixelmatch'; +import { diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL } from '../third_party/diff_match_patch'; +import BlinkDiff from '../third_party/blink-diff'; +import PNGImage from '../third_party/png-js'; + +// Note: we require the pngjs version of pixelmatch to avoid version mismatches. +const { PNG } = require(require.resolve('pngjs', { paths: [require.resolve('pixelmatch')] })) as typeof import('pngjs'); + +export type ImageComparatorOptions = { threshold?: number, pixelCount?: number, pixelRatio?: number }; +export type ComparatorResult = { diff?: Buffer; errorMessage?: string; } | null; +export type Comparator = (actualBuffer: Buffer | string, expectedBuffer: Buffer, options?: any) => ComparatorResult; +export const mimeTypeToComparator: { [key: string]: Comparator } = { + 'application/octet-string': compareBuffersOrStrings, + 'image/png': compareImages.bind(null, 'image/png'), + 'image/jpeg': compareImages.bind(null, 'image/jpeg'), + 'text/plain': compareText, +}; + +function compareBuffersOrStrings(actualBuffer: Buffer | string, expectedBuffer: Buffer): ComparatorResult { + if (typeof actualBuffer === 'string') + return compareText(actualBuffer, expectedBuffer); + if (!actualBuffer || !(actualBuffer instanceof Buffer)) + return { errorMessage: 'Actual result should be a Buffer or a string.' }; + if (Buffer.compare(actualBuffer, expectedBuffer)) + return { errorMessage: 'Buffers differ' }; + return null; +} + +function compareImages(mimeType: string, actualBuffer: Buffer | string, expectedBuffer: Buffer, options: ImageComparatorOptions = {}): ComparatorResult { + if (!actualBuffer || !(actualBuffer instanceof Buffer)) + return { errorMessage: 'Actual result should be a Buffer.' }; + + const actual = mimeType === 'image/png' ? PNG.sync.read(actualBuffer) : jpeg.decode(actualBuffer); + const expected = mimeType === 'image/png' ? PNG.sync.read(expectedBuffer) : jpeg.decode(expectedBuffer); + if (expected.width !== actual.width || expected.height !== actual.height) { + return { + errorMessage: `Sizes differ; expected image ${expected.width}px X ${expected.height}px, but got ${actual.width}px X ${actual.height}px. ` + }; + } + const diff = new PNG({ width: expected.width, height: expected.height }); + const thresholdOptions = { threshold: 0.2, ...options }; + if (process.env.PW_USE_BLINK_DIFF && mimeType === 'image/png') { + const diff = new BlinkDiff({ + imageA: new PNGImage(expected as any), + imageB: new PNGImage(actual as any), + }); + const result = diff.runSync(); + return result.code !== BlinkDiff.RESULT_IDENTICAL ? { diff: PNG.sync.write(diff._imageOutput.getImage()) } : null; + } + const count = pixelmatch(expected.data, actual.data, diff.data, expected.width, expected.height, thresholdOptions); + + const pixelCount1 = options.pixelCount; + const pixelCount2 = options.pixelRatio !== undefined ? expected.width * expected.height * options.pixelRatio : undefined; + let pixelCount; + if (pixelCount1 !== undefined && pixelCount2 !== undefined) + pixelCount = Math.min(pixelCount1, pixelCount2); + else + pixelCount = pixelCount1 ?? pixelCount2 ?? 0; + return count > pixelCount ? { diff: PNG.sync.write(diff) } : null; +} + +function compareText(actual: Buffer | string, expectedBuffer: Buffer): ComparatorResult { + if (typeof actual !== 'string') + return { errorMessage: 'Actual result should be a string' }; + const expected = expectedBuffer.toString('utf-8'); + if (expected === actual) + return null; + const dmp = new diff_match_patch(); + const d = dmp.diff_main(expected, actual); + dmp.diff_cleanupSemantic(d); + return { + errorMessage: diff_prettyTerminal(d) + }; +} + +function diff_prettyTerminal(diffs: diff_match_patch.Diff[]) { + const html = []; + for (let x = 0; x < diffs.length; x++) { + const op = diffs[x][0]; // Operation (insert, delete, equal) + const data = diffs[x][1]; // Text of change. + const text = data; + switch (op) { + case DIFF_INSERT: + html[x] = colors.green(text); + break; + case DIFF_DELETE: + html[x] = colors.reset(colors.strikethrough(colors.red(text))); + break; + case DIFF_EQUAL: + html[x] = text; + break; + } + } + return html.join(''); +} diff --git a/packages/playwright-test/src/matchers/golden.ts b/packages/playwright-test/src/matchers/golden.ts deleted file mode 100644 index 214c379c4d..0000000000 --- a/packages/playwright-test/src/matchers/golden.ts +++ /dev/null @@ -1,243 +0,0 @@ -/** - * Copyright 2017 Google Inc. All rights reserved. - * Modifications copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable no-console */ -import colors from 'colors/safe'; -import fs from 'fs'; -import path from 'path'; -import jpeg from 'jpeg-js'; -import pixelmatch from 'pixelmatch'; -import { diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL } from '../third_party/diff_match_patch'; -import { UpdateSnapshots } from '../types'; -import { addSuffixToFilePath, serializeError } from '../util'; -import BlinkDiff from '../third_party/blink-diff'; -import PNGImage from '../third_party/png-js'; -import { TestInfoImpl } from '../testInfo'; - -// Note: we require the pngjs version of pixelmatch to avoid version mismatches. -const { PNG } = require(require.resolve('pngjs', { paths: [require.resolve('pixelmatch')] })) as typeof import('pngjs'); - -const extensionToMimeType: { [key: string]: string } = { - 'dat': 'application/octet-string', - 'jpeg': 'image/jpeg', - 'jpg': 'image/jpeg', - 'png': 'image/png', - 'txt': 'text/plain', -}; - -type Comparator = (actualBuffer: Buffer | string, expectedBuffer: Buffer, mimeType: string, options?: any) => { diff?: Buffer; errorMessage?: string; } | null; -const GoldenComparators: { [key: string]: Comparator } = { - 'application/octet-string': compareBuffersOrStrings, - 'image/png': compareImages, - 'image/jpeg': compareImages, - 'text/plain': compareText, -}; - -function compareBuffersOrStrings(actualBuffer: Buffer | string, expectedBuffer: Buffer, mimeType: string): { diff?: Buffer; errorMessage?: string; } | null { - if (typeof actualBuffer === 'string') - return compareText(actualBuffer, expectedBuffer); - if (!actualBuffer || !(actualBuffer instanceof Buffer)) - return { errorMessage: 'Actual result should be a Buffer or a string.' }; - if (Buffer.compare(actualBuffer, expectedBuffer)) - return { errorMessage: 'Buffers differ' }; - return null; -} - -function compareImages(actualBuffer: Buffer | string, expectedBuffer: Buffer, mimeType: string, options: { threshold?: number, pixelCount?: number, pixelRatio?: number } = {}): { diff?: Buffer; errorMessage?: string; } | null { - if (!actualBuffer || !(actualBuffer instanceof Buffer)) - return { errorMessage: 'Actual result should be a Buffer.' }; - - const actual = mimeType === 'image/png' ? PNG.sync.read(actualBuffer) : jpeg.decode(actualBuffer); - const expected = mimeType === 'image/png' ? PNG.sync.read(expectedBuffer) : jpeg.decode(expectedBuffer); - if (expected.width !== actual.width || expected.height !== actual.height) { - return { - errorMessage: `Sizes differ; expected image ${expected.width}px X ${expected.height}px, but got ${actual.width}px X ${actual.height}px. ` - }; - } - const diff = new PNG({ width: expected.width, height: expected.height }); - const thresholdOptions = { threshold: 0.2, ...options }; - if (process.env.PW_USE_BLINK_DIFF && mimeType === 'image/png') { - const diff = new BlinkDiff({ - imageA: new PNGImage(expected as any), - imageB: new PNGImage(actual as any), - }); - const result = diff.runSync(); - return result.code !== BlinkDiff.RESULT_IDENTICAL ? { diff: PNG.sync.write(diff._imageOutput.getImage()) } : null; - } - const count = pixelmatch(expected.data, actual.data, diff.data, expected.width, expected.height, thresholdOptions); - - const pixelCount1 = options.pixelCount; - const pixelCount2 = options.pixelRatio !== undefined ? expected.width * expected.height * options.pixelRatio : undefined; - let pixelCount; - if (pixelCount1 !== undefined && pixelCount2 !== undefined) - pixelCount = Math.min(pixelCount1, pixelCount2); - else - pixelCount = pixelCount1 ?? pixelCount2 ?? 0; - return count > pixelCount ? { diff: PNG.sync.write(diff) } : null; -} - -function compareText(actual: Buffer | string, expectedBuffer: Buffer): { diff?: Buffer; errorMessage?: string; diffExtension?: string; } | null { - if (typeof actual !== 'string') - return { errorMessage: 'Actual result should be a string' }; - const expected = expectedBuffer.toString('utf-8'); - if (expected === actual) - return null; - const dmp = new diff_match_patch(); - const d = dmp.diff_main(expected, actual); - dmp.diff_cleanupSemantic(d); - return { - errorMessage: diff_prettyTerminal(d) - }; -} - -export function compare( - actual: Buffer | string, - pathSegments: string[], - testInfo: TestInfoImpl, - updateSnapshots: UpdateSnapshots, - withNegateComparison: boolean, - options?: { threshold?: number, pixelCount?: number, pixelRatio?: number } -): { pass: boolean; message?: string; expectedPath?: string, actualPath?: string, diffPath?: string, mimeType?: string } { - const snapshotFile = testInfo.snapshotPath(...pathSegments); - const outputFile = testInfo.outputPath(...pathSegments); - const expectedPath = addSuffixToFilePath(outputFile, '-expected'); - const actualPath = addSuffixToFilePath(outputFile, '-actual'); - const diffPath = addSuffixToFilePath(outputFile, '-diff'); - - if (!fs.existsSync(snapshotFile)) { - const isWriteMissingMode = updateSnapshots === 'all' || updateSnapshots === 'missing'; - const commonMissingSnapshotMessage = `${snapshotFile} is missing in snapshots`; - if (withNegateComparison) { - const message = `${commonMissingSnapshotMessage}${isWriteMissingMode ? ', matchers using ".not" won\'t write them automatically.' : '.'}`; - return { pass: true , message }; - } - if (isWriteMissingMode) { - fs.mkdirSync(path.dirname(snapshotFile), { recursive: true }); - fs.mkdirSync(path.dirname(actualPath), { recursive: true }); - fs.writeFileSync(snapshotFile, actual); - fs.writeFileSync(actualPath, actual); - } - const message = `${commonMissingSnapshotMessage}${isWriteMissingMode ? ', writing actual.' : '.'}`; - if (updateSnapshots === 'all') { - console.log(message); - return { pass: true, message }; - } - if (updateSnapshots === 'missing') { - testInfo._failWithError(serializeError(new Error(message)), false /* isHardError */); - return { pass: true }; - } - return { pass: false, message }; - } - - const expected = fs.readFileSync(snapshotFile); - const extension = path.extname(snapshotFile).substring(1); - const mimeType = extensionToMimeType[extension] || 'application/octet-string'; - const comparator = GoldenComparators[mimeType]; - if (!comparator) { - return { - pass: false, - message: 'Failed to find comparator with type ' + mimeType + ': ' + snapshotFile, - }; - } - - const result = comparator(actual, expected, mimeType, options); - if (!result) { - if (withNegateComparison) { - const message = [ - colors.red('Snapshot comparison failed:'), - '', - indent('Expected result should be different from the actual one.', ' '), - ].join('\n'); - return { - pass: true, - message, - }; - } - - return { pass: true }; - } - - if (withNegateComparison) { - return { - pass: false, - }; - } - - if (updateSnapshots === 'all') { - fs.mkdirSync(path.dirname(snapshotFile), { recursive: true }); - fs.writeFileSync(snapshotFile, actual); - console.log(snapshotFile + ' does not match, writing actual.'); - return { - pass: true, - message: snapshotFile + ' running with --update-snapshots, writing actual.' - }; - } - - fs.mkdirSync(path.dirname(expectedPath), { recursive: true }); - fs.mkdirSync(path.dirname(actualPath), { recursive: true }); - fs.writeFileSync(expectedPath, expected); - fs.writeFileSync(actualPath, actual); - if (result.diff) - fs.writeFileSync(diffPath, result.diff); - - const output = [ - colors.red(`Snapshot comparison failed:`), - ]; - if (result.errorMessage) { - output.push(''); - output.push(indent(result.errorMessage, ' ')); - } - output.push(''); - output.push(`Expected: ${colors.yellow(expectedPath)}`); - output.push(`Received: ${colors.yellow(actualPath)}`); - if (result.diff) - output.push(` Diff: ${colors.yellow(diffPath)}`); - - return { - pass: false, - message: output.join('\n'), - expectedPath, - actualPath, - diffPath: result.diff ? diffPath : undefined, - mimeType - }; -} - -function indent(lines: string, tab: string) { - return lines.replace(/^(?=.+$)/gm, tab); -} - -function diff_prettyTerminal(diffs: diff_match_patch.Diff[]) { - const html = []; - for (let x = 0; x < diffs.length; x++) { - const op = diffs[x][0]; // Operation (insert, delete, equal) - const data = diffs[x][1]; // Text of change. - const text = data; - switch (op) { - case DIFF_INSERT: - html[x] = colors.green(text); - break; - case DIFF_DELETE: - html[x] = colors.reset(colors.strikethrough(colors.red(text))); - break; - case DIFF_EQUAL: - html[x] = text; - break; - } - } - return html.join(''); -} diff --git a/packages/playwright-test/src/matchers/toMatchSnapshot.ts b/packages/playwright-test/src/matchers/toMatchSnapshot.ts index 27493318d3..edf576e817 100644 --- a/packages/playwright-test/src/matchers/toMatchSnapshot.ts +++ b/packages/playwright-test/src/matchers/toMatchSnapshot.ts @@ -16,8 +16,14 @@ import type { Expect } from '../types'; import { currentTestInfo } from '../globals'; -import { compare } from './golden'; -import { addSuffixToFilePath, sanitizeForFilePath, trimLongString } from '../util'; +import { mimeTypeToComparator, ComparatorResult, ImageComparatorOptions } from './comparators'; +import { addSuffixToFilePath, serializeError, sanitizeForFilePath, trimLongString } from '../util'; +import { UpdateSnapshots } from '../types'; +import colors from 'colors/safe'; +import fs from 'fs'; +import path from 'path'; +import * as mime from 'mime'; +import { TestInfoImpl } from '../testInfo'; // from expect/build/types type SyncExpectationResult = { @@ -27,22 +33,30 @@ type SyncExpectationResult = { type NameOrSegments = string | string[]; const SNAPSHOT_COUNTER = Symbol('noname-snapshot-counter'); -export function toMatchSnapshot(this: ReturnType, received: Buffer | string, nameOrOptions: NameOrSegments | { name: NameOrSegments, threshold?: number }, optOptions: { threshold?: number, pixelCount?: number, pixelRatio?: number } = {}): SyncExpectationResult { - let options: { name: NameOrSegments, threshold?: number, pixelCount?: number, pixelRatio?: number }; - const testInfo = currentTestInfo(); - if (!testInfo) - throw new Error(`toMatchSnapshot() must be called during the test`); - if (Array.isArray(nameOrOptions) || typeof nameOrOptions === 'string') - options = { name: nameOrOptions, ...optOptions }; - else + +function parseMatchSnapshotOptions( + testInfo: TestInfoImpl, + anonymousSnapshotExtension: string, + nameOrOptions: NameOrSegments | { name?: NameOrSegments } & ImageComparatorOptions, + optOptions: ImageComparatorOptions, +) { + let options: ImageComparatorOptions; + let name: NameOrSegments | undefined; + if (Array.isArray(nameOrOptions) || typeof nameOrOptions === 'string') { + name = nameOrOptions; + options = optOptions; + } else { + name = nameOrOptions.name; options = { ...nameOrOptions }; - if (!options.name) { + delete (options as any).name; + } + if (!name) { (testInfo as any)[SNAPSHOT_COUNTER] = ((testInfo as any)[SNAPSHOT_COUNTER] || 0) + 1; const fullTitleWithoutSpec = [ ...testInfo.titlePath.slice(1), (testInfo as any)[SNAPSHOT_COUNTER], ].join(' '); - options.name = sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + determineFileExtension(received); + name = sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.' + anonymousSnapshotExtension; } options = { @@ -57,38 +71,184 @@ export function toMatchSnapshot(this: ReturnType, received: throw new Error('`pixelRatio` option value must be between 0 and 1'); // sanitizes path if string - const pathSegments = Array.isArray(options.name) ? options.name : [addSuffixToFilePath(options.name, '', undefined, true)]; - const withNegateComparison = this.isNot; + const pathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, '', undefined, true)]; + const snapshotPath = testInfo.snapshotPath(...pathSegments); + const outputFile = testInfo.outputPath(...pathSegments); + const expectedPath = addSuffixToFilePath(outputFile, '-expected'); + const actualPath = addSuffixToFilePath(outputFile, '-actual'); + const diffPath = addSuffixToFilePath(outputFile, '-diff'); + let updateSnapshots = testInfo.config.updateSnapshots; if (updateSnapshots === 'missing' && testInfo.retry < testInfo.project.retries) updateSnapshots = 'none'; - const { pass, message, expectedPath, actualPath, diffPath, mimeType } = compare( - received, - pathSegments, - testInfo, - updateSnapshots, - withNegateComparison, - options - ); - const contentType = mimeType || 'application/octet-stream'; - if (expectedPath) - testInfo.attachments.push({ name: 'expected', contentType, path: expectedPath }); - if (actualPath) - testInfo.attachments.push({ name: 'actual', contentType, path: actualPath }); - if (diffPath) - testInfo.attachments.push({ name: 'diff', contentType, path: diffPath }); - return { pass, message: () => message || '' }; + const mimeType = mime.getType(path.basename(snapshotPath)) ?? 'application/octet-string'; + const comparator = mimeTypeToComparator[mimeType]; + if (!comparator) + throw new Error('Failed to find comparator with type ' + mimeType + ': ' + snapshotPath); + return { + snapshotPath, + hasSnapshotFile: fs.existsSync(snapshotPath), + expectedPath, + actualPath, + diffPath, + comparator, + mimeType, + updateSnapshots, + options, + }; } +export function toMatchSnapshot( + this: ReturnType, + received: Buffer | string, + nameOrOptions: NameOrSegments | { name?: NameOrSegments } & ImageComparatorOptions = {}, + optOptions: ImageComparatorOptions = {} +): SyncExpectationResult { + const testInfo = currentTestInfo(); + if (!testInfo) + throw new Error(`toMatchSnapshot() must be called during the test`); + const { + options, + updateSnapshots, + snapshotPath, + hasSnapshotFile, + expectedPath, + actualPath, + diffPath, + mimeType, + comparator, + } = parseMatchSnapshotOptions(testInfo, determineFileExtension(received), nameOrOptions, optOptions); + if (!hasSnapshotFile) + return commitMissingSnapshot(testInfo, received, snapshotPath, actualPath, updateSnapshots, this.isNot); + const expected = fs.readFileSync(snapshotPath); + const result = comparator(received, expected, options); + return commitComparatorResult( + testInfo, + expected, + received, + result, + mimeType, + snapshotPath, + expectedPath, + actualPath, + diffPath, + updateSnapshots, + this.isNot, + ); +} + +function commitMissingSnapshot( + testInfo: TestInfoImpl, + actual: Buffer | string, + snapshotPath: string, + actualPath: string, + updateSnapshots: UpdateSnapshots, + withNegateComparison: boolean, +) { + const isWriteMissingMode = updateSnapshots === 'all' || updateSnapshots === 'missing'; + const commonMissingSnapshotMessage = `${snapshotPath} is missing in snapshots`; + if (withNegateComparison) { + const message = `${commonMissingSnapshotMessage}${isWriteMissingMode ? ', matchers using ".not" won\'t write them automatically.' : '.'}`; + return { pass: true , message: () => message }; + } + if (isWriteMissingMode) { + writeFileSync(snapshotPath, actual); + writeFileSync(actualPath, actual); + } + const message = `${commonMissingSnapshotMessage}${isWriteMissingMode ? ', writing actual.' : '.'}`; + if (updateSnapshots === 'all') { + /* eslint-disable no-console */ + console.log(message); + return { pass: true, message: () => message }; + } + if (updateSnapshots === 'missing') { + testInfo._failWithError(serializeError(new Error(message)), false /* isHardError */); + return { pass: true, message: () => '' }; + } + return { pass: false, message: () => message }; +} + +function commitComparatorResult( + testInfo: TestInfoImpl, + expected: Buffer | string, + actual: Buffer | string, + result: ComparatorResult, + mimeType: string, + snapshotPath: string, + expectedPath: string, + actualPath: string, + diffPath: string, + updateSnapshots: UpdateSnapshots, + withNegateComparison: boolean, +) { + if (!result) { + const message = withNegateComparison ? [ + colors.red('Snapshot comparison failed:'), + '', + indent('Expected result should be different from the actual one.', ' '), + ].join('\n') : ''; + return { pass: true, message: () => message }; + } + + if (withNegateComparison) + return { pass: false, message: () => '' }; + + if (updateSnapshots === 'all') { + writeFileSync(snapshotPath, actual); + /* eslint-disable no-console */ + console.log(snapshotPath + ' does not match, writing actual.'); + return { + pass: true, + message: () => snapshotPath + ' running with --update-snapshots, writing actual.' + }; + } + + writeAttachment(testInfo, 'expected', mimeType, expectedPath, expected); + writeAttachment(testInfo, 'actual', mimeType, actualPath, actual); + if (result.diff) + writeAttachment(testInfo, 'diff', mimeType, diffPath, result.diff); + + const output = [ + colors.red(`Snapshot comparison failed:`), + ]; + if (result.errorMessage) { + output.push(''); + output.push(indent(result.errorMessage, ' ')); + } + output.push(''); + output.push(`Expected: ${colors.yellow(expectedPath)}`); + output.push(`Received: ${colors.yellow(actualPath)}`); + if (result.diff) + output.push(` Diff: ${colors.yellow(diffPath)}`); + + return { + pass: false, + message: () => output.join('\n'), + }; +} + +function writeFileSync(aPath: string, content: Buffer | string) { + fs.mkdirSync(path.dirname(aPath), { recursive: true }); + fs.writeFileSync(aPath, content); +} + +function writeAttachment(testInfo: TestInfoImpl, name: string, contentType: string, aPath: string, body: Buffer | string) { + writeFileSync(aPath, body); + testInfo.attachments.push({ name, contentType, path: aPath }); +} + +function indent(lines: string, tab: string) { + return lines.replace(/^(?=.+$)/gm, tab); +} function determineFileExtension(file: string | Buffer): string { if (typeof file === 'string') - return '.txt'; + return 'txt'; if (compareMagicBytes(file, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) - return '.png'; + return 'png'; if (compareMagicBytes(file, [0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01])) - return '.jpg'; - return '.bin'; + return 'jpg'; + return 'dat'; } function compareMagicBytes(file: Buffer, magicBytes: number[]): boolean { diff --git a/tests/playwright-test/golden.spec.ts b/tests/playwright-test/golden.spec.ts index 36ab8d640c..47e19dc3a6 100644 --- a/tests/playwright-test/golden.spec.ts +++ b/tests/playwright-test/golden.spec.ts @@ -65,12 +65,12 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => { expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test', 'is-a-test-2-actual.txt'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test', 'is-a-test-3-actual.png'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test', 'is-a-test-4-actual.jpg'))).toBe(true); - expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test', 'is-a-test-5-actual.bin'))).toBe(true); + expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test', 'is-a-test-5-actual.dat'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-1.txt'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-2.txt'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-3.png'))).toBe(true); expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-4.jpg'))).toBe(true); - expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-5.bin'))).toBe(true); + expect(fs.existsSync(testInfo.outputPath('a.spec.js-snapshots', 'is-a-test-5.dat'))).toBe(true); }); test('should compile with different option combinations', async ({ runTSC }) => {