Repository navigation
Description
Version
Playwright / playwright-core 1.64.0, Node 26.5.0, macOS arm64.
Chromium headless shell 156.0.8078.4, Playwright build 1248.
Summary
Starting a second programmatic recording while the shared Recorder has a pending click delivers that pre-start click to the new recording.
This reproduces with a real Chromium browser and two Playwright connections sharing the same context. It uses internal recording APIs without modifying Playwright or injecting actions into the signal processor.
Reproduction
Two Playwright connections share one browser context using _sharedBrowser: true:
await contextA._startRecording({ language: 'javascript' }, onA);
await page.getByRole('button', { name: 'Before start', exact: true }).click();
await contextB._startRecording({ language: 'javascript' }, onB);
await contextA._stopRecording();The click completes before B starts, but its recorder event is still buffered. Stopping A flushes it to both recordings.
Expected
B should receive actions captured after B's recording begins. A should retain its earlier click.
This follows the intent described in #42627, including its test comment that the second client only sees what happened after it started recording. If the intended boundary is event delivery rather than capture, please clarify that contract.
Observed
The browser reproduction fails the expected boundary assertion in 5/5 attempts. All five controls pass.
A receives its earlier click in both cases. In the control, B receives only the fresh post-start click. When B starts before the earlier click is flushed, B receives both clicks, including:
await page.getByRole('button', { name: 'Before start' }).click();That action is delivered to B as actionAdded, even though the click completed before B's _startRecording() call.
Source investigation
RecorderSignalProcessorbuffers left clicks and navigation for 500 ms.ProgrammaticRecorderApp.start()subscribes the new app to the shared recorder without first flushing pending actions. If the recorder is already in recording mode,setMode()returns without creating a boundary.- A later flush delivers the earlier action to both apps.
As a diagnostic only, flushing before constructing the new app in an in-memory bundle copy makes all ten browser scenarios pass. A retains its earlier click and B receives fresh clicks normally. This has not been evaluated as a complete fix.
This is narrower than the old per-client sink issue #42608, which #42627 already fixed.
Activity