From 714235d6c842ba53056dfd119152ff5f99230391 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 25 Apr 2024 13:34:00 -0700 Subject: [PATCH] fix(merge): include command hash into the report name (#30528) Reference https://github.com/microsoft/playwright/issues/30091 --- packages/playwright/src/reporters/blob.ts | 5 +++- packages/playwright/src/runner/reporters.ts | 19 ++++++++++++ tests/playwright-test/reporter-blob.spec.ts | 32 +++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/packages/playwright/src/reporters/blob.ts b/packages/playwright/src/reporters/blob.ts index 20135cb5f3..3d2f498627 100644 --- a/packages/playwright/src/reporters/blob.ts +++ b/packages/playwright/src/reporters/blob.ts @@ -16,7 +16,7 @@ import fs from 'fs'; import path from 'path'; -import { ManualPromise, calculateSha1, createGuid, getUserAgent, removeFolders } from 'playwright-core/lib/utils'; +import { ManualPromise, calculateSha1, createGuid, getUserAgent, removeFolders, sanitizeForFilePath } from 'playwright-core/lib/utils'; import { mime } from 'playwright-core/lib/utilsBundle'; import { Readable } from 'stream'; import type { EventEmitter } from 'events'; @@ -30,6 +30,7 @@ type BlobReporterOptions = { configDir: string; outputDir?: string; fileName?: string; + _commandHash: string; }; export const currentBlobReportVersion = 2; @@ -114,6 +115,8 @@ export class BlobReporter extends TeleReporterEmitter { if (process.env.PLAYWRIGHT_BLOB_FILE_NAME) return process.env.PLAYWRIGHT_BLOB_FILE_NAME; let reportName = 'report'; + if (this._options._commandHash) + reportName += '-' + sanitizeForFilePath(this._options._commandHash); if (config.shard) { const paddedNumber = `${config.shard.current}`.padStart(`${config.shard.total}`.length, '0'); reportName = `${reportName}-${paddedNumber}`; diff --git a/packages/playwright/src/runner/reporters.ts b/packages/playwright/src/runner/reporters.ts index 084aed2912..cbad53e892 100644 --- a/packages/playwright/src/runner/reporters.ts +++ b/packages/playwright/src/runner/reporters.ts @@ -32,6 +32,7 @@ import { loadReporter } from './loadUtils'; import { BlobReporter } from '../reporters/blob'; import type { ReporterDescription } from '../../types/test'; import { type ReporterV2, wrapReporterAsV2 } from '../reporters/reporterV2'; +import { calculateSha1 } from 'playwright-core/lib/utils'; export async function createReporters(config: FullConfigInternal, mode: 'list' | 'test' | 'merge', isTestServer: boolean, descriptions?: ReporterDescription[]): Promise { const defaultReporters: { [key in BuiltInReporter]: new(arg: any) => ReporterV2 } = { @@ -90,9 +91,27 @@ function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'me configDir: config.configDir, _mode: mode, _isTestServer: isTestServer, + _commandHash: computeCommandHash(config), }; } +function computeCommandHash(config: FullConfigInternal) { + const parts = []; + // Include project names for readability. + if (config.cliProjectFilter) + parts.push(...config.cliProjectFilter); + const command = {} as any; + if (config.cliArgs.length) + command.cliArgs = config.cliArgs; + if (config.cliGrep) + command.cliGrep = config.cliGrep; + if (config.cliGrepInvert) + command.cliGrepInvert = config.cliGrepInvert; + if (Object.keys(command).length) + parts.push(calculateSha1(JSON.stringify(command)).substring(0, 7)); + return parts.join('-'); +} + class ListModeReporter extends EmptyReporter { private config!: FullConfig; diff --git a/tests/playwright-test/reporter-blob.spec.ts b/tests/playwright-test/reporter-blob.spec.ts index c940a6f0d6..2c733de3cd 100644 --- a/tests/playwright-test/reporter-blob.spec.ts +++ b/tests/playwright-test/reporter-blob.spec.ts @@ -1826,3 +1826,35 @@ test('preserve static annotations when tests did not run', async ({ runInlineTes await page.goBack(); } }); + +test('project filter in report name', async ({ runInlineTest }) => { + const files = { + 'playwright.config.ts': ` + module.exports = { + reporter: 'blob', + projects: [ + { name: 'foo' }, + { name: 'b%/\\ar' }, + { name: 'baz' }, + ] + }; + `, + 'a.test.js': ` + import { test, expect } from '@playwright/test'; + test('math 1 @smoke', async ({}) => {}); + `, + }; + + const reportDir = test.info().outputPath('blob-report'); + + { + await runInlineTest(files, { shard: `2/2`, project: 'foo' }); + const reportFiles = await fs.promises.readdir(reportDir); + expect(reportFiles.sort()).toEqual(['report-foo-2.zip']); + } + { + await runInlineTest(files, { shard: `1/2`, project: 'foo,b*r', grep: 'smoke' }); + const reportFiles = await fs.promises.readdir(reportDir); + expect(reportFiles.sort()).toEqual(['report-foo-b-r-6d9d49e-1.zip']); + } +}); \ No newline at end of file