anthropics/skills · skills/webapp-testing/SKILL.md
webapp-testing
“Anthropic's Playwright skill: lean, practical web app testing that never says what 'passed' looks like”
What it does
Guides the agent to test local web apps by writing Python Playwright scripts. A bundled helper starts and stops dev servers around the script, and a short decision tree covers static HTML, servers not yet running, and live apps.
- When the agent uses it
- When asked to test, click through, screenshot or debug a local web app or HTML file with Playwright, including reading browser console logs.
- Who it is for
- Good for anyone testing a local frontend with Python Playwright installed; skip it if you test in JS/TS Playwright, Cypress, or against remote sites.
- What it costs
- 74 lines, about 1k tokens once the agent loads it.
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
What it tells the agent to do
- Decide whether the target is static HTML or a dynamic web app
- For static HTML, read the file for selectors and write a Playwright script, or treat it as dynamic if that fails
- If no server is running, run scripts/with_server.py --help, then wrap the automation script with it
- Launch headless Chromium, open the page and wait for networkidle
- Take a screenshot or dump the DOM to find selectors from the rendered page
- Run the actions with the discovered selectors, then close the browser
Lines worth reading
Straight from the file, with why each one matters.
line 3Toolkit for interacting with and testing local web applications using Playwright.
The trigger. It names the tool and the target up front but never says 'use when', so the agent has to infer the moment.
line 14DO NOT read the source until you try running the script first
A sharp context-saving rule: treat helpers as black boxes and run --help rather than loading big files into the context.
line 47--server "cd backend && python server.py" --port 3000
A useful trick: one helper call can start a backend and a frontend, wait on their ports, then run your script.
line 60page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
Marked critical, yet Playwright's own docs discourage networkidle. Apps that poll or stream may never go idle and will time out.
line 89page.wait_for_timeout()
Listed as an 'appropriate wait', but fixed sleeps are the classic source of flaky tests.
Watch out for
- Medium
with_server.py runs whatever shell commands are passed to --server, and the agent is told not to read it. Its source could not be checked here.
line 14They exist to be called directly as black-box scripts rather than ingested into your context window.
- Low
Relying on networkidle can hang or time out on apps with polling or live connections, which wastes runs and gives misleading failures.
line 60page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
The scorecard
- TriggerSays when to use it7/10
Clear tool and target words, but no 'use when' clause
- FocusOne clear job8/10
One job: drive local web apps with Playwright
- LeanLight to load8/10
About 100 lines; helpers and examples kept in side files
- ConcreteSteps you can follow7/10
Real commands and code, but no assertions or definition of done
- SafeSafe to run7/10
Unread black-box script runs arbitrary server commands
What it does well
- The with_server.py examples show single and multi-server setups as copy-ready commands.
- The decision tree tells the agent which path to take before it writes any code.
- It keeps big helpers and examples out of the context, calling them by --help instead.
How it could be better
Add a 'use when' clause to the description
The agent decides from the description alone, so naming the requests that should trigger it makes the skill fire reliably.
Adddescription: Tests and debugs local web apps with Python Playwright: drives the browser, checks UI behavior, captures screenshots and console logs. Use when the user asks to test, click through, screenshot or debug a site on localhost or a local HTML file.
Say what a finished test looks like
Without assertions or a report format, the agent can 'test' a page without checking anything.
Add## Done means - Each check uses `expect(locator).to_be_visible()` / `to_have_text(...)` from `playwright.sync_api` - The script exits non-zero on failure - Report: what was checked, pass/fail per check, screenshot path (e.g. /tmp/<name>.png), and any console errors
Replace sleeps and networkidle with element waits
Fixed timeouts are flaky, and networkidle never settles on apps that poll, so waiting for a specific element is more reliable.
Add- Prefer `page.wait_for_selector('<selector>')` or `expect(<locator>).to_be_visible()` - Use `networkidle` only for simple pages; if it times out (polling, live reload), wait for a known element instead - Avoid `page.wait_for_timeout()` except while debugging
Kin reviews against Anthropic’s Extend Claude with skills and agentskills.io’s the Agent Skills standard. It reads SKILL.md only, so a script beside it can still do things the file does not say.