agentleFS
pfangueiropfangueiro/claude-code-agents/.claude/skills/browser-testing/SKILL.md

browser-testing

Skill7 starsChanged 19 days agoMITView on GitHub

Hand-driven end-to-end browser testing through the Playwright MCP server — navigating pages, filling forms, asserting HTTP responses, capturing screenshots for visual regression, checking responsive breakpoints and cross-browser behaviour, and recording codegen sessions. Use when a browser genuinely has to be driven interactively and no runnable suite covers the need — authoring e2e, screenshot, or visual-verification coverage where none exists, debugging a failure a suite already surfaced, or exploring a live page. It does not cover running a repository's existing suite. When the repo has a playwright.config file, a tests or e2e directory, or a test:e2e script, running that suite is the correct action and this skill is not required.

11 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use receiving-code-review.

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.
  • CloudflareSkill

    receiving-code-review

    Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation

    Also in 3 projects that use this

The file

We split this skill into the rules it gives an agent

7 rules. 0 are common, 3 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 11 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not re-implement an existing test by hand, and never present a hand-driven MCP walkthrough as equivalent to a suite run — if the suite …

    line 18
  2. Distinctive:

    Run the repo's existing Playwright suite before hand-driving MCP tools (see the gate at the top)

    line 173
  3. Very specific:

    Always mcp__playwright__playwright_close when done — releases browser resources

    line 174
  4. Very specific:

    Use selector option on screenshots to capture specific components

    line 175
  5. Very specific:

    Use mcp__playwright__playwright_console_logs with type: "error" after interactions to catch JS errors

    line 177
  6. Very specific:

    Always pass value to mcp__playwright__playwright_assert_response — without it, a 401/500 passes

    line 179
  7. Distinctive:

    Use device presets for accurate mobile/tablet testing (includes user-agent + touch emulation)

    line 180

“Common” is measured: kept by at least 6 in 10 of the 11 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 Testing with Playwright MCP

Comprehensive patterns for end-to-end browser testing, visual regression, and responsive design verification using the Playwright MCP server.

First: prefer the repo's own test suite

This skill is for hand-driving a browser when no runnable suite covers the need. It deliberately does NOT claim the bare word "Playwright" — running an existing suite is the correct action. Before hand-driving any MCP tool, check for one:

  • playwright.config.{ts,js,mjs}, a tests/ / e2e/ directory, or a test:e2e / playwright script in package.json.

