-
Screen recording and streaming without an extension click:
recording.*andstream.*now use CDP screencast piped toffmpeginstead ofchrome.tabCapture. No user click and no special Chrome flags. Recording now also works in direct CDP mode, headless, cloud browsers and Remote control, and survives cross-site navigation.await recording.start({ page: state.page, outputPath: './demo.mp4', audio: true }) await state.page.click('a') const { path, duration, size } = await recording.stop({ page: state.page })
ffmpegon PATH is required..mp4,.mov,.mkvuse H.264 (hardware encoder when available) + AAC..webmuses VP8 + Opus.- Page audio with
audio: truetaps<audio>,<video>and AudioContext output. Default off for recordings, on for streams. Cross-origin iframe audio is not captured. - New options
maxSize(longest edge, default 1920) andquality(JPEG, default 90). - Breaking:
videoBitsPerSecondandaudioBitsPerSecondare removed. The library exportsstopRecording,isRecordingandcancelRecordingare replaced bystartRecording({ page, outputPath }), which returns a recording withstop()andcancel(). The relay/recording/*and/stream/*endpoints are removed. stream.stop()returns{ duration, frames }. Streams end when the page closes or the session is reset.- The skill recorder and a video recording on the same tab no longer stop each other.
- The extension no longer asks for the
tabCapturepermission.
-
Skill recordings explain why a step failed:
- Toasts and alerts: new
toastevents hold the text ofrole=alert,role=statusandaria-liveregions. A click that sent no request because the site refused it on the client (limits, validation) now shows the reason. - Same-origin GETs (quota checks, job polling) are recorded. Cross-origin GETs are still skipped.
- Compressed response bodies: gzip and brotli JSON responses are stored instead of
responseBodyOmitted: "encoded". afterAction:networkandtoastevents carry the id of the action that happened up to 3s before them.- Auto-stop at 500 MB: recordings stop when frames and events grow past 500 MB. The
recording-stoppedevent hasreason: "max-size"and the totalbytes.
New CLI options to read recordings faster:
playwriter recorder events --errors # failed requests, console and page errors, toasts playwriter recorder events --exclude 'analytics|telemetry' # drop noisy network URLs playwriter recorder frame 42 --offset 1500 # screencast frame 1.5s after event 42
The thin timeline merges runs of identical requests into one event with
repeatandlastId. - Toasts and alerts: new
-
Chrome menus and a smaller in-page toolbar: right-click a page or the extension icon to find Playwriter actions.
page right-click > Playwriter extension icon right-click ├─ Copy Playwriter Locator for this element ├─ ─────────── ┐ ├─ Copy remote agent prompt │ only while sharing ──> same items ├─ Copy remote id │ └─ Stop sharing ┘- Copy Playwriter Locator works on any tab, even before you enable Playwriter on it. It pins the right-clicked element (also inside open shadow roots), copies the
playwriter -e 'inspectPinnedElement(...)'command and attaches the tab. - Short toasts like
Copied locatorand a short sound confirm every copy. - The in-page toolbar now starts as a small tab at the top center of the page. Click it to open the full toolbar with labels;
×collapses it again. No hover expansion or dragging. Agent clicks still pass through it. - Record Skill and Remote control start from the toolbar. Toolbar and menus share one Remote control state, so you can start sharing from the toolbar and stop it from the menu.
- Copy Playwriter Locator works on any tab, even before you enable Playwriter on it. It pins the right-clicked element (also inside open shadow roots), copies the
-
Breaking:
connectViaExtension()keeps tabs open onclose()by default: each SDK script closes the tabs it opens, so a later process or another script sharing the tab can keep using it.await using connection = await connectViaExtension({ tabGroup: 'docs' }) await using page = await connection.browser.contexts()[0].newPage() // closes its tab at scope end await page.goto('https://example.com')
Pass
closeTabsOnEnd: truefor the old behavior:close()also closes every tab the connection opened, plus popups they opened. -
Ghost cursor stays hidden until the agent uses the mouse: it now appears on the first click, move or scroll, then fades out after 5 seconds idle.
-
Remote control tunnels no longer stay awake while idle: relays send WebSocket protocol pings that Cloudflare answers at the edge, instead of a JSON ping every 5 seconds. Dials to a browser that stopped sharing fail at once and back off from 1s up to 60s; after 10 minutes offline the relay stops dialing, and the next
executeon that session dials again. A failedplaywriter session new --remote <id>no longer leaves a dial running. -
Fixed the page closing when another extension injects an iframe: password managers like 1Password inject a
chrome-extension://iframe on focus, and Chrome then detaches the debugger from the whole tab. The extension now removes those iframes, reattaches with the same session and restores init scripts, exposed functions, viewport and emulation, so the samepagekeeps working. Chromium treats this detach as intended: https://issues.chromium.org/issues/498987209 -
Fixed new tabs missing from
context.pages()when Chrome creates them inside a Playwriter group without a later group-change event. Child tabs are now controllable without another extension click. -
Fixed
Function "__pw_recorderRecordAction" is not exposedpage errors when several sessions or CDP clients share a tab. Only the client that exposed a function now answers its calls (via@xmorse/playwright-core@1.59.14). -
Better welcome page: the agent install prompt now ends with the agent telling you what Playwriter can do (your own Chrome with logins, working together in one browser, full Playwright API, Record skill, Remote control). CLI examples fit on one line.
-
Skill tells agents to pass a short
--tab-groupname likedocsorshopinstead of using the defaultplaywritergroup.