chore: keep backwards compat with old extension

This commit is contained in:
Simon Knott 2025-02-26 10:11:25 +01:00
parent b8b68cdad1
commit 589c8041b5
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 39 additions and 3 deletions

View file

@ -22,7 +22,7 @@ import { escapeTemplateString, isString, sanitizeForFilePath } from 'playwright-
import { kNoElementsFoundError, matcherHint } from './matcherHint';
import { EXPECTED_COLOR } from '../common/expectBundle';
import { callLogText, sanitizeFilePathBeforeExtension, trimLongString } from '../util';
import { callLogText, fileExistsAsync, sanitizeFilePathBeforeExtension, trimLongString } from '../util';
import { printReceivedStringContainExpectedSubstring } from './expect';
import { currentTestInfo } from '../common/globals';
@ -79,6 +79,13 @@ export async function toMatchAriaSnapshot(
}
const fullTitleWithoutSpec = [...testInfo.titlePath.slice(1), ++snapshotNames.anonymousSnapshotIndex].join(' ');
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.snapshot.yml']);
// in 1.51, we changed the default template to use .snapshot.yml extension
// for backwards compatibility, we check for the legacy .yml extension
if (!(await fileExistsAsync(expectedPath))) {
const legacyPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.yml']);
if (await fileExistsAsync(legacyPath))
expectedPath = legacyPath;
}
}
expected = await fs.promises.readFile(expectedPath, 'utf8').catch(() => '');
timeout = expectedParam?.timeout ?? this.timeout;

View file

@ -203,9 +203,10 @@ export function trimLongString(s: string, length = 100) {
function findNthFromEnd(string: string, searchString: string, n: number) {
let i = string.length;
while (n--) {
i = string.lastIndexOf(searchString, i - 1);
if (i === -1)
const pos = string.lastIndexOf(searchString, i - 1);
if (pos === -1)
break;
i = pos;
}
return i;
}
@ -219,6 +220,7 @@ function multiExtname(filePath: string, maximum = 2): string {
export function parsePathMultiExt(filePath: string, maximum = 2) {
const startOfExtension = findNthFromEnd(filePath, '.', maximum);
const result = path.parse(filePath.substring(0, startOfExtension) + '.ext');
result.base = filePath.substring(0, startOfExtension);
result.ext = filePath.substring(startOfExtension);
return result;
}
@ -414,6 +416,15 @@ function fileExists(resolved: string) {
return fs.statSync(resolved, { throwIfNoEntry: false })?.isFile();
}
export async function fileExistsAsync(resolved: string) {
try {
const stat = await fs.promises.stat(resolved);
return stat.isFile();
} catch {
return false;
}
}
function dirExists(resolved: string) {
return fs.statSync(resolved, { throwIfNoEntry: false })?.isDirectory();
}

View file

@ -130,6 +130,24 @@ test('should generate snapshot name', async ({ runInlineTest }, testInfo) => {
expect(snapshot2).toBe('- heading "hello world 2" [level=1]');
});
test('backwads compat with .yml extension', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.spec.ts-snapshots/test-1.yml': `
- heading "hello old world"
`,
'a.spec.ts': `
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await page.setContent(\`<h1>hello new world</h1>\`);
await expect(page.locator('body')).toMatchAriaSnapshot();
});
`
}, { 'update-snapshots': 'changed' });
expect(result.exitCode).toBe(0);
expect(result.output).toContain(`A snapshot is generated at a.spec.ts-snapshots${path.sep}test-1.yml.`);
});
for (const updateSnapshots of ['all', 'changed', 'missing', 'none']) {
test(`should update snapshot with the update-snapshots=${updateSnapshots} (config)`, async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({