If a suite exists, run it (the repo's script, or npx playwright test) and report its actual result. A suite is reproducible, runs in CI, and asserts far more than a hand-driven MCP session can. Use the MCP tools below only to (a) debug a failure the suite surfaced, (b) explore a page interactively, or (c) build coverage where no suite exists.

Do not re-implement an existing test by hand, and never present a hand-driven MCP walkthrough as equivalent to a suite run — if the suite was not run, say so.

Available Playwright MCP Tools

Names below are the full MCP tool names, as invoked.

Navigation & State

  • mcp__playwright__playwright_navigate — Open a URL (set browserType, width, height, headless)
  • mcp__playwright__playwright_go_back / mcp__playwright__playwright_go_forward — History navigation
  • mcp__playwright__playwright_resize — Change viewport (manual or 143+ device presets: iPhone 13, iPad Pro, Galaxy S24, etc.)

Interaction

  • mcp__playwright__playwright_click — Click an element (CSS selector)
  • mcp__playwright__playwright_fill — Fill an input field
  • mcp__playwright__playwright_select — Select dropdown value
  • mcp__playwright__playwright_hover — Hover over element
  • mcp__playwright__playwright_drag — Drag element to target
  • mcp__playwright__playwright_press_key — Press keyboard key
  • mcp__playwright__playwright_upload_file — Upload file to input

Inspection

  • mcp__playwright__playwright_screenshot — Capture page or element screenshot (with fullPage, selector, savePng, downloadsDir)
  • mcp__playwright__playwright_get_visible_text — Get all visible text on page
  • mcp__playwright__playwright_get_visible_html — Get HTML (options: cleanHtml, minify, removeScripts, selector)
  • mcp__playwright__playwright_console_logs — Retrieve browser console logs (filter by type: error, warning, etc.)
  • mcp__playwright__playwright_evaluate — Execute arbitrary JavaScript in browser

HTTP API Testing

  • mcp__playwright__playwright_get / mcp__playwright__playwright_post / mcp__playwright__playwright_put / mcp__playwright__playwright_patch / mcp__playwright__playwright_delete — Direct HTTP operations with auth headers

Code Generation

These four are the only tools with no playwright_ infix — the name is mcp__playwright__start_codegen_session, not ..._playwright_start_codegen_session.

  • mcp__playwright__start_codegen_session — Begin recording interactions as Playwright test code (requires options.outputPath)
  • mcp__playwright__end_codegen_session — Generate the test file from recorded actions (requires sessionId)
  • mcp__playwright__get_codegen_session — Check session status (requires sessionId)
  • mcp__playwright__clear_codegen_session — Discard without generating (requires sessionId)

Response Validation

  • mcp__playwright__playwright_expect_response — Start waiting for an HTTP response. Required: id (an arbitrary handle you choose) and url (pattern). Registers the wait; does not block.
  • mcp__playwright__playwright_assert_response — Await that response. Required: id. Optional: value — a substring that must appear in the JSON body.

Neither tool can assert an HTTP status code — there is no status parameter. Two consequences, both fail-closed:

  • Never call assert_response with only an id. With no value, the server reports success for any response it received: a 401, 403 or 500 comes back as "Response assertion ... successful" with the status merely printed in the message, not checked. A failed login then reads as a green E2E. Always pass value.
  • value must be a substring that appears ONLY on success (a token field name, the user id, "status":"ok"). A string that also occurs in the error body proves nothing. If no success-only substring exists, this tool cannot verify the call — assert the outcome another way (e.g. mcp__playwright__playwright_get_visible_text for an element that renders only when authenticated) and report the response as not verified rather than as a pass.

value is matched as a plain substring against JSON.stringify(body), and the body is parsed as JSON — a non-JSON response makes the assertion error out.

Patterns

E2E Test: User Journey

1. mcp__playwright__playwright_navigate → target URL
2. mcp__playwright__playwright_fill → username/password fields
3. mcp__playwright__playwright_expect_response → id: "auth", url: "**/api/auth**"
   (MUST precede the click — the wait is registered here; a response that
    fires before this call is never seen)
4. mcp__playwright__playwright_click → submit button
5. mcp__playwright__playwright_assert_response → id: "auth", value: "\"authenticated\":true"
   (`value` is mandatory — with only `id`, a 401 is reported as success)
6. mcp__playwright__playwright_screenshot → capture authenticated state
7. mcp__playwright__playwright_get_visible_text → verify welcome message

Replace "\"authenticated\":true" with whatever substring your auth endpoint returns only on success.

Visual Regression: Screenshot Comparison

The Playwright MCP server has no image comparator — no baseline store, no diff, no threshold. mcp__playwright__playwright_screenshot only captures. The comparison step must be an external tool, or the comparison is not happening.

1. mcp__playwright__playwright_resize → pin an exact viewport (both runs must match)
2. mcp__playwright__playwright_navigate → target page
3. mcp__playwright__playwright_screenshot → name: "homepage", savePng: true,
     downloadsDir: "<repo>/.screenshots/baseline"
4. [Make code changes]
5. mcp__playwright__playwright_navigate → same page (fresh load)
6. mcp__playwright__playwright_screenshot → name: "homepage", savePng: true,
     downloadsDir: "<repo>/.screenshots/current"
7. Compare — but assert the dimensions FIRST (see the size-mismatch rule below):
     B=.screenshots/baseline/homepage.png; C=.screenshots/current/homepage.png
     db=$(magick identify -format '%wx%h' "$B") ; dc=$(magick identify -format '%wx%h' "$C")
     [ -n "$db" ] && [ -n "$dc" ] || { echo "FAIL: cannot read dimensions"; exit 1; }
     [ "$db" = "$dc" ] || { echo "FAIL: size mismatch $db vs $dc — comparison invalid"; exit 1; }
     compare -metric AE "$B" "$C" diff.png     # differing-pixel count; needs ImageMagick
   NOTE the filenames: mcp__playwright__playwright_screenshot may write `<name>-<timestamp>.png` rather than
   `<name>.png`. Resolve the actual path (e.g. `ls -t .screenshots/current/homepage*.png | head -1`)
   instead of assuming — a comparator pointed at a path that does not exist must FAIL, not pass.

Fail-closed rules:

  • Decide the pass threshold before running. "Looks fine" is not a threshold.
  • A missing baseline is a FAIL, not a pass. Recording a first baseline is a separate, deliberate step — never let "nothing to compare against" report green.
  • Pin the viewport and use the same fullPage value for both captures, and assert the two images have identical dimensions before comparing. Do not rely on the comparator to notice. Measured on ImageMagick 7.1.2-21: compare -metric AE on a 200×200 vs a 100×100 image returns 0 (0) with exit 0 — a perfect pass — while a genuine same-size regression returns 2601 (0.065) with exit 1. A size mismatch is therefore the cleanest possible green, which is the opposite of erroring out. Compare magick identify -format '%wx%h' on both files and FAIL on any difference. (Earlier revisions of this file asserted the mismatch "makes the comparator error out"; that was wrong, and it was wrong in the direction that hides regressions.)
  • A comparator that did not run, is not installed, or errored is a FAIL. Report "not verified" — never downgrade it to a pass.
  • Never report a visual-regression pass from eyeballing two screenshots. Model inspection of two PNGs is not a diff; if no comparator ran, the honest result is "not verified".

Responsive Design Testing

1. mcp__playwright__playwright_navigate → target page
2. mcp__playwright__playwright_resize → device: "iPhone 13" (375x812)
3. mcp__playwright__playwright_screenshot → name: "mobile"
4. mcp__playwright__playwright_resize → device: "iPad Pro 11" (834x1194)
5. mcp__playwright__playwright_screenshot → name: "tablet"
6. mcp__playwright__playwright_resize → width: 1920, height: 1080
7. mcp__playwright__playwright_screenshot → name: "desktop"

Form Validation Testing

1. mcp__playwright__playwright_navigate → form page
2. mcp__playwright__playwright_fill → invalid email
3. mcp__playwright__playwright_click → submit
4. mcp__playwright__playwright_get_visible_text → check for error messages
5. mcp__playwright__playwright_console_logs → type: "error" (check for JS errors)
6. mcp__playwright__playwright_fill → valid data
7. mcp__playwright__playwright_expect_response → id: "submit", url: "**/api/submit**"
   (register the wait BEFORE the click that triggers it)
8. mcp__playwright__playwright_click → submit
9. mcp__playwright__playwright_assert_response → id: "submit", value: "\"created\":true"
   (success-only substring; omitting `value` would pass on a 422 validation error)

Codegen: Record Test from Manual Actions

1. mcp__playwright__start_codegen_session → options: { outputPath: "/tests/e2e/" }
2. mcp__playwright__playwright_navigate → target URL
3. mcp__playwright__playwright_click → interact with elements
4. mcp__playwright__playwright_fill → fill forms
5. mcp__playwright__end_codegen_session → sessionId from step 1; writes the test file to outputPath

Cross-Browser Testing

1. mcp__playwright__playwright_navigate → url, browserType: "chromium"
2. mcp__playwright__playwright_screenshot → name: "chrome-result"
3. mcp__playwright__playwright_close
4. mcp__playwright__playwright_navigate → url, browserType: "firefox"
5. mcp__playwright__playwright_screenshot → name: "firefox-result"
6. mcp__playwright__playwright_close
7. mcp__playwright__playwright_navigate → url, browserType: "webkit"
8. mcp__playwright__playwright_screenshot → name: "safari-result"

Best Practices

  • Run the repo's existing Playwright suite before hand-driving MCP tools (see the gate at the top)
  • Always mcp__playwright__playwright_close when done — releases browser resources
  • Use selector option on screenshots to capture specific components
  • Set headless: true for CI/automated runs, false for debugging
  • Use mcp__playwright__playwright_console_logs with type: "error" after interactions to catch JS errors
  • Register mcp__playwright__playwright_expect_response BEFORE the action that triggers the request
  • Always pass value to mcp__playwright__playwright_assert_response — without it, a 401/500 passes
  • Use device presets for accurate mobile/tablet testing (includes user-agent + touch emulation)
  • For iframes, use mcp__playwright__playwright_iframe_click and mcp__playwright__playwright_iframe_fill

When to Use

  • After implementing UI changes — verify visual correctness
  • During investigate — reproduce UI bugs with exact browser state
  • For accessibility — check WCAG compliance with visual + text inspection
  • For API testing — use HTTP tools for direct endpoint verification
  • For regression — screenshot before/after code changes

Related

  • test-automation agent — generates test suites (uses Playwright for E2E)
  • frontend-specialist agent — implements UI components (uses Playwright for verification)
  • investigate skill — Phase 2 (REPRODUCE) uses Playwright for UI bug reproduction

Download now (ZIP)

Does it work?

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

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

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.