agentleFS
AbdurRafay2004AbdurRafay2004/handoff/skills/browser-qa/SKILL.md

browser-qa

Skill4 starsChanged 24 days agoMITView on GitHub

Use to exercise the running app in a real browser — after UI changes, before ship, or when the user asks to QA the site, smoke-test a branch, or check "does it actually work". Drives affected routes headlessly via Playwright, captures console errors, failed requests, and screenshots, and produces a report with a health score. Report-only — it finds bugs, it never fixes them.

  • Reads credentials
  • Installs packages

We split this skill into the rules it gives an agent

12 rules. 0 are common, 6 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 20 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every run — even T2 — ends with a health score and the plain-language summary.

    line 25
  2. Distinctive:

    Test what changed, not the whole site.

    line 29
  3. Very specific:

    Prefer the built-in verify and run skills: when available in this environment: run knows how to launch this project's app.

    line 49
  4. Distinctive:

    If they cover the need, use them and fold their observations into the report below.

    line 51
  5. Distinctive:

    If the host supplies browser tools, prefer those and adapt the checks and evidence below to that API.

    line 53
  6. Very specific:

    1. Get the app running: Check common dev ports first — Next.js :3000, Vite :5173, Astro :4321:

    line 60
  7. Very specific:

    If nothing is up, start npm run dev in the background, wait for the ready line, and note the port.

    line 67
  8. Very specific:

    If MISSING, ask the user once: "Browser QA needs Playwright (dev-only dependency).

    line 76
  9. Very specific:

    Never report an issue with no evidence at all.

    line 152
  10. Distinctive:

    If nothing is broken, say so plainly: score, routes covered, "no user-facing issues found".

    line 205
  11. Distinctive:

    Test as a user, not a developer: reading source is for *scoping routes only*, never for judging "that probably works".

    line 211
  12. Very specific:

    Keep all screenshots and scripts in $QA_OUT.

    line 212

“Common” is measured: kept by at least 6 in 10 of the 20 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Browser QA: exercise the running app, report what breaks

Part of the Verify phase — see the workflow skill for tiers and sequencing.

You are a QA engineer. Test the app like a real user — load the pages this change touched, click what a user would click, watch the console. Produce a report with evidence. NEVER fix anything. Fixes go through the normal Build/Verify loop (see Report-only discipline at the end).

Tier plan

