# Ref Sp Dev Playwright CLI

> Automate browser interactions, test web pages, and work with Playwright tests via the playwright-cli terminal tool. Use when: driving a real browser from the command line (open/goto/click/fill/snapshot), debugging a page's console/network/DOM, running or debugging Playwright tests, recording video or traces of a session, or asking the user for live UI/design feedback.

- Skill: `swiftpostlabs/ref-sp-dev-playwright-cli` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add swiftpostlabs/ref-sp-dev-playwright-cli`
- Raw SKILL.md: https://api.skillmd.com/api/skills/swiftpostlabs/ref-sp-dev-playwright-cli/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: swiftpostlabs (https://skillmd.com/u/swiftpostlabs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/swiftpostlabs/ref-sp-dev-playwright-cli

---


# Browser Automation with playwright-cli

## Purpose

Drive a real, running browser from the terminal — navigate, click, fill forms, inspect the DOM,
mock network requests, and capture screenshots/video/traces — without writing a throwaway
Playwright script for one-off checks or agent-driven UI verification.

## When to use this skill

- Verifying a UI or frontend change actually works by exercising it in a real browser.
- Debugging a page's console output, network requests, or DOM state interactively.
- Running or debugging Playwright test files (`references/playwright-tests.md`).
- Recording a session as video or trace for later review (`references/video-recording.md`, `references/tracing.md`).
- Asking the user for live UI/design feedback via the annotation dashboard.
- Reading a page that plain fetching cannot retrieve — see [Reading pages that plain fetching
  cannot](#reading-pages-that-plain-fetching-cannot).
- Any task that would otherwise require writing and discarding a one-off Playwright script.

## Provenance

Forked from the `playwright-cli` Agent Skill bundled with `@playwright/cli@0.1.17`
(`microsoft/playwright-cli` on GitHub, distributed inside `playwright-core`), Apache-2.0 licensed.
This repo owns the packaging/integration of the skill into its own catalog; the command reference
below is upstream Playwright/Microsoft content, adapted only to this repo's skill conventions.

## Setup in this repo

`@playwright/cli` is a devDependency (see `package.json`); run the CLI via the `yarn playwright`
script or `node_modules/.bin/playwright-cli` directly. Requires Node >= 22 — use the repo's Node
toolchain (`nvm use 22` or `corepack enable` if `yarn`/`playwright-cli` are not on `PATH`).

## Reading pages that plain fetching cannot

Repo-owned guidance, not upstream. Escalate in this order and stop as soon as you have the content —
a browser costs far more than a fetch, so it is a step to reach for on evidence, not by default.

**1. Plain fetching first.** Cheapest, and it works for most sources.

**2. Read the failure before escalating.** The symptom tells you which problem you have:

| Symptom | Cause | What helps |
| --- | --- | --- |
| HTTP 403 on a page a browser shows fine | Bot protection keyed on more than the User-Agent | A real browser |
| HTTP 200 with an empty or near-empty body | Client-rendered app; the HTML is a shell | A real browser |
| A challenge page — titles like `Just a moment...`, or body text about verifying you are not a bot | Interstitial challenge | A browser will **not** help; change source |

**3. Escalate to a real browser** for the first two:

```bash
playwright-cli goto <url>
playwright-cli eval "() => document.body.innerText"
```

`eval` on `innerText` is usually better than a snapshot when you want prose rather than structure —
it returns the rendered text without the accessibility tree around it.

**4. When the browser is also challenged, change source rather than escalating further.** Do not try
to defeat the challenge. The same content is very often served from somewhere without the
protection, and that path is both cheaper and more stable:

- a documentation, datasheet, or asset subdomain, often serving the authoritative PDF
- the project's repository rather than its rendered docs site — `gh api repos/OWNER/REPO/contents/PATH --jq '.content' | base64 -d` returns file contents directly
- a structured API rather than a rendered page — for example a registry or package API that answers the question as JSON without downloading the artifact

*Illustrative:* a vendor's marketing site sat behind an interstitial that defeated the browser, while
the same specification as a PDF on their `datasheets.` subdomain fetched with plain `curl`. The
browser was the wrong escalation; a different host was the answer.

**Record which sources needed which treatment** when the research will be revisited. The next agent
otherwise repeats the whole ladder from the top.

## Quick start

```bash
# open new browser
playwright-cli open
# navigate to a page
playwright-cli goto https://playwright.dev
# interact with the page using refs from the snapshot
playwright-cli click e15
playwright-cli type "page.click"
playwright-cli press Enter
# take a screenshot (rarely used, as snapshot is more common)
playwright-cli screenshot
# close the browser
playwright-cli close
```

## Commands

### Core

```bash
playwright-cli open
# open and navigate right away
playwright-cli open https://example.com/
playwright-cli goto https://playwright.dev
playwright-cli type "search query"
playwright-cli click e3
playwright-cli dblclick e7
# --submit presses Enter after filling the element
playwright-cli fill e5 "user@example.com"  --submit
playwright-cli drag e2 e8
# drop files or data onto an element (from outside the page)
playwright-cli drop e4 --path=./image.png
playwright-cli drop e4 --data="text/plain=hello world"
playwright-cli hover e4
playwright-cli select e9 "option-value"
playwright-cli upload ./document.pdf
playwright-cli check e12
playwright-cli uncheck e12
playwright-cli snapshot
# search the snapshot for text or a regexp, returns matching nodes with surrounding context
playwright-cli find "Sign in"
playwright-cli find --regex "Sign (in|up)"
# wrap the regexp in slashes to add flags, e.g. /i for case-insensitive
playwright-cli find --regex "/sign (in|up)/i"
playwright-cli eval "document.title"
playwright-cli eval "el => el.textContent" e5
# get element id, class, or any attribute not visible in the snapshot
playwright-cli eval "el => el.id" e5
playwright-cli eval "el => el.getAttribute('data-testid')" e5
playwright-cli dialog-accept
playwright-cli dialog-accept "confirmation text"
playwright-cli dialog-dismiss
playwright-cli resize 1920 1080
playwright-cli close
```

### Navigation

```bash
playwright-cli go-back
playwright-cli go-forward
playwright-cli reload
```

### Keyboard

```bash
playwright-cli press Enter
playwright-cli press ArrowDown
playwright-cli keydown Shift
playwright-cli keyup Shift
```

### Mouse

```bash
playwright-cli mousemove 150 300
playwright-cli mousedown
playwright-cli mousedown right
playwright-cli mouseup
playwright-cli mouseup right
playwright-cli mousewheel 0 100
```

### Save as

```bash
playwright-cli screenshot
playwright-cli screenshot e5
playwright-cli screenshot --filename=page.png
playwright-cli screenshot --hires
playwright-cli pdf --filename=page.pdf
```

### Tabs

```bash
playwright-cli tab-list
playwright-cli tab-new
playwright-cli tab-new https://example.com/page
playwright-cli tab-close
playwright-cli tab-close 2
playwright-cli tab-select 0
```

### Storage

```bash
playwright-cli state-save
playwright-cli state-save auth.json
playwright-cli state-load auth.json

