chore: trim file names longer than 60 chars (was 100) (#29725)

Test-specific output dir and snapshot names are trimmed to 60 chars
instead of just 100. The snapshot names are still trimmed at 100 chars
for backwards compatibility.


Reference https://github.com/microsoft/playwright/issues/29719
This commit is contained in:
Yury Semikhatsky 2024-03-18 12:53:15 -07:00 committed by GitHub
parent ef4438ee99
commit 35db70ea1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 20 additions and 17 deletions

View File

@ -23,7 +23,8 @@ import {
addSuffixToFilePath,
trimLongString, callLogText,
expectTypes,
sanitizeFilePathBeforeExtension } from '../util';
sanitizeFilePathBeforeExtension,
windowsFilesystemFriendlyLength } from '../util';
import { colors } from 'playwright-core/lib/utilsBundle';
import fs from 'fs';
import path from 'path';
@ -74,7 +75,7 @@ const NonConfigProperties: (keyof ToHaveScreenshotOptions)[] = [
class SnapshotHelper {
readonly testInfo: TestInfoImpl;
readonly snapshotName: string;
readonly outputBaseName: string;
readonly legacyExpectedPath: string;
readonly previousPath: string;
readonly snapshotPath: string;
@ -128,9 +129,9 @@ class SnapshotHelper {
...testInfo.titlePath.slice(1),
++snapshotNames.anonymousSnapshotIndex,
].join(' ');
name = sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.' + anonymousSnapshotExtension;
inputPathSegments = [name];
this.snapshotName = name;
inputPathSegments = [sanitizeForFilePath(trimLongString(fullTitleWithoutSpec)) + '.' + anonymousSnapshotExtension];
// Trim the output file paths more aggresively to avoid hitting Windows filesystem limits.
this.outputBaseName = sanitizeForFilePath(trimLongString(fullTitleWithoutSpec, windowsFilesystemFriendlyLength)) + '.' + anonymousSnapshotExtension;
} else {
// We intentionally do not sanitize user-provided array of segments, but for backwards
// compatibility we do sanitize the name if it is a single string.
@ -140,13 +141,13 @@ class SnapshotHelper {
snapshotNames.namedSnapshotIndex[joinedName] = (snapshotNames.namedSnapshotIndex[joinedName] || 0) + 1;
const index = snapshotNames.namedSnapshotIndex[joinedName];
if (index > 1)
this.snapshotName = addSuffixToFilePath(joinedName, `-${index - 1}`);
this.outputBaseName = addSuffixToFilePath(joinedName, `-${index - 1}`);
else
this.snapshotName = joinedName;
this.outputBaseName = joinedName;
}
this.snapshotPath = testInfo.snapshotPath(...inputPathSegments);
this.legacyExpectedPath = addSuffixToFilePath(testInfo._getOutputPath(...inputPathSegments), '-expected');
const outputFile = testInfo._getOutputPath(sanitizeFilePathBeforeExtension(this.snapshotName));
const outputFile = testInfo._getOutputPath(sanitizeFilePathBeforeExtension(this.outputBaseName));
this.legacyExpectedPath = addSuffixToFilePath(outputFile, '-expected');
this.previousPath = addSuffixToFilePath(outputFile, '-previous');
this.actualPath = addSuffixToFilePath(outputFile, '-actual');
this.diffPath = addSuffixToFilePath(outputFile, '-diff');
@ -222,7 +223,7 @@ class SnapshotHelper {
if (isWriteMissingMode) {
writeFileSync(this.snapshotPath, actual);
writeFileSync(this.actualPath, actual);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-actual'), contentType: this.mimeType, path: this.actualPath });
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.outputBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
}
const message = `A snapshot doesn't exist at ${this.snapshotPath}${isWriteMissingMode ? ', writing actual.' : '.'}`;
if (this.updateSnapshots === 'all') {
@ -256,22 +257,22 @@ class SnapshotHelper {
// Copy the expectation inside the `test-results/` folder for backwards compatibility,
// so that one can upload `test-results/` directory and have all the data inside.
writeFileSync(this.legacyExpectedPath, expected);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-expected'), contentType: this.mimeType, path: this.snapshotPath });
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.outputBaseName, '-expected'), contentType: this.mimeType, path: this.snapshotPath });
output.push(`\nExpected: ${colors.yellow(this.snapshotPath)}`);
}
if (previous !== undefined) {
writeFileSync(this.previousPath, previous);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-previous'), contentType: this.mimeType, path: this.previousPath });
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.outputBaseName, '-previous'), contentType: this.mimeType, path: this.previousPath });
output.push(`Previous: ${colors.yellow(this.previousPath)}`);
}
if (actual !== undefined) {
writeFileSync(this.actualPath, actual);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-actual'), contentType: this.mimeType, path: this.actualPath });
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.outputBaseName, '-actual'), contentType: this.mimeType, path: this.actualPath });
output.push(`Received: ${colors.yellow(this.actualPath)}`);
}
if (diff !== undefined) {
writeFileSync(this.diffPath, diff);
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.snapshotName, '-diff'), contentType: this.mimeType, path: this.diffPath });
this.testInfo.attachments.push({ name: addSuffixToFilePath(this.outputBaseName, '-diff'), contentType: this.mimeType, path: this.diffPath });
output.push(` Diff: ${colors.yellow(this.diffPath)}`);
}

View File

@ -185,6 +185,8 @@ export function expectTypes(receiver: any, types: string[], matcherName: string)
}
}
export const windowsFilesystemFriendlyLength = 60;
export function trimLongString(s: string, length = 100) {
if (s.length <= length)
return s;

View File

@ -24,7 +24,7 @@ import { TimeoutManager, TimeoutManagerError, kMaxDeadline } from './timeoutMana
import type { RunnableDescription } from './timeoutManager';
import type { Annotation, FullConfigInternal, FullProjectInternal } from '../common/config';
import type { Location } from '../../types/testReporter';
import { debugTest, filteredStackTrace, formatLocation, getContainedPath, normalizeAndSaveAttachment, serializeError, trimLongString } from '../util';
import { debugTest, filteredStackTrace, formatLocation, getContainedPath, normalizeAndSaveAttachment, serializeError, trimLongString, windowsFilesystemFriendlyLength } from '../util';
import { TestTracing } from './testTracing';
import type { Attachment } from './testTracing';
import type { StackFrame } from '@protocol/channels';
@ -175,7 +175,7 @@ export class TestInfoImpl implements TestInfo {
const sanitizedRelativePath = relativeTestFilePath.replace(process.platform === 'win32' ? new RegExp('\\\\', 'g') : new RegExp('/', 'g'), '-');
const fullTitleWithoutSpec = this.titlePath.slice(1).join(' ');
let testOutputDir = trimLongString(sanitizedRelativePath + '-' + sanitizeForFilePath(fullTitleWithoutSpec));
let testOutputDir = trimLongString(sanitizedRelativePath + '-' + sanitizeForFilePath(fullTitleWithoutSpec), windowsFilesystemFriendlyLength);
if (projectInternal.id)
testOutputDir += '-' + sanitizeForFilePath(projectInternal.id);
if (this.retry)

View File

@ -413,7 +413,7 @@ test('should allow shorten long output dirs characters in the output dir', async
`,
});
const outputDir = result.outputLines[0];
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'very-deep-and-long-file-name-that-i-want-to-be-99202--keeps-going-and-going-and-we-should-shorten-it'));
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'very-deep-and-long-file-na-99202-ng-and-we-should-shorten-it'));
});
test('should not mangle double dashes', async ({ runInlineTest }, testInfo) => {