Skip to main content
This guide assumes you’ve already installed Playwriter. You’ll create a session, navigate to a page, take a snapshot, and interact with elements.
1

Create a session

Sessions provide isolated state for your automation tasks. Each session has its own state object that persists between commands.
playwriter session new
This outputs a session ID (e.g., 1). You’ll use this ID in all subsequent commands.
Always use -s <session-id> with your commands. Using the same session preserves your state between calls.
2

Navigate to a page

Use the execute command to run Playwright code. Navigate to a website:
playwriter -s 1 -e 'await page.goto("https://example.com")'
Always wrap -e code in single quotes ('...') to prevent bash from interpreting $, backticks, and other special characters. Use double quotes for strings inside the JavaScript code.
3

Take a snapshot

Get an accessibility snapshot of the page. This shows all interactive elements with their locators:
playwriter -s 1 -e 'console.log(await snapshot({ page }))'
Example output:
- banner:
  - heading "Example Domain" [id="main-heading"]
  - link "More information..." role=link[name="More information..."]
The snapshot shows interactive elements and their Playwright locators (in square brackets).
4

Interact with elements

Use locators from the snapshot to click elements. The snapshot provides the exact selector:
playwriter -s 1 -e 'await page.locator("role=link[name=\"More information...\"]").click()'
Or use the locator directly:
playwriter -s 1 -e 'await page.getByRole("link", { name: "More information..." }).click()'
Always get a fresh snapshot before clicking. Locators can change when the page updates.
5

Check the result

After any action, verify what happened by printing the URL and taking another snapshot:
playwriter -s 1 -e 'console.log("URL:", page.url()); console.log(await snapshot({ page }))'
This is the observe → act → observe loop. Always check page state after actions.

Create your own page

The default page variable is shared across all sessions. To avoid interference from other agents, create your own page:
playwriter -s 1 -e '
state.page = context.pages().find(p => p.url() === "about:blank") ?? await context.newPage();
await state.page.goto("https://example.com");
console.log("URL:", state.page.url());
'
Now use state.page for all subsequent operations:
playwriter -s 1 -e 'console.log(await snapshot({ page: state.page }))'
playwriter -s 1 -e 'await state.page.click("button")'

Multiline code

For complex logic, use a heredoc to avoid bash quoting issues:
playwriter -s 1 -e "$(cat <<'EOF'
const title = await state.page.title();
const url = state.page.url();
console.log({ title, url });
EOF
)"
The quoted 'EOF' delimiter disables all bash expansion, so $, backticks, and single quotes work inside the JavaScript.

Session management

List all active sessions:
playwriter session list
Example output:
ID  State Keys
--------------
1   myPage, userData
2   -
Reset a session if the browser connection is stale:
playwriter session reset 1

Taking screenshots

For visual layout issues, take a screenshot with visual labels:
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page: state.page })'
This overlays Vimium-style labels on interactive elements, captures a screenshot, then removes the labels. The image and accessibility snapshot are automatically included in the response.
Always use scale: 'css' when taking screenshots to avoid 2-4x larger images on high-DPI displays:
playwriter -s 1 -e "await state.page.screenshot({ path: 'screenshot.png', scale: 'css' })"

Persist data in state

The state object persists between execute calls within your session:
playwriter -s 1 -e 'state.users = await state.page.$$eval(".user", els => els.map(e => e.textContent))'
playwriter -s 1 -e 'console.log(state.users)'
Each session has its own isolated state. Sessions don’t interfere with each other.

What’s available in scope?

When you run playwriter -s <id> -e '<code>', the following variables are in scope:
  • page - a default page (may be shared with other agents)
  • context - browser context, access all pages via context.pages()
  • state - object persisted between calls within your session
  • require - load Node.js modules (e.g., const fs = require('node:fs'))
  • Node.js globals: setTimeout, fetch, URL, Buffer, crypto, etc.

Common patterns

Get page title

playwriter -s 1 -e 'console.log(await state.page.title())'

Click a button

playwriter -s 1 -e 'await state.page.click("button")'

Fill an input

playwriter -s 1 -e 'await state.page.fill("input[name=email]", "[email protected]")'

Wait for selector

playwriter -s 1 -e 'await state.page.waitForSelector("article", { timeout: 10000 })'

Extract data

playwriter -s 1 -e '
const links = await state.page.$$eval("a", els => els.map(e => e.href));
console.log(links);
'

Next steps

CLI usage

Learn advanced CLI features and best practices

API reference

Explore all available functions and utilities

Examples

See real-world automation examples

Troubleshooting

Fix common issues and view logs

Build docs developers (and LLMs) love