-
New
--patchrightsession mode with human-like input: for production sites where you are logged in. The session connects with Patchright (@playwriter/patchright-core) instead of Playwright. Mouse moves follow curved paths, clicks get human press timing, scrolling glides in wheel flicks, and key presses are spaced 30-110 ms apart.playwriter session new --tab-group shop --patchright # switch an existing session; tabs stay open, state is cleared playwriter session update 1 --patchright playwriter session update 1 --patchright false
With Patchright,
page.evaluateruns in the main world like in Playwright. Passtrueas fourth argument for Patchright's isolated world, where pages cannot see the call.snapshot,getPageMarkdownandwaitForPageLoadalways run isolated.page.on('console')stays silent because Patchright keeps CDPRuntimeoff; usegetLatestLogs. The Node API takesconnectViaExtension({ patchright: true }), andplaywriter --patchright(MCP) also humanizes input. The driver is now per session, not per relay. -
Each CLI session sees only its own tabs: a session sees the tabs it opened (and their popups), plus tabs you enabled with the extension icon. Parallel agents no longer navigate or close each other's tabs. Tabs of a deleted session become shared again. SDK scripts and the MCP still see every tab. Needs extension 0.0.174; with an older extension every tab stays shared.
-
Tabs report focus only while an execute uses them:
document.hasFocus(),focusandblurevents of a CLI session's tab are active only while an execute of that session runs. Before, every attached tab claimed focus all the time, and chat apps marked messages as read in tabs nobody looked at. MCP and SDK connections keep the always-focused behavior. -
Native screen recording:
recording.startnow uses Chrome's own screen recorder (Chrome 153+). A 1080p recording costs about 4x less Chrome CPU and 15x less CDP traffic.- Defaults are 60 fps (max 120) and a 3840 px longest edge. Pass
maxSize: 1920for X uploads. - Output is H.264 MP4, so stop takes under a second.
codec: 'av1'keeps Chrome's output and needs no ffmpeg. audio: truerecords tab audio, cross-origin iframes included.- Auto-stop is 60 minutes and saves the file. A closed page keeps what was recorded.
stop()returnsendReason. - The video grows in
<name>.<id>.partial.mp4, so a crash leaves a playable file. recording.stop({ page })recovers a lost handle. RelativeoutputPathresolves against the session cwd.- The
qualityoption is removed. Older Chrome fails with an "update Chrome" error.
- Defaults are 60 fps (max 120) and a 3840 px longest edge. Pass
-
Warnings for verification and block pages: after an execute navigates, Playwriter checks for a verification page. Checks that clear by themselves are waited out. Otherwise execute prints a
[WARNING]that tells the agent not to reload and to ask the user. -
Pages can no longer see Playwriter's scripts: the ghost cursor, bot challenge check and screenshot cleanup run in a private isolated world. Pages find no
__playwriterGhostCursorglobal, leftover<style>or<html>class. With human-like input, element clicks land a few pixels off center, inside the element. -
snapshot()shows element state: in Playwright aria syntax, before the locator:- heading "Settings" [level=2] - checkbox "Alerts" [checked] [id="alerts"] - [expanded] role=button[name="Menu"i]snapshot({ search })now matches strings case-insensitively, handles regexes with thegflag, and starts with a match count like12 matches (showing 10). Snapshots never show Playwriter's toolbar. -
Web workers work:
page.on('worker'),page.workers()andworker.evaluate()work in Playwright and Patchright sessions, also for workers that already ran before a reconnect. -
Safe CLI upgrades: a newer CLI asks the old relay to drain. It refuses new executes with a "relay is restarting" error and waits up to 30 seconds for running ones.
playwriter serve restartrefuses while executes run; pass--forceto restart anyway. Ctrl-C or an agent bash timeout onplaywriter -eaborts the running script. -
Session ids are never reused: ids survive relay restarts in
~/.playwriter/session-counter.json. A stale-s 1now fails withSession N ended or was lost when the relay restartedinstead of running in another agent's session. -
Relay survives agent mistakes: a missing
awaitor a throwing timer callback no longer kills the relay. The session gets a[WARNING] Unhandled promise rejection in your code (missing await?)line.resetandsession deleteclear pending sandbox timers.relay-server.logkeeps the previous run asrelay-server.log.1and rotates at 20 MB. A background relay now usesPLAYWRITER_PORT. -
Execute output keeps the return value: long
console.logoutput no longer hides the result. Logs keep their start and end, and repeated lines show once with a count, like[log] retrying (x37).playwriter -eno longer cuts error output at 64 KiB when piped. -
Better recovery guidance: execute warns when a page in state crashes. Errors for crashed tabs, closed pages and failed navigations give specific steps instead of a session reset. Actions are never retried automatically.
-
Cookies and
route.fetch()work:route.fetch(),context.cookies()andcontext.addCookies()work, also with older extensions.context.clearCookies()throws a clear error, because it would delete cookies for every site in your browser. Fixes #66. -
Long
page.evaluate()calls:page.evaluate()andpage.waitForFunction()can wait up to 5 minutes. Before, the relay cut them at 30 seconds with a misleading "Execution context was destroyed" error. -
New CDP clients no longer break other sessions on a tab: a running
page.evaluate()keeps working and element handles stay valid when another client connects. -
Raw CDP clients get
Target.targetInfoChanged: browser-use and other clients that track page URLs from this event no longer see every page as blank. -
refToLocatorresolves labelled screenshot refs: it uses refs from the lastscreenshotWithAccessibilityLabelscall. Labels are also drawn in the right place on scrolled pages. -
Extension welcome page shows if Playwriter is pinned: the "Pin the extension" step turns into a checkmark when you pin it.
-
Playwright 1.64.1:
@xmorse/playwright-coreis based on Playwright 1.64.1.locator.dblclick()sends a real double click, andplaywriter recorderreports clicks live, so a click comes before the popup it opens. Every recording names its first pagepage.
Fixes #66