add special case for ext

This commit is contained in:
Simon Knott 2025-02-26 14:53:59 +01:00
parent 9f80c3c3e9
commit 106c8cef01
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
3 changed files with 13 additions and 36 deletions

View file

@ -70,7 +70,8 @@ export async function toMatchAriaSnapshot(
timeout = options.timeout ?? this.timeout;
} else {
if (expectedParam?.name) {
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeFilePathBeforeExtension(expectedParam.name)]);
const ext = expectedParam.name!.endsWith('.snapshot.yml') ? '.snapshot.yml' : undefined;
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeFilePathBeforeExtension(expectedParam.name, ext)]);
} else {
let snapshotNames = (testInfo as any)[snapshotNamesSymbol] as SnapshotNames;
if (!snapshotNames) {
@ -78,11 +79,11 @@ export async function toMatchAriaSnapshot(
(testInfo as any)[snapshotNamesSymbol] = snapshotNames;
}
const fullTitleWithoutSpec = [...testInfo.titlePath.slice(1), ++snapshotNames.anonymousSnapshotIndex].join(' ');
expectedPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.snapshot.yml']);
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']);
const legacyPath = testInfo._resolveSnapshotPath(pathTemplate, defaultTemplate, [sanitizeForFilePath(trimLongString(fullTitleWithoutSpec))], '.yml');
if (await fileExistsAsync(legacyPath))
expectedPath = legacyPath;
}

View file

@ -200,39 +200,13 @@ export function trimLongString(s: string, length = 100) {
return s.substring(0, start) + middle + s.slice(-end);
}
function findNthFromEnd(string: string, searchString: string, n: number) {
let i = string.length;
while (n--) {
const pos = string.lastIndexOf(searchString, i - 1);
if (pos === -1)
break;
i = pos;
}
return i;
}
function multiExtname(filePath: string, maximum = 2): string {
const basename = path.basename(filePath);
const startOfExtension = findNthFromEnd(basename, '.', maximum);
return basename.substring(startOfExtension);
}
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;
}
export function addSuffixToFilePath(filePath: string, suffix: string): string {
const ext = multiExtname(filePath);
const ext = path.extname(filePath);
const base = filePath.substring(0, filePath.length - ext.length);
return base + suffix + ext;
}
export function sanitizeFilePathBeforeExtension(filePath: string): string {
const ext = multiExtname(filePath);
export function sanitizeFilePathBeforeExtension(filePath: string, ext = path.extname(filePath)): string {
const base = filePath.substring(0, filePath.length - ext.length);
return sanitizeForFilePath(base) + ext;
}

View file

@ -20,7 +20,7 @@ import path from 'path';
import { captureRawStack, monotonicTime, sanitizeForFilePath, stringifyStackFrames, currentZone } from 'playwright-core/lib/utils';
import { TimeoutManager, TimeoutManagerError, kMaxDeadline } from './timeoutManager';
import { debugTest, filteredStackTrace, formatLocation, getContainedPath, normalizeAndSaveAttachment, trimLongString, windowsFilesystemFriendlyLength, parsePathMultiExt } from '../util';
import { debugTest, filteredStackTrace, formatLocation, getContainedPath, normalizeAndSaveAttachment, trimLongString, windowsFilesystemFriendlyLength } from '../util';
import { TestTracing } from './testTracing';
import { testInfoError } from './util';
import { FloatingPromiseScope } from './floatingPromiseScope';
@ -463,9 +463,11 @@ export class TestInfoImpl implements TestInfo {
return sanitizeForFilePath(trimLongString(fullTitleWithoutSpec));
}
_resolveSnapshotPath(template: string | undefined, defaultTemplate: string, pathSegments: string[]) {
_resolveSnapshotPath(template: string | undefined, defaultTemplate: string, pathSegments: string[], extension?: string) {
const subPath = path.join(...pathSegments);
const parsedSubPath = parsePathMultiExt(subPath);
const dir = path.dirname(subPath);
const ext = extension ?? path.extname(subPath);
const name = path.basename(subPath, ext);
const relativeTestFilePath = path.relative(this.project.testDir, this._requireFile);
const parsedRelativeTestFilePath = path.parse(relativeTestFilePath);
const projectNamePathSegment = sanitizeForFilePath(this.project.name);
@ -481,8 +483,8 @@ export class TestInfoImpl implements TestInfo {
.replace(/\{(.)?testName\}/g, '$1' + this._fsSanitizedTestName())
.replace(/\{(.)?testFileName\}/g, '$1' + parsedRelativeTestFilePath.base)
.replace(/\{(.)?testFilePath\}/g, '$1' + relativeTestFilePath)
.replace(/\{(.)?arg\}/g, '$1' + path.join(parsedSubPath.dir, parsedSubPath.name))
.replace(/\{(.)?ext\}/g, parsedSubPath.ext ? '$1' + parsedSubPath.ext : '');
.replace(/\{(.)?arg\}/g, '$1' + path.join(dir, name))
.replace(/\{(.)?ext\}/g, ext ? '$1' + ext : '');
return path.normalize(path.resolve(this._configInternal.configDir, snapshotPath));
}