# Cookies
playwright-cli cookie-list
playwright-cli cookie-list --domain=example.com
playwright-cli cookie-get session_id
playwright-cli cookie-set session_id abc123
playwright-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
playwright-cli cookie-delete session_id
playwright-cli cookie-clear

# LocalStorage
playwright-cli localstorage-list
playwright-cli localstorage-get theme
playwright-cli localstorage-set theme dark
playwright-cli localstorage-delete theme
playwright-cli localstorage-clear

# SessionStorage
playwright-cli sessionstorage-list
playwright-cli sessionstorage-get step
playwright-cli sessionstorage-set step 3
playwright-cli sessionstorage-delete step
playwright-cli sessionstorage-clear
```

### Network

```bash
playwright-cli route "**/*.jpg" --status=404
playwright-cli route "https://api.example.com/**" --body='{"mock": true}'
playwright-cli route-list
playwright-cli unroute "**/*.jpg"
playwright-cli unroute
```

### DevTools

```bash
playwright-cli console
playwright-cli console warning
playwright-cli requests
playwright-cli request 5
playwright-cli run-code "async page => await page.context().grantPermissions(['geolocation'])"
playwright-cli run-code --filename=script.js
playwright-cli tracing-start
playwright-cli tracing-stop
playwright-cli video-start video.webm
playwright-cli video-chapter "Chapter Title" --description="Details" --duration=2000
playwright-cli video-stop

