diff --git a/packages/playwright-core/src/server/trace/recorder/tracing.ts b/packages/playwright-core/src/server/trace/recorder/tracing.ts index 7e7bdab6f0fc0..38e2193e08fc3 100644 --- a/packages/playwright-core/src/server/trace/recorder/tracing.ts +++ b/packages/playwright-core/src/server/trace/recorder/tracing.ts @@ -261,8 +261,12 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps return {}; // Network file survives across chunks, make a snapshot before returning the resulting entries. - const suffix = state.chunkOrdinal ? `-${state.chunkOrdinal}` : ``; - const networkFile = path.join(state.tracesDir, state.traceName + `${suffix}.network`); + // We should pick a name starting with "traceName" and ending with .network. + // Something like someSuffixHere.network. + // However, this name must not clash with any other "traceName".network in the same tracesDir. + // We can use -.network, but "-pwnetcopy-0" suffix is more readable + // and makes it easier to debug future issues. + const networkFile = path.join(state.tracesDir, state.traceName + `-pwnetcopy-${state.chunkOrdinal}.network`); await fs.promises.copyFile(state.networkFile, networkFile); const entries: NameValue[] = []; diff --git a/tests/playwright-test/playwright.trace.spec.ts b/tests/playwright-test/playwright.trace.spec.ts index b5412353e82d1..f3fdfa570d091 100644 --- a/tests/playwright-test/playwright.trace.spec.ts +++ b/tests/playwright-test/playwright.trace.spec.ts @@ -132,6 +132,42 @@ test('should not throw with trace: on-first-retry and two retries in the same wo expect(result.flaky).toBe(6); }); +test('should not mixup network files between contexts', async ({ runInlineTest, server }, testInfo) => { + // NOTE: this test reproduces the issue 10% of the time. Running with --repeat-each=20 helps. + test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22089' }); + + const result = await runInlineTest({ + 'playwright.config.ts': ` + export default { use: { trace: 'on' } }; + `, + 'a.spec.ts': ` + import { test, expect } from '@playwright/test'; + + let page1, page2; + + test.beforeAll(async ({ browser }) => { + page1 = await browser.newPage(); + await page1.goto("${server.EMPTY_PAGE}"); + + page2 = await browser.newPage(); + await page2.goto("${server.EMPTY_PAGE}"); + }); + + test.afterAll(async () => { + await page1.close(); + await page2.close(); + }); + + test('example', async ({ page }) => { + await page.goto("${server.EMPTY_PAGE}"); + }); + `, + }, { workers: 1, timeout: 15000 }); + expect(result.exitCode).toEqual(0); + expect(result.passed).toBe(1); + expect(fs.existsSync(testInfo.outputPath('test-results', 'a-example', 'trace.zip'))).toBe(true); +}); + test('should save sources when requested', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ 'playwright.config.ts': ` diff --git a/tests/playwright-test/ui-mode-test-run.spec.ts b/tests/playwright-test/ui-mode-test-run.spec.ts index 59221c6bd24f4..1982bd6e34410 100644 --- a/tests/playwright-test/ui-mode-test-run.spec.ts +++ b/tests/playwright-test/ui-mode-test-run.spec.ts @@ -228,7 +228,7 @@ test('should stop', async ({ runUITest }) => { `, }); - await expect(page.getByTitle('Run all')).toBeEnabled(); + await expect(page.getByTitle('Run all')).toBeEnabled({ timeout: 15000 }); await expect(page.getByTitle('Stop')).toBeDisabled(); await page.getByTitle('Run all').click();