Match effort to the tier the workflow skill assigned (or infer from the change's risk):

TierWhat to do
T1 (typo, comment, config-only)Skip browser QA entirely. Say so and stop.
T2 (normal features, including refactors; bug fixes)Smoke the affected routes only: load, console clean, no failed requests, screenshot, one DOM assert per route.
T3 (money, auth, user data, migrations — or pre-ship of such work)Full plan: affected routes plus adjacent routes and the top navigation targets, per-page checklist on each, health score with all categories.

Every run — even T2 — ends with a health score and the plain-language summary.

Scope: derive routes from the diff

Test what changed, not the whole site. From git diff main...HEAD --name-only and git log main..HEAD --oneline, map changed files to routes:

A multi-route QA run is token-heavy — a delegate trigger. Ask the user delegate-or-inline before running it (delegate skill).

Changed fileRoutes to test
Route/page file (app/**/page.tsx, pages/foo.tsx, src/pages/foo.astro)The route it serves (/foo)
Shared componentGrep for importers; test the routes that render them
Layout, global CSS, providersEvery route inherits it — test homepage + one route per layout
API handler (app/api/**, src/api/**)Hit the endpoint directly (fetch in the script or curl), plus the page that calls it
Model/service/lib codeRoutes whose pages call into it
Backend/config/infra with no obvious routeDo NOT skip — smoke homepage + top 5 nav targets; backend changes still break pages

Cross-reference commit messages to understand intent: what is this change supposed to do? Verify it does that, not just that pages load.

Driving the browser

Prefer the built-in verify and run skills when available in this environment: run knows how to launch this project's app; verify drives a changed flow end-to-end. If they cover the need, use them and fold their observations into the report below.

If the host supplies browser tools, prefer those and adapt the checks and evidence below to that API. In Codex, follow the installed browser skill; don't install Playwright or drive it through Bash when the host requires its own browser tools.

Otherwise, drive Chromium yourself via Playwright through Bash.

1. Get the app running. Check common dev ports first — Next.js :3000, Vite :5173, Astro :4321:

for p in 3000 5173 4321; do curl -sf -o /dev/null "http://localhost:$p" && echo "UP :$p"; done

If nothing is up, start npm run dev in the background, wait for the ready line, and note the port. If the port can't be determined, ask the user for the URL.

2. Check Playwright is available.

node -e "require.resolve('playwright')" 2>/dev/null && echo READY || echo MISSING

If MISSING, ask the user once: "Browser QA needs Playwright (dev-only dependency). OK to run npm i -D playwright && npx playwright install chromium?" Wait for a yes before installing. Never install silently.

3. Set up an evidence directory in the session scratchpad (never inside the repo):

QA_OUT="$SCRATCHPAD/browser-qa-$(date +%Y%m%d-%H%M%S)"   # use this session's scratchpad dir
mkdir -p "$QA_OUT"

4. Write the smoke script to $QA_OUT/qa-smoke.mjs and run it with the route list:

// qa-smoke.mjs — node qa-smoke.mjs <baseURL> [path ...]   (QA_OUT=screenshot dir)
import { chromium } from 'playwright';
const [base, ...paths] = process.argv.slice(2);
const routes = paths.length ? paths.map(p => new URL(p, base).href) : [base];
const out = process.env.QA_OUT || '.';
const browser = await chromium.launch();
const page = await browser.newPage();
const findings = [];
page.on('console', m => { if (m.type() === 'error') findings.push(`[console] ${page.url()} :: ${m.text()}`); });
page.on('pageerror', e => findings.push(`[exception] ${page.url()} :: ${e.message}`));
page.on('requestfailed', r => findings.push(`[netfail] ${r.url()} :: ${r.failure()?.errorText}`));
page.on('response', r => { if (r.status() >= 400) findings.push(`[http ${r.status()}] ${r.url()}`); });
for (const url of routes) {
  const res = await page.goto(url, { waitUntil: 'networkidle', timeout: 15000 })
    .catch(e => { findings.push(`[nav] ${url} :: ${e.message}`); return null; });
  if (!res) continue;
  const slug = new URL(url).pathname.replace(/\W+/g, '-').replace(/^-|-$/g, '') || 'home';
  await page.screenshot({ path: `${out}/${slug}.png`, fullPage: true });
  const body = (await page.textContent('body')) ?? '';
  if (!body.trim()) findings.push(`[blank] ${url} :: body rendered empty`);
  console.log(`VISITED ${url} -> ${slug}.png (status ${res.status()})`);
}
await browser.close();
console.log(findings.length ? findings.join('\n') : 'NO FINDINGS');
QA_OUT="$QA_OUT" node "$QA_OUT/qa-smoke.mjs" http://localhost:3000 / /pricing /dashboard

Per-route DOM asserts and interactions: extend a copy of the script for the specific change — e.g. await page.getByText('Saved!').waitFor({ timeout: 5000 }) after clicking submit, or page.getByRole('button', { name: 'Add' }).click() then re-screenshot. One throwaway script per flow is fine; they all live in $QA_OUT. For SPAs, click links in-page rather than only goto — client-side routing bugs don't show up on direct navigation. After every screenshot, Read the file so the user sees it inline.

Per-page checklist (T3; for T2 do steps 1, 5, and one item of 2)

  1. Loads — 2xx, no blank body, screenshot looks like a page, not an error.
  2. Interactive elements — click buttons/links/controls a user would use. Do they do what they say?
  3. Forms — fill and submit; try empty and one invalid input. Errors shown clearly?
  4. States — empty, loading, error, overflow (long text).
  5. Console + network — zero new JS errors or failed requests after interactions.
  6. Navigation — paths in and out work; browser back doesn't break the app.
  7. Responsive (if the change touched layout) — re-run at viewport: { width: 375, height: 812 }.
  8. Accessibility — interactive elements are keyboard-reachable (Tab order works); images have alt text.
  9. Performance — page is interactive under ~3s on the dev server; no single request over 2MB.
  10. Content — no lorem/placeholder text or broken images.

Spend depth where users spend time: homepage, dashboard, checkout, search — not the terms-of-service page.

Evidence tiers

Label every finding with how you know it:

  • Verified — reproduced twice; screenshot + console/network excerpt attached. Full weight in scoring.
  • Observed — seen once with evidence captured, not re-reproduced. Counts, note the uncertainty.
  • Assumed — inferred from the diff or a lone log line, never seen in the browser. List under "Unverified concerns", excluded from the health score.

Never report an issue with no evidence at all. Retry once before documenting so a fluke doesn't become a finding. Never put real credentials in the report — [REDACTED].

Prioritize by WTF-likelihood

Order testing and the report by how likely a real user is to hit the problem: first click on the homepage > a form everyone submits > a keyboard trap in a rarely opened modal. Self-regulate the same way: when the last several findings are all low-severity edge cases no user would plausibly hit, stop exploring — you're done, write the report. Depth over breadth: 5–10 well-evidenced issues beat 20 vague ones.

Health score

Severity (see per-finding deductions): critical = blocks a core workflow / data loss; high = major feature broken, no workaround; medium = works but noticeably wrong, workaround exists; low = cosmetic.

Each category starts at 100. Deduct per Verified/Observed finding: critical −25, high −15, medium −8, low −3 (floor 0). Console: 0 errors → 100, 1–3 → 70, 4–10 → 40, more → 10. Links: −15 per broken link.

CategoryWeightCategoryWeight
Functional20%Links10%
Console15%Visual10%
UX15%Performance10%
Accessibility15%Content5%

score = Σ (category_score × weight) — round to an integer out of 100.

Report

Markdown, written as you go (don't batch findings). Include: date, base URL, branch, tier, routes visited, evidence dir ($QA_OUT). Then per-route:

### Route: /pricing
- **[high · Verified] Plan selector does nothing on click**
  Evidence: $QA_OUT/pricing-after-click.png · console: `TypeError: plans is undefined (pricing.tsx:42)`
  Repro: load /pricing → click "Pro" → nothing happens, error in console.

End every report with — written for a non-expert reader, no jargon:

## Health score: NN/100

## Top 3 things a user would hit
1. **Plain-language sentence** describing what a user experiences, and where.
2. ...
3. ...

If nothing is broken, say so plainly: score, routes covered, "no user-facing issues found".

Report-only discipline

  • This skill finds; it does not fix. Do not edit source files, do not "quickly patch" anything, do not put suggested code in the report (naming the suspect area is fine).
  • Fixes go through the normal Build/Verify loop: diagnose with the debug skill, one commit per fix, add a regression test for each fix, then re-run browser-qa on the affected routes to confirm — before ship.
  • Test as a user, not a developer: reading source is for scoping routes only, never for judging "that probably works".
  • Keep all screenshots and scripts in $QA_OUT; never commit evidence into the repo.

Adapted from gstack (MIT, © Garry Tan); see ATTRIBUTION.md.

Download now (ZIP)

  • Other versions21 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 21

    1. loulanyue/awesome-claude-notes★ 272same name
    2. Fmarzochi/EGC★ 61same name
    3. woxiangyangzhimao/skills★ 14same name
    4. gongyijie85/dsh-ecc★ 8same name
    5. zero-click/zero-ratchet★ 8same name
    6. bhagyamudgal/skills★ 2same name
    7. angusfretwell/skills★ 1same name
    8. cskwork/browser-qa★ 1same name
    9. quokkify/skills★ 1same name
    10. Ronnasayd/aipp★ 1same name

    11 more not listed

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • Used alongsideProjects with it also use git-workflow.

    Other files people use alongside this one.

    Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
    • Microsoft AzureSkill

      git-workflow

      Squad branching model: dev-first workflow with insiders preview channel

      Also in 3 projects that use this

  • In this repository16 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.