playwright · git:20260928.1f81021 · 2026-09-28 · sha256 67158499850c7674

playwright git:20260928.1f81021A

Immutable. This exact content never changes and is served at /api/v1/blob/67158499850c7674.

---
name: "playwright"
description: "Use when the task requires automating a real browser from the terminal (navigation, form filling, snapshots, screenshots, data extraction, UI-flow debugging) via `playwright-cli` or the bundled wrapper script."
---


# Playwright CLI Skill

Drive a real browser from the terminal using `playwright-cli`. Prefer the bundled wrapper script so the CLI works even when it is not globally installed.
Treat this skill as CLI-first automation. Do not pivot to `@playwright/test` unless the user explicitly asks for test files.

Before any browser command, read [session ownership and cleanup](references/lifecycle.md).
It is mandatory for every workflow, including examples copied from the references.

## Prerequisite check (required)

Before proposing commands, check whether `npx` is available (the wrapper depends on it):

```bash
command -v npx >/dev/null 2>&1
```

If it is not available, pause and ask the user to install Node.js/npm (which provides `npx`). Provide these steps verbatim:

```bash
# Verify Node/npm are installed
node --version
npm --version

# If missing, install Node.js/npm, then:
npm install -g @playwright/cli@latest
playwright-cli --help
```

Once `npx` is present, proceed with the wrapper script. A global install of `playwright-cli` is optional.

## Skill path (set once)

Resolve `scripts/playwright_cli.sh` relative to this skill directory, then export that absolute path:

```bash
export PWCLI="/absolute/path/to/this/skill/scripts/playwright_cli.sh"
```

Do not assume this skill is installed under `~/.codex/skills`; it may be loaded from a plugin cache.

Run `"$PWCLI" --version` before using the command examples. They were verified
against `@playwright/cli` 0.1.21. For another resolved version, check its `--help`
before using `requests`, `run-code`, or the configuration path; do not assume
an older cached CLI supports the documented syntax.

## Quick start

Generate one session name for this task and pass it explicitly on every browser
command. Keep the same value across shell calls; never generate it per command.
The mandatory lifecycle reference defines when a session may be closed.

```bash
PW_SESSION="codex-$(node -e 'process.stdout.write(require("node:crypto").randomUUID())')"
"$PWCLI" --session "$PW_SESSION" open https://playwright.dev --headed
"$PWCLI" --session "$PW_SESSION" snapshot
"$PWCLI" --session "$PW_SESSION" click e15
"$PWCLI" --session "$PW_SESSION" type "Playwright"
"$PWCLI" --session "$PW_SESSION" press Enter
"$PWCLI" --session "$PW_SESSION" screenshot
# After verifying the saved artifact and cleanup conditions:
"$PWCLI" --session "$PW_SESSION" close
```

If the user prefers a global install, this is also valid:

```bash
npm install -g @playwright/cli@latest
playwright-cli --help
```

## Core workflow

1. Record session ownership and open the page in the task's explicit session.
2. Snapshot to get stable element refs.
3. Interact using refs from the latest snapshot.
4. Re-snapshot after navigation or significant DOM changes.
5. Capture artifacts (screenshot, pdf, traces) when useful.
6. Verify saved outputs, then finalize the owned session or record a deliberate
   handoff using the mandatory lifecycle reference.

Minimal loop:

```bash
"$PWCLI" --session "$PW_SESSION" open https://example.com
"$PWCLI" --session "$PW_SESSION" snapshot
"$PWCLI" --session "$PW_SESSION" click e3
"$PWCLI" --session "$PW_SESSION" snapshot
```

## When to snapshot again

Snapshot again after:

- navigation
- clicking elements that change the UI substantially
- opening/closing modals or menus
- tab switches

Refs can go stale. When a command fails due to a missing ref, snapshot again.

## Recommended patterns

### Form fill and submit

```bash
"$PWCLI" --session "$PW_SESSION" open https://example.com/form
"$PWCLI" --session "$PW_SESSION" snapshot
"$PWCLI" --session "$PW_SESSION" fill e1 "user@example.com"
"$PWCLI" --session "$PW_SESSION" fill e2 "password123"
"$PWCLI" --session "$PW_SESSION" click e3
"$PWCLI" --session "$PW_SESSION" snapshot
```

### Debug a UI flow with traces

```bash
"$PWCLI" --session "$PW_SESSION" open https://example.com --headed
"$PWCLI" --session "$PW_SESSION" tracing-start
# ...interactions...
"$PWCLI" --session "$PW_SESSION" tracing-stop
```

### Multi-tab work

```bash
"$PWCLI" --session "$PW_SESSION" tab-new https://example.com
"$PWCLI" --session "$PW_SESSION" tab-list
"$PWCLI" --session "$PW_SESSION" tab-select 0
"$PWCLI" --session "$PW_SESSION" snapshot
```

## Wrapper script

The wrapper script uses `npx --package @playwright/cli playwright-cli` so the CLI can run without a global install:

```bash
"$PWCLI" --help
```

Prefer the wrapper unless the repository already standardizes on a global install.

## References

Read the lifecycle contract first; open the other references as needed:

- Required session lifecycle: [ownership and cleanup](references/lifecycle.md)
- CLI command reference: `references/cli.md`
- Practical workflows and troubleshooting: `references/workflows.md`

## Guardrails

- Always snapshot before referencing element ids like `e12`.
- Re-snapshot when refs seem stale.
- Prefer explicit commands over `eval` and `run-code` unless needed.
- When you do not have a fresh snapshot, use placeholder refs like `eX` and say why; do not bypass refs with `run-code`.
- Use `--headed` when a visual check will help.
- When capturing artifacts in this repo, use `output/playwright/` and avoid introducing new top-level artifact folders.
- Default to CLI commands and workflows, not Playwright test specs.