Skip to content
Back to skills

Browser Qa

ASecurity

Live browser QA + Playwright-compatible replay. Disk .agents/qa/. Use when (terminal Lane Stack): проверь в браузере, кликни сценарий, вёрстка 375, screenshot QA. SKIP: Lane Pilot chats (PM calls `lane_pilot_browser_qa`); DESIGN.md taste (design-lead); product Vue/CSS (writer lane); L0/L1 unit/API (lane-contract).

  • 121 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 20, 2026
ai-agentsgobashvuegitapibackend

Works with

  • terminal
  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add VKirill/claude-lane-stack --skill browser-qa --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Browser Qa?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Browser Qa
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/vkirill-browser-qa/badge)](https://www.skillsdirectory.com/skills/vkirill-browser-qa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: browser-qa
description: "Live browser QA + Playwright-compatible replay. Disk .agents/qa/. Use when (terminal Lane Stack): проверь в браузере, кликни сценарий, вёрстка 375, screenshot QA. SKIP: Lane Pilot chats (PM calls `lane_pilot_browser_qa`); DESIGN.md taste (design-lead); product Vue/CSS (writer lane); L0/L1 unit/API (lane-contract)."
argument-hint: "[info]"
---

# Browser QA

Adapted from [lee-to/ai-factory#154](https://github.com/lee-to/ai-factory/pull/154)
replay rules. Paths and gates are lane-stack. No `.ai-factory`, no human
«работает или нет».

> **Inside a Lane Pilot chat** (`LANE_PILOT_AGENT_TYPE` set / tools `lane_pilot_*` present) do not run this file's replay and digest procedure. The PM checks an accepted task with `lane_pilot_browser_qa`; the check runs in a child thread through `bb browser-automation` (no MCP browser) and ends with the one fenced JSON verdict its prompt asks for, changing no files. `.agents/qa/` replay, `qa-digest`, `chrome-qa`, `browser-qa-jev` and `chrome-devtools` below are the terminal harness. The PM does not click in its own chat.

## Info

If `$ARGUMENTS` is exactly `info`, print `references/info.md` verbatim (Russian), then stop.

## Layout

```text
.agents/qa/context.md          # cross-run, non-secret
.agents/qa/<slug>/
  cases.md                     # source of truth for TC-*
  REPORT.md                    # execution only; never overwrite cases
  shots/
  replay/TC-00N.js
  replay/history/
```

Copy structure from `references/` next to this skill. English on disk.
Chat may be Russian. Redact tokens, cookies, OTP, `password`, `jwt` → `[REDACTED]`.

## Cases

PM / SPEC acceptance → `cases.md`. One `## TC-00N` heading per case (see
`references/cases.md`). Fields: Surface, Priority, Viewport, Preconditions,
Steps, Expected.

| Surface | This agent |
|---------|------------|
| `browser-ui` | Required. Live browser. Replay first. |
| `cli` / `backend-test` / `api` | Do not click. Note `blocked: use L0/L1`. No human array-checking. |
| `human` | Leave pending. The PM asks the operator. |

Default viewports if omitted: `375` `768` `1280`.

## Bindings

```bash
qa-digest cases .agents/qa/<slug>/cases.md
qa-digest script .agents/qa/<slug>/replay/TC-001.js
qa-digest target local 'http://127.0.0.1:5173/'
git -C . rev-parse HEAD
```

`tree` is `clean` if `git status --porcelain` has nothing **except** `.agents/qa/`;
else `dirty`.

`target_fingerprint` input is `QA TARGET\n<class>\n<normalized_base_url>\n`.
Normalize: drop userinfo, query, fragment; keep scheme/host/port/base path;
strip trailing slash except origin `/`. Class:
`local` | `staging` | `preview` | `production` | `unknown`.

Matching replay = embedded `case_digest` + embedded `target_fingerprint` +
file `script_digest` all equal REPORT's last **proven** values.

Stale (uncheck, keep old evidence, do not count as current):

- HEAD or `tree` changed → all results stale; **scripts stay reusable** if matching
- `cases.md` `source_digest` changed → stale only cases whose `case_digest` changed
- new TC → pending; removed TC → Stale / removed
- script bytes ≠ recorded script digest → that case stale, needs proof run
- missing digest metadata → unproven, not matching

## Replay (PR #154)

One case → `replay/TC-00N.js`. Smallest `async (page) => { … }`. No imports,
no new npm deps. Navigation uses the literal `"BASE_URL"` placeholder. At run
time substitute `normalized_base_url` **in memory**; do not rewrite the file
just to inject the host.

```js
// case_digest: <from qa-digest cases>
// target_fingerprint: <from qa-digest target>
async (page) => { /* goto("BASE_URL"+"/…"); asserts throw */ };
```

1. Write the script **before** the first click. That first execution is the proof. Do not auto-run a new/updated script a second time.
2. If mechanics were clarified after the observed run and the file changed, mark `unproven`. Repeat only after preconditions restored. Stateful (submit, pay, delete, email, permissions) needs a fresh go-ahead that says this is a **repeat**.
3. Record `script_digest` as proven only after **that exact file** executed. Until then: `n/a`, proof `unproven`.
4. Before repair/rebind: `cp` to `replay/history/TC-00N-<old_script_digest>.js`. Keep the first error in REPORT. Never run history.
5. Missing selector = **product fail** until the same control and behavior are proven in-browser and only the locator changed. Do not pick a similar element. Syntax/runner errors may be repaired (new proof). Assertion mismatch = fail, not a reason to regenerate the script.
6. Target mismatch → stop. Rebind changes `script_digest` and needs a new proof. Never treat a staging script as matching localhost.
7. After HEAD/`tree` change: replay every **matching** script (old pass and fail). Capability and side-effect rules still apply.
8. `proven` means the script ran, not that the product passed.
9. Discrete chrome-devtools actions: treat the file as the program; do not rewrite steps because the surface is MCP not `npx playwright`.
10. After replay, at most one bounded exploratory pass when the change is cross-cutting (nav, auth, layout, shared state) or a replay needed repair. Skip when the fix is narrow and matching replay already covers it. New bug → REPORT only; add `## TC-00N` first, then a script.

## Delegation (`stages.browser_qa`)

| provider | Who clicks | Command |
|----------|------------|---------|
| `jev` (default) | CDP snapshot → Jev Choice (click/type/done). `backend` = `chrome-qa` \| `live-chrome` \| `headless` | `browser-qa-jev --project-cwd . --url … --slug … --case "…"` |
| `codex` | Codex `gpt-6-astra` / `low` + browser plugins | `browser-qa-codex --project-cwd . --url … --slug … --case "…"` |
| `claude` | this agent via `chrome-devtools` MCP | steps below |

`browser-qa-jev` writes `cases.md`, `REPORT.md`, `shots/`, `jev-run.json`.
`browser-qa-codex` writes `codex-run.json` / `codex-result.json`. Replay scripts
are not produced in jev/codex mode; receipt + shots are the proof.

## Preflight

1. Read `.agents/qa/context.md` if present (routes, how to start the app, test-user **role**). No secrets.
2. Live browser: host-level `chrome-devtools` MCP (`mcp__chrome-devtools__*`: `list_pages`, `new_page`, `navigate_page`, `take_snapshot`, `take_screenshot`), else MetaMCP `chrome-devtools`, else existing project Playwright. If the MCP reports no browser, run `chrome-qa start` (dedicated profile, fixed port, no consent dialog) and retry once. No new dependency. None → every `browser-ui` case `blocked`. Do not write `pass`. WebFetch is not a browser.
   **Attached to the user's real Chrome** (macOS `--autoConnect`, or `--browserUrl`): the server exposes every open tab. Create your own page with `new_page`, act only in pages you created, never snapshot, navigate or close other tabs, close yours when done, and prefer a dedicated QA profile for sensitive sites.
3. `production` or `unknown`, or any side-effect case: do not run until the PM wrote `authorized` in the spawn prompt. Deny → `blocked`.
4. Auth: reuse a safe local fixture from context/docs. Never store prod/personal passwords, cookies, OTP. Disposable local users only if the repo already has a seed command.

## Run

1. `cd` project root. Slug from PM or `qa-<YYYYMMDD-HHMM>`.
2. Write or refresh `cases.md` from SPEC/acceptance. Do not invent URLs.
3. `qa-digest cases` + `qa-digest target`. If REPORT exists, apply stale rules before changing statuses.
4. Create REPORT from `references/REPORT.md` when missing. All new cases start pending.
5. Each `browser-ui` case: matching replay first; else write script, run once, shots `shots/TC-00N-<w>.png`.
6. Supporting L0/L1 commands may be listed; they do not count as extra TC results.
7. Last line to PM: `DONE .agents/qa/<slug>/REPORT.md` plus fail list and 3–5 shots.

## NEVER (each with its alternative)

- Product Vue/TS/CSS and `docs/DESIGN.md` are not yours: report the defect in REPORT and leave the file.
- A `browser-ui` case is `pass` only after a live browser run of that case; without a live browser it is `blocked`.
- Work only in cases from `cases.md`; for anything else add a `## TC-00N` first. This is the Playwright-replay harness, so no Human mode, `.ai-factory` or `/aif-qa`.
- Credentials stay out of files, and the preview host stays out of scripts (`BASE_URL` placeholder).
- Cleanup is read-only for shared state: no `rm`, `git reset` or shared DB wipe.

Files in this skill

  • SKILL.md8.3 KB
  • references/REPORT.md1.1 KB
  • references/TC.js402 B
  • references/cases.md379 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…