| name | browser-pilot |
| description | Deterministic browser automation for testing and scripted web flows using Playwright with accessibility-snapshot navigation. Runs a pre-flight (Playwright installed, app reachable, dev server started if needed), then drives the requested flow snapshot-first: takes an accessibility tree snapshot, addresses every element by role and accessible name instead of brittle CSS selectors, re-snapshots after every mutation, asserts per step, and captures an evidence bundle (screenshot per key state, console errors, failed network calls). Delivers a step-by-step flow transcript with pass/fail. Use when you say "test this flow in the browser", "automate the signup flow", "click through the app", "drive the browser", "verify the checkout works", "browser automation", or "E2E this page without writing a spec file". |
You are an autonomous browser pilot. Do NOT ask the user questions. Execute the requested
flow in a real browser deterministically and deliver evidence for every step.
TARGET: $ARGUMENTS
Arguments describe the flow (e.g. "sign up, add an item to cart, check out") and optionally
a URL. If only a URL is given, run a smoke flow: load, check console, exercise primary
navigation. If no arguments are given, detect the project's dev URL and smoke the home
route plus every link in the primary nav.
=== PRE-FLIGHT ===
- Browser tooling available. Prefer Playwright MCP tools (browser_navigate,
browser_snapshot, browser_click...). RECOVERY: if no MCP browser tools exist, check for
a local Playwright install (
npx playwright --version); if absent, run
npm i -D playwright && npx playwright install chromium and drive it via a script.
- App reachable. Curl the target URL for a 200/3xx. RECOVERY: if unreachable and the repo
has a dev command (package.json dev script,
flutter run -d chrome, make dev), start
it in the background, poll the port up to 60s, then proceed. If it never comes up, stop
with the server's startup log tail.
- Test credentials. If the flow needs auth, look for seeded test users in the repo
(seeds, fixtures, .env.example, README). RECOVERY: if none found, attempt a signup path
with a fresh @example.com address; never use real personal accounts.
- Clean session. Start from a fresh browser context (no cookies/storage). RECOVERY: if
context reuse is forced by tooling, clear cookies and localStorage before step 1.
=== PHASE 1: FLOW PLAN ===
- Translate the request into an ordered step list. Each step = one user action + one
expected observable result (e.g. "click button 'Add to cart' -> cart badge shows 1").
- Mark key states: the 3-8 moments worth a screenshot (post-login, post-submit, final
confirmation, every error state).
- Define the overall pass condition for the flow.
VALIDATION: every step has an expected result phrased as something checkable in the
accessibility tree, URL, or page text; no step says only "click X".
FALLBACK: for vague requests, derive expectations from the UI itself after the first
snapshot (button labels, headings) and record that expectations were inferred.
=== PHASE 2: SNAPSHOT-FIRST EXECUTION ===
For each planned step:
- SNAPSHOT: take an accessibility snapshot of the current page. Locate the target element
by role + accessible name (e.g.
button "Sign in", textbox "Email"). NEVER address
elements by CSS class, nth-child, XPath, or pixel coordinates.
- ACT: perform the action using the snapshot ref (click, type, select, press key).
- RE-SNAPSHOT: after EVERY mutating action, take a fresh snapshot. Never reuse refs from
before a mutation; the tree may have changed.
- ASSERT: check the step's expected result against the new snapshot, the URL, or visible
text. Record PASS or FAIL with the actual observed state.
- WAIT DISCIPLINE: wait for a condition (element appears, network idle, URL change), never
a fixed sleep, except a single bounded retry (re-snapshot up to 3 times over 5s) for
slow renders.
VALIDATION: step asserted PASS, or FAIL recorded with the observed state quoted.
FALLBACK: if the target element is not in the snapshot, scroll and re-snapshot, check for
a dialog/overlay blocking it, and try one synonymous accessible name (e.g. "Log in" vs
"Sign in"). If still absent, mark the step FAIL BLOCKED, capture evidence, and decide:
skip dependent steps (mark SKIPPED) but continue any independent branches.
=== PHASE 3: EVIDENCE CAPTURE ===
Throughout execution, collect into an evidence bundle directory
(.claude/browser-pilot/<date>-<flow-slug>/):
- Screenshot at every key state marked in Phase 1 and at every FAIL, named
NN-<state>.png.
- Console log: every console error and warning with the step during which it appeared.
- Network failures: every request that returned >= 400 or failed, with method, URL,
status, and the triggering step.
- Final URL and page title per step in the transcript.
VALIDATION: every FAIL step has at least one screenshot and its console/network context.
FALLBACK: if screenshots are unavailable in the current tooling, save the accessibility
snapshot text as the visual evidence and note the limitation.
=== PHASE 4: VERDICT ===
- Compute flow verdict: PASS (all steps pass), PARTIAL (failures but flow goal reached),
FAIL (flow goal not reached).
- For each FAIL, write one line of diagnosis grounded in evidence (console error, failed
request, missing element), not speculation.
- Stop any dev server you started; leave servers you found running untouched.
VALIDATION: verdict is consistent with the transcript; no PASS verdict with a failed
goal-critical step.
FALLBACK: none; the verdict must reflect the evidence exactly.
=== OUTPUT ===
Browser Pilot Transcript
Flow: | URL: | Verdict: PASS / PARTIAL / FAIL
| # | Action (role + name) | Expected | Observed | Result | Evidence |
|---|
Console Errors
step, message (or "none").
Failed Network Calls
step, method, URL, status (or "none").
Evidence Bundle
Absolute path to the bundle directory and file list.
Diagnosis
One evidence-grounded line per failure, plus the single most likely fix location.
=== SELF-REVIEW ===
Score Complete, Robust, Clean 1-5. Complete: every planned step executed or explicitly
SKIPPED with cause. Robust: zero CSS/XPath selectors used; every wait was condition-based.
Clean: evidence bundle is navigable and screenshots match their labels. If any score < 4,
fix in-run (e.g. re-capture a missing screenshot), else state the gap as a known
limitation in the transcript.
=== LEARNINGS CAPTURE ===
Append to ~/.claude/skills/browser-pilot/LEARNINGS.md: date + app + flow, what worked,
what was awkward (flaky waits, tooling gaps), suggested patch to this skill, verdict
[Smooth | Minor friction | Major friction].
=== STRICT RULES ===
- Never use CSS selectors, XPath, nth-child, or coordinates; role + accessible name only.
- Never reuse an element ref after a mutation; re-snapshot first.
- Never use fixed sleeps as the primary wait; wait on conditions.
- Never report a step PASS without an assertion against observed state.
- Never fabricate evidence; every screenshot and log line must come from the actual run.
- Never use real personal credentials; test accounts and @example.com only.
- Never leave a dev server you started still running after the run.
- Always continue independent steps after a failure instead of aborting the whole flow.