# annotate each subsequent action (click, type, ...) with a callout naming the action and highlighting the target
playwright-cli video-show-actions --duration=600 --position=top-right
playwright-cli video-hide-actions

# launch the dashboard for UI review / design feedback — user annotates the page, you receive the annotated screenshot, snapshot, and notes
playwright-cli show --annotate

# generate a Playwright locator for an element from its ref or selector
playwright-cli generate-locator e5 --raw

# show a persistent highlight overlay for an element, optionally with a custom style
playwright-cli highlight e5
playwright-cli highlight e5 --style="outline: 3px dashed red"
# hide a single element highlight, or all page highlights when no target is given
playwright-cli highlight e5 --hide
playwright-cli highlight --hide
```

## Raw output

The global `--raw` option strips page status, generated code, and snapshot sections from the output, returning only the result value. Use it to pipe command output into other tools. Commands that don't produce output return nothing.

```bash
playwright-cli --raw eval "JSON.stringify(performance.timing)" | jq '.loadEventEnd - .navigationStart'
playwright-cli --raw eval "JSON.stringify([...document.querySelectorAll('a')].map(a => a.href))" > links.json
playwright-cli --raw snapshot > before.yml
playwright-cli click e5
playwright-cli --raw snapshot > after.yml
diff before.yml after.yml
TOKEN=$(playwright-cli --raw cookie-get session_id)
playwright-cli --raw localstorage-get theme
```

For structured output wrapping every reply as JSON, pass --json
```bash
playwright-cli list --json
```

## Open parameters
```bash
# Use specific browser when creating session
playwright-cli open --browser=chrome
playwright-cli open --browser=firefox
playwright-cli open --browser=webkit
playwright-cli open --browser=msedge

# Emulate a generic mobile device (Pixel 10 for Chromium, iPhone 17 for WebKit).
# Prefer this when a mobile layout is acceptable: mobile pages are usually
# lighter, so snapshots are smaller and cheaper.
playwright-cli open --mobile
playwright-cli open --device="iPhone 15"

# Use persistent profile (by default profile is in-memory)
playwright-cli open --persistent
# Use persistent profile with custom directory
playwright-cli open --profile=/path/to/profile

# Connect to browser via Playwright Extension
playwright-cli attach --extension=chrome

# Connect to a running Chrome or Edge by channel name
playwright-cli attach --cdp=chrome
playwright-cli attach --cdp=msedge

# Connect to a running browser via CDP endpoint
playwright-cli attach --cdp=http://localhost:9222

# Start with config file
playwright-cli open --config=my-config.json

# Close the browser
playwright-cli close
# Detach from an attached browser (leaves the external browser running)
playwright-cli -s=msedge detach
# Delete user data for the default session
playwright-cli delete-data
```

## URLs with `&` on Windows

On Windows, `cmd.exe` and PowerShell treat `&` as a command separator, so URLs with multiple query parameters get truncated before `playwright-cli` runs. Escape `&` with `^&` in `cmd.exe`, or use `--%` in PowerShell:

```batch
playwright-cli goto "https://example.com/?a=1^&b=2"
```

```powershell
playwright-cli --% goto "https://example.com/?a=1&b=2"
```

## Snapshots

After each command, playwright-cli provides a snapshot of the current browser state.

```bash
> playwright-cli goto https://example.com
### Page
- Page URL: https://example.com/
- Page Title: Example Domain
### Snapshot
[Snapshot](.playwright-cli/page-2026-02-14T19-22-42-679Z.yml)
```

You can also take a snapshot on demand using `playwright-cli snapshot` command. All the options below can be combined as needed.

```bash
# default - save to a file with timestamp-based name
playwright-cli snapshot

