playwriter recorder start. From this
moment every click, fill, navigation, and mutating xhr/fetch is captured
to a JSON event file. A jpeg is saved for each visual change; clicks
flash a ripple in those frames. Recording attaches to the current
Playwriter tabs and auto-stops after 20 minutes.playwriter skill),
then playwriter recorder stop and inspects the events, verifying each
locator against the live page.SKILL.md with numbered playwriter commands plus a helper
script (submit.js, sdk.js), then validates the whole flow by replaying
that script end-to-end.await page.getByRole('button', { name: 'Submit' }).click().1234playwriter recorder start # Recording 1 started on session 1. # Events file: ~/.playwriter/recordings/1.json # ... prints the full skill-authoring instructions for the agent ...
123playwriter recorder stop # Recording 1 stopped. 47 events captured. # Events file: ~/.playwriter/recordings/1.json
1playwriter recorder events | jq -r '[.id, .t, .type, (.code // .url // empty)] | @tsv'
12345671 0 recording-started https://directory.example.com 2 2.1 action await page.getByRole('link', { name: 'Submit a product' }).click() 3 2.4 navigation https://directory.example.com/submit 4 3.8 action await page.getByRole('textbox', { name: 'Product name' }).fill('Acme') 5 5.2 action await page.getByRole('textbox', { name: 'Website URL' }).fill('https://acme.com') 6 7.0 action await page.getByRole('button', { name: 'Submit' }).click() 7 7.3 network POST 200 https://directory.example.com/api/products
1playwriter recorder events 7 # full request postData + responseBody of event 7
playwriter commands an agent can replay later with your logins.You (Chrome) Agent (CLI) │ │ │ toolbar Record │ playwriter recorder start ▼ ▼ POST /recorder/start POST /recorder/start (no sessionId) (-s optional) │ │ └─────────────────────┬────────────────────────┘ ▼ Relay picks a session (free extension session, or creates one) │ ▼ Playwright API recorder ~/.playwriter/recordings/<id>/ │ Stop │ playwriter recorder stop (its recording id) │ │ ▼ ▼ 1 recording ► stop it 2+ recordings ► error with page URLs then: recorder stop <id>
state). Browser tabs are
shared across extension sessions. The recorder attaches to one session's
Playwright context so it can listen for clicks. Any extension session sees the
same tabs.playwriter recorder stop and playwriter recorder events. If two recordings
are active, stop lists each one with its current or last page URL so the
agent can pick or ask you.| Start from | What happens |
| In-page Record | POST /recorder/start with no session id. Never fails just because many sessions exist. |
playwriter recorder start | Reuses the only session, or creates one. Pass -s <id> when several sessions exist. |
playwriter recorder start -s 1 | Attaches to session 1. Fails with 409 if that session is already recording. |
playwriter recorder stop without an id stops the only active
recording, or errors with URLs if there are several.12345678910playwriter recorder start # reuse the only session, or create one playwriter recorder start -s 1 # attach to an existing session playwriter recorder status # active recordings + current page urls playwriter recorder stop # stop the only active recording playwriter recorder stop 3 # stop recording 3 playwriter recorder events # thin timeline of the latest recording playwriter recorder events -r 3 # events of recording 3 playwriter recorder events 4 7 # full details of events 4 and 7 playwriter recorder events --type action playwriter recorder events --full # whole timeline, no size projection
recorder events prints one JSON object per line (jq-friendly). Default output
is a thin timeline: heavy payloads become sizes. Pass event ids to read
full request and response bodies.12playwriter recorder events | jq -r 'select(.type == "action") | .code' playwriter recorder events | jq -r 'select(.type == "network") | [.id, .method, .status, .url] | @tsv'
1234Multiple active recordings. Pass a recording id. 3 session 1 https://app.example.com/settings 5 session 2 https://github.com/remorses/playwriter
123playwriter recorder status playwriter recorder stop 3 playwriter recorder events -r 3
t, seconds since start):| Event type | What it captures |
action | Click, fill, press, select, setInputFiles — with generated Playwright locator code |
network | POST/PUT/PATCH/DELETE xhr/fetch only: method, url, status, post data, and response bodies for JSON/text. WebSockets are not recorded. |
download | File downloads: source url and suggested filename |
navigation | Full navigations |
page-opened / page-closed | Popups and new tabs, with page aliases |
console / page-error | Console errors/warnings and uncaught page errors |
signal | Navigation signals tied to an action |
recorder start output tells the agent to read
https://playwriter.dev/SKILL.md first, inspect
the events, verify locators against the live page, then write a SKILL.md
plus a helper script named for the flow (submit.js, sdk.js): markdown
instructions for the flow you performed, with example playwriter
commands, and an importable script for cheap replay.12345678910111213141516171819202122# Submit to directory Preconditions: already signed in. Playwriter drives the browser. 1. Open the submit page ```bash playwriter -s 1 -e 'await page.goto("https://directory.example.com/submit")' ``` 2. Fill name and URL (parameters) ```bash playwriter -s 1 -e 'const name = "Acme"; await page.getByRole("textbox", { name: "Product name" }).fill(name)' playwriter -s 1 -e 'const url = "https://acme.com"; await page.getByRole("textbox", { name: "Website URL" }).fill(url)' ``` 3. Click Submit. Expect POST `/api/products` and confirmation text. ```bash playwriter -s 1 -e 'await page.getByRole("button", { name: "Submit" }).click()' ```
1playwriter -s 1 -e 'const { submitProduct } = await import("./.agents/skills/submit-to-directory/submit.js"); await submitProduct({ page, name: "Acme", url: "https://acme.com" })'
fetch
(page.evaluate), so cookies, captchas, and Cloudflare stay in the real tab:1234# the site's API surface, extracted from one recorded session playwriter recorder events | jq -r 'select(.type == "network" and .responseBodySize) | [.id, .method, .url, .responseBodySize] | @tsv' # then read the full request/response payloads of the interesting endpoints playwriter recorder events 14 15 22
sdk.js. Shared state (page) goes in the constructor.
Methods take one object argument. fetch runs inside page.evaluate. Failed
calls throw with method, path, status, and response text.{ name, email, owner }.download events tie each file to the click that
produced it, so the agent writes a skill with a month parameter per vendor. The same pattern
covers bank statements, shipping labels, and result PDFs from healthcare or government
portals.setInputFiles actions —
and replay it for every launch, adapting locators per site while reusing the flow shape.console errors, page-error events — is a complete repro report an
agent can replay and debug against.http://127.0.0.1:19988/recorder/start. Check:playwriter session list should respond)playwriter logfile for Record start endpoint errorplaywriter recorder start asks for -s-s when several sessions exist, because you are
choosing a sandbox to attach to. The toolbar does not. Pass -s or let the
user click Record.1playwriter recorder stop 3
~/.playwriter/recordings/<id>.json.~/.playwriter/recordings/<id>.json (readable only by your user).
Cookie values are never stored; storage values and request bodies are truncated.