-
recording.start()returns a handle and supports a manual clock: a manual clock keeps agent thinking time out of demo videos.state.video = await recording.start({ page: state.page, outputPath: '/abs/demo.mp4', clock: 'manual' }) await state.page.getByRole('button', { name: 'Open' }).click() await state.video.wait(800) // records the next 800ms await state.video.setPage(otherTab) // record another tab from now on await state.video.stop()
With
clock: 'manual'frames are written only insidewait(ms). The page keeps running normally, so the video has no idle time and needs nocreateDemoVideopass. Put each action and itswait()in the same execute call. The defaultclock: 'real'records wall-clock time like before. The librarystartRecording()also acceptsclock: 'manual'and haswait(ms)andsetPage(page).Breaking:
recording.stop({ page }),recording.isRecording({ page })andrecording.cancel({ page })are removed, and so are thestartRecording,stopRecording,isRecordingandcancelRecordingsandbox aliases. Use the handle:state.video = await recording.start({ page: state.page, outputPath }) await state.video.stop() // also: state.video.cancel(), state.video.isRecording
This also fixes
recording.stop()in a later execute call, which failed with "No active recording for this page" and left the recording running. -
Timed-out
executecode is aborted and cannot overlap the next call: on timeout the script's running Playwright action is cancelled (a pending click never fires later), its later calls throw, and a newsignalglobal (AbortSignal) is aborted. New execute calls always run at once. Passsignaltofetchor checksignal.abortedin long loops so they stop on timeout:for (const url of urls) { if (signal.aborted) break await fetch(url, { signal }) }
-
Idle headless sessions are deleted after 30 minutes: the shared headless Chrome now exits when its last session goes away, instead of running for days when agents forget
playwriter session delete. -
Headless mode keeps the Chromium sandbox on:
--browser headlesssessions now run sandboxed, so a page that exploits a Chrome bug stays inside the renderer sandbox. Linux as root (Docker) keeps the old behaviour, since Chromium cannot start sandboxed there. -
Recording no longer crashes NVIDIA NVENC encoders when the viewport changes: frames keep a fixed sample aspect ratio. Recording also starts faster: the first live frame is used without waiting for a slow screenshot.
-
Screenshots always restore the page UI: page screenshots and
screenshotWithAccessibilityLabelsrestore the hidden toolbar, scrollbars, caret and labels when capture fails. -
Skill docs no longer suggest
.first(),.last()or.nth()for strict mode violations: these click by position and can hit the wrong element. Agents now retry with the unique locator listed in the Playwright error. -
Shorter agent install prompt on the extension welcome page.