Playwright CLI Browser Automation
Drive a real browser from the terminal using playwright-cli. Navigate pages, fill forms, capture screenshots, extract data, and debug UI flows without writing test files.
Overview
Playwright CLI provides headless and headed browser control through a single command-line interface. Every interaction follows a snapshot-first pattern: open a page, take an accessibility snapshot to obtain stable element references (e1, e2, ...), then interact using those refs.
What you will learn:
- Setting up the wrapper script and verifying prerequisites
- The snapshot-interact-snapshot core loop
- Form filling, data extraction, and multi-tab workflows
- Tracing and debugging production UI issues
- Session isolation for parallel workstreams
Prerequisites:
- Node.js >= 18 and npm/npx on
PATH - The bundled
scripts/playwright_cli.shwrapper (avoids global install)
Learning Path
Level 1: Setup and First Snapshot
Verify Node.js and npx are available:
node --version # must be >= 18
npm --version
command -v npx >/dev/null 2>&1 && echo "npx ready"
If npx is missing, install Node.js first. Once available, set the wrapper path:
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export PWCLI="$SKILL_DIR/scripts/playwright_cli.sh"
Open a page and take the first snapshot:
"$PWCLI" open https://playwright.dev
"$PWCLI" snapshot
The snapshot returns an accessibility tree with stable refs like e1, e3, e15. Use these refs for all subsequent interactions.
Key point: Always snapshot before interacting. Stale refs cause ElementNotFound errors.
Level 2: Core Interaction Loop
The fundamental pattern is open-snapshot-interact-snapshot:
"$PWCLI" open https://example.com
"$PWCLI" snapshot # get initial refs
"$PWCLI" click e3 # interact with ref from snapshot
"$PWCLI" snapshot # refresh refs after DOM change
When to re-snapshot:
- After any navigation (
clickon a link,go-back,go-forward) - After modal open/close, dropdown expand, or tab switch
- After
fill/typeif it triggers dynamic content - Whenever a command returns
ElementNotFound
Common interactions:
"$PWCLI" click e5 # click element
"$PWCLI" dblclick e7 # double-click
"$PWCLI" fill e1 "user@test.io" # fill input field
"$PWCLI" type "search query" # type into focused element
"$PWCLI" press Enter # press keyboard key
"$PWCLI" select e9 "option-value" # select dropdown option
"$PWCLI" hover e4 # hover for tooltips
"$PWCLI" check e12 # check checkbox
"$PWCLI" uncheck e12 # uncheck checkbox
"$PWCLI" upload ./document.pdf # upload file
"$PWCLI" drag e2 e8 # drag and drop
Capture artifacts:
"$PWCLI" screenshot # full viewport PNG
"$PWCLI" screenshot e5 # element-specific screenshot
"$PWCLI" pdf # save page as PDF
Level 3: Advanced Patterns
Form submission workflow:
"$PWCLI" open https://app.example.com/login --headed
"$PWCLI" snapshot
"$PWCLI" fill e1 "admin@company.io"
"$PWCLI" fill e2 "securePass!42"
"$PWCLI" click e3 # submit button
"$PWCLI" snapshot # verify post-login state
"$PWCLI" screenshot # capture dashboard
Data extraction with eval:
"$PWCLI" eval "document.title"
"$PWCLI" eval "el => el.textContent" e12
"$PWCLI" eval "JSON.stringify([...document.querySelectorAll('table tr')].map(r => [...r.cells].map(c => c.textContent)))"
Multi-tab workflows:
"$PWCLI" tab-new https://docs.example.com
"$PWCLI" tab-list # see all open tabs
"$PWCLI" tab-select 0 # switch to first tab
"$PWCLI" snapshot # always snapshot after tab switch
"$PWCLI" tab-close 1 # close second tab
Debug with tracing:
"$PWCLI" open https://app.example.com --headed
"$PWCLI" tracing-start
"$PWCLI" snapshot
"$PWCLI" click e5
"$PWCLI" fill e8 "test data"
"$PWCLI" click e10
"$PWCLI" tracing-stop # saves trace.zip
The trace file can be viewed at trace.playwright.dev for timeline, network, and DOM inspection.
Session isolation:
"$PWCLI" --session checkout open https://shop.example.com/cart
"$PWCLI" --session checkout snapshot
"$PWCLI" --session admin open https://admin.example.com
"$PWCLI" --session admin snapshot
Or set once per shell:
export PLAYWRIGHT_CLI_SESSION=checkout
"$PWCLI" open https://shop.example.com/cart
Console and network inspection:
"$PWCLI" console # all console messages
"$PWCLI" console warning # warnings and errors only
"$PWCLI" network # all network requests
Browser window control:
"$PWCLI" open https://example.com --headed
"$PWCLI" resize 1920 1080
Best Practices
Do
- Snapshot before every interaction sequence
- Re-snapshot immediately after navigation or significant DOM mutations
- Use
--headedwhen visual confirmation helps debugging - Use
--sessionto isolate parallel workflows - Capture screenshots as evidence after completing multi-step flows
- Store artifacts under
output/playwright/<label>/to keep them organized - Use
evalfor targeted data extraction rather than scraping full HTML - Set
PWCLIonce at session start and reference it everywhere
Avoid
- Referencing element IDs (
e3,e12) without a recent snapshot - Using
run-codeorevalto bypass the snapshot-ref pattern - Running
@playwright/testspecs unless the user specifically requests it - Assuming refs survive across navigation or modal open/close
- Hardcoding element refs in scripts (they change between page loads)
- Skipping the npx prerequisite check
Common Questions
Q: Element ref e5 not found after clicking a link?
A: Navigation invalidates all refs. Run "$PWCLI" snapshot after the click completes, then use the new refs from the fresh snapshot.
Q: How do I handle authentication cookies across sessions?
A: Named sessions (--session myapp) maintain separate browser contexts with independent cookie jars. Cookies persist within a session until the browser closes.
Q: Can I run playwright-cli without Node.js?
A: No. The CLI depends on npx to resolve @playwright/mcp. Verify with command -v npx before starting. The wrapper script exits with an error if npx is missing.
Q: How do I configure viewport size or headless mode by default?
A: Create a playwright-cli.json configuration file:
{
"browser": {
"launchOptions": { "headless": false },
"contextOptions": {
"viewport": { "width": 1280, "height": 720 }
}
}
}
Place it in the working directory or pass --config path/to/config.json.
Examples
Example 1: Scrape a Table
User: Extract the pricing table from https://example.com/pricing
Assistant:
1. "$PWCLI" open https://example.com/pricing
2. "$PWCLI" snapshot → identifies table at e14
3. "$PWCLI" eval "JSON.stringify([...document.querySelectorAll('#pricing tr')].map(r => [...r.cells].map(c => c.textContent)))"
4. "$PWCLI" screenshot → saves visual evidence
Result: Returns JSON array of row/cell text content
Example 2: Fill and Submit a Login Form
User: Log into https://app.example.com with test credentials
Assistant:
1. "$PWCLI" open https://app.example.com/login --headed
2. "$PWCLI" snapshot → e1=email, e2=password, e3=submit
3. "$PWCLI" fill e1 "test@example.com"
4. "$PWCLI" fill e2 "TestPass123!"
5. "$PWCLI" click e3
6. "$PWCLI" snapshot → verify redirect to dashboard
7. "$PWCLI" screenshot → capture logged-in state
Example 3: Debug a Broken Checkout Flow
User: The checkout button does nothing on our staging site
Assistant:
1. "$PWCLI" open https://staging.shop.example.com/cart --headed
2. "$PWCLI" tracing-start
3. "$PWCLI" snapshot → locate checkout button at e22
4. "$PWCLI" click e22
5. "$PWCLI" console warning → check for JavaScript errors
6. "$PWCLI" network → inspect failed API requests
7. "$PWCLI" tracing-stop → save trace for detailed analysis
Result: Trace reveals 403 on POST /api/checkout (expired CSRF token)
Guardrails
- Always verify npx availability before running any playwright-cli command
- Always snapshot before referencing element IDs like
e12 - Re-snapshot when refs seem stale or after
ElementNotFounderrors - Prefer explicit CLI commands over
evalandrun-codeunless data extraction requires JavaScript - When you lack a fresh snapshot, use placeholder refs like
eXand explain why - Use
--headedwhen a visual check adds value - Default to CLI commands and workflows, not Playwright test specifications
- Store output artifacts under
output/playwright/<label>/in the project directory
References
Load these on demand when deeper detail is needed:
- CLI command reference:
references/cli-reference.md-- full command listing with arguments - Workflow patterns:
references/workflow-patterns.md-- step-by-step recipes for common scenarios