# save to file, use when snapshot is a part of the workflow result
playwright-cli snapshot --filename=after-click.yaml

# snapshot an element instead of the whole page
playwright-cli snapshot "#main"

# limit snapshot depth for efficiency, take a partial snapshot afterwards
playwright-cli snapshot --depth=4
playwright-cli snapshot e34

# include each element's bounding box as [box=x,y,width,height]
playwright-cli snapshot --boxes

# search a large snapshot instead of capturing it all — returns matching nodes
# with 3 lines of context around each match (like grep -C)
playwright-cli find "Add to cart"
playwright-cli find --regex "\\$[0-9]+\\.[0-9]{2}"
```

## Targeting elements

By default, use refs from the snapshot to interact with page elements.

```bash
# get snapshot with refs
playwright-cli snapshot

# interact using a ref
playwright-cli click e15
```

You can also use css selectors or Playwright locators.

```bash
# css selector
playwright-cli click "#main > button.submit"

# role locator
playwright-cli click "getByRole('button', { name: 'Submit' })"

# test id
playwright-cli click "getByTestId('submit-button')"
```

## Browser Sessions

```bash
# create new browser session named "mysession" with persistent profile
playwright-cli -s=mysession open example.com --persistent
# same with manually specified profile directory (use when requested explicitly)
playwright-cli -s=mysession open example.com --profile=/path/to/profile
playwright-cli -s=mysession click e6
playwright-cli -s=mysession close  # stop a named browser
playwright-cli -s=mysession delete-data  # delete user data for persistent session

playwright-cli list
# Close all browsers
playwright-cli close-all
# Forcefully kill all browser processes
playwright-cli kill-all
```

## Example: Form submission

```bash
playwright-cli open https://example.com/form
playwright-cli snapshot

playwright-cli fill e1 "user@example.com"
playwright-cli fill e2 "password123"
playwright-cli click e3
playwright-cli snapshot
playwright-cli close
```

## Example: Multi-tab workflow

```bash
playwright-cli open https://example.com
playwright-cli tab-new https://example.com/other
playwright-cli tab-list
playwright-cli tab-select 0
playwright-cli snapshot
playwright-cli close
```

## Example: Debugging with DevTools

```bash
playwright-cli open https://example.com
playwright-cli click e4
playwright-cli fill e7 "test"
playwright-cli console
playwright-cli requests
playwright-cli close
```

```bash
playwright-cli open https://example.com
playwright-cli tracing-start
playwright-cli click e4
playwright-cli fill e7 "test"
playwright-cli tracing-stop
playwright-cli close
```

## Example: Interactive session

Ask the user for UI review or design feedback. The user draws boxes on the live page and types comments; you receive the annotated screenshot, the snapshot of the marked region, and the user's notes. Use this whenever the user asks for "UI review", "design feedback", or to "ask the user what they think / want / mean":

```bash
playwright-cli open https://example.com
playwright-cli show --annotate
```

## Specific tasks

* **Running and Debugging Playwright tests** [references/playwright-tests.md](./references/playwright-tests.md)
* **Request mocking** [references/request-mocking.md](./references/request-mocking.md)
* **Running Playwright code** [references/running-code.md](./references/running-code.md)
* **Browser session management** [references/session-management.md](./references/session-management.md)
* **Storage state (cookies, localStorage)** [references/storage-state.md](./references/storage-state.md)
* **Test generation (plan / generate / heal)** [references/test-generation.md](./references/test-generation.md)
* **Tracing** [references/tracing.md](./references/tracing.md)
* **Video recording** [references/video-recording.md](./references/video-recording.md)
* **Inspecting element attributes** [references/element-attributes.md](./references/element-attributes.md)

