diff --git a/packages/playwright/src/isomorphic/teleReceiver.ts b/packages/playwright/src/isomorphic/teleReceiver.ts index c5d82d810d..a14523da1a 100644 --- a/packages/playwright/src/isomorphic/teleReceiver.ts +++ b/packages/playwright/src/isomorphic/teleReceiver.ts @@ -209,8 +209,8 @@ export class TeleReporterReceiver { this._rootSuite.suites.push(projectSuite); projectSuite.parent = this._rootSuite; } - const p = this._parseProject(project); - projectSuite.project = () => p; + // Always update project in watch mode. + projectSuite._project = this._parseProject(project); this._mergeSuitesInto(project.suites, projectSuite); // Remove deleted tests when listing. Empty suites will be auto-filtered @@ -428,6 +428,7 @@ export class TeleSuite implements SuitePrivate { _timeout: number | undefined; _retries: number | undefined; _fileId: string | undefined; + _project: TeleFullProject | undefined; _parallelMode: 'none' | 'default' | 'serial' | 'parallel' = 'none'; readonly _type: 'root' | 'project' | 'file' | 'describe'; @@ -459,7 +460,7 @@ export class TeleSuite implements SuitePrivate { } project(): TeleFullProject | undefined { - return undefined; + return this._project ?? this.parent?.project(); } } diff --git a/tests/playwright-test/reporter-blob.spec.ts b/tests/playwright-test/reporter-blob.spec.ts index 63b6fd815b..1bbc3e2a26 100644 --- a/tests/playwright-test/reporter-blob.spec.ts +++ b/tests/playwright-test/reporter-blob.spec.ts @@ -1677,3 +1677,35 @@ test('merge reports without --config preserves path separators', async ({ runInl expect(output).toContain(`test: ${test.info().outputPath('dir1', 'tests2', 'b.test.js').replaceAll(path.sep, otherSeparator)}`); expect(output).toContain(`test title: ${'tests2' + otherSeparator + 'b.test.js'}`); }); + +test('TestSuite.project() should return owning project', async ({ runInlineTest, mergeReports }) => { + test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29173' }); + const files1 = { + 'echo-reporter.js': ` + export default class EchoReporter { + onTestBegin(test) { + console.log('test project:', test.parent?.project()?.name); + } + }; + `, + 'merge.config.ts': `module.exports = { + testDir: 'mergeRoot', + reporter: './echo-reporter.js' + };`, + 'playwright.config.ts': `module.exports = { + testDir: 'tests', + reporter: [['blob', { outputDir: 'blob-report' }]], + projects: [{name: 'my-project'}] + };`, + 'tests/a.test.js': ` + import { test, expect } from '@playwright/test'; + test('math 1', async ({}) => { }); + `, + }; + await runInlineTest(files1); + + const { exitCode, output } = await mergeReports(test.info().outputPath('blob-report'), undefined, { additionalArgs: ['--config', 'merge.config.ts'] }); + expect(exitCode).toBe(0); + console.log(output); + expect(output).toContain(`test project: my-project`); +});