diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index ae3928ffdd..fbca27cd23 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -173,6 +173,7 @@ export abstract class BrowserContext extends SdkObject { async resetForReuse(metadata: CallMetadata, params: channels.BrowserNewContextForReuseParams | null) { this.setDefaultNavigationTimeout(undefined); this.setDefaultTimeout(undefined); + this.tracing.resetForReuse(); if (params) { for (const key of paramsThatAllowContextReuse) diff --git a/packages/playwright-core/src/server/trace/recorder/snapshotter.ts b/packages/playwright-core/src/server/trace/recorder/snapshotter.ts index 452166ae31..f99133699f 100644 --- a/packages/playwright-core/src/server/trace/recorder/snapshotter.ts +++ b/packages/playwright-core/src/server/trace/recorder/snapshotter.ts @@ -74,6 +74,11 @@ export class Snapshotter { this._started = false; } + resetForReuse() { + // Next time we start recording, we will call addInitScript again. + this._initialized = false; + } + async _initialize() { for (const page of this._context.pages()) this._onPage(page); diff --git a/packages/playwright-core/src/server/trace/recorder/tracing.ts b/packages/playwright-core/src/server/trace/recorder/tracing.ts index 6b4bad5339..23e7b046e5 100644 --- a/packages/playwright-core/src/server/trace/recorder/tracing.ts +++ b/packages/playwright-core/src/server/trace/recorder/tracing.ts @@ -110,6 +110,10 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps } } + resetForReuse() { + this._snapshotter?.resetForReuse(); + } + async start(options: TracerOptions) { if (this._isStopping) throw new Error('Cannot start tracing while stopping'); diff --git a/tests/playwright-test/playwright.reuse.spec.ts b/tests/playwright-test/playwright.reuse.spec.ts index 896a6ce439..3b061f4544 100644 --- a/tests/playwright-test/playwright.reuse.spec.ts +++ b/tests/playwright-test/playwright.reuse.spec.ts @@ -15,6 +15,7 @@ */ import { test, expect } from './playwright-test-fixtures'; +import { parseTrace } from '../config/utils'; import fs from 'fs'; test('should reuse context', async ({ runInlineTest }) => { @@ -430,3 +431,44 @@ test('should cancel pending operations upon reuse', async ({ runInlineTest }) => expect(result.exitCode).toBe(0); expect(result.passed).toBe(2); }); + +test('should reset tracing', async ({ runInlineTest }, testInfo) => { + const traceFile1 = testInfo.outputPath('trace1.zip'); + const traceFile2 = testInfo.outputPath('trace2.zip'); + const result = await runInlineTest({ + 'reuse.spec.ts': ` + const { test } = pwt; + test('one', async ({ page }) => { + await page.context().tracing.start({ snapshots: true }); + await page.setContent(''); + await page.click('button'); + await page.context().tracing.stopChunk({ path: ${JSON.stringify(traceFile1)} }); + }); + test('two', async ({ page }) => { + await page.context().tracing.start({ snapshots: true }); + await page.setContent(''); + await page.fill('input', 'value'); + await page.locator('input').click(); + await page.context().tracing.stopChunk({ path: ${JSON.stringify(traceFile2)} }); + }); + `, + }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); + + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(2); + + const trace1 = await parseTrace(traceFile1); + expect(trace1.actions).toEqual([ + 'page.setContent', + 'page.click', + ]); + expect(trace1.events.some(e => e.type === 'frame-snapshot')).toBe(true); + + const trace2 = await parseTrace(traceFile2); + expect(trace2.actions).toEqual([ + 'page.setContent', + 'page.fill', + 'locator.click', + ]); + expect(trace2.events.some(e => e.type === 'frame-snapshot')).toBe(true); +});