Browser QA — Automated Visual Testing & Interaction
Automate visual testing and UI verification by driving a real browser through whatever browser-automation MCP is available. Adapted from the ECC browser-qa skill, extended with an MCP preflight so it never assumes a browser tool is already wired up.
When to use
- After deploying a feature to staging/preview, or before a release
- To verify UI behavior, layouts, forms, and interactions across pages
- When reviewing PRs that touch frontend code
- For responsive checks, accessibility audits, or performance/Core Web Vitals
- Any time a task needs to see and act on a rendered page rather than read source
Phase 0 — Preflight: confirm a browser MCP is available
Do this first, every time, before any navigation or testing. The skill is portable across clients (Claude Code, Claude Desktop, claude.ai, Cursor, VS Code, Windsurf, etc.), so don't assume a specific tool — detect what's actually present.
0.1 Detect connected browser MCPs
Inspect the tools available in the current session for browser-automation capability. Match by tool-name fingerprint (names vary by client and may be namespaced, e.g. mcp__playwright__...):
| | | |
|---|
Playwright MCP (Microsoft, official) | | browser_navigate, browser_snapshot, browser_click, browser_take_screenshot, browser_resize
| Deterministic E2E / regression, cross-browser (Chromium/Firefox/WebKit), token-efficient a11y snapshots |
chrome-devtools-mcp (Google, official) | | navigate_page, take_snapshot, list_console_messages, list_network_requests, performance_start_trace
| Live debugging, network inspection, Core Web Vitals / perf traces, attaching to a real logged-in Chrome |
| @modelcontextprotocol/server-puppeteer
| puppeteer_navigate, puppeteer_screenshot, puppeteer_evaluate
| Lightweight Chromium-only scraping/screenshots |
Claude in Chrome (Anthropic) | browser extension / connector | navigate, read_page, find, get_page_text, computer
| Driving your actual Chrome with your real sessions/extensions |
| cloud (account + API key) | browserbase_* / multi_browserbase_*
| Cloud/CI runs with no local browser |
| | browser_use_* / agent-style task tools
| High-level autonomous flows from natural-language goals |
If you see browser-capable tools that don't match any row above, treat them as a candidate anyway and check "Staying current" below.
0.2 If one or more browser MCPs are available → surface the choice (never auto-pick)
Always let the user decide which tool to use — do not silently select one.
- Exactly one available → name it and confirm: "You have
<mcp> connected — want me to run the QA with it, or set up a different one?"
- Several available → list them with a one-line "best at" each (from the table) and ask which to use for this run.
Only proceed once the user has chosen.
0.3 If no browser MCP is available → present options and ask the user to install one
Don't try to QA without a browser tool, and don't install it silently — installing/registering an MCP is a config change the user runs themselves. Present the options, recommend a fit for their task, and ask them to install one, then resume once it's connected.
Pick the recommendation from the task: regression/E2E → Playwright; perf/CWV or "debug my real session" → chrome-devtools-mcp; quick Chromium screenshots → Puppeteer; cloud/CI → Browserbase.
Install commands (give the row that matches the user's client):
Playwright MCP — @playwright/mcp (download browsers once with npx playwright install):
Note: a community package @executeautomation/playwright-mcp-server also shows up in searches — it's a different project with a different API. The official one is @playwright/mcp.
chrome-devtools-mcp — chrome-devtools-mcp (Chrome/Chrome-for-Testing only):
Useful flags: --isolated (temp profile, cleared on exit), --autoConnect (Chrome M144+, attach to your running Chrome and keep logins/cookies/extensions), --no-usage-statistics (opt out of telemetry). It exposes browser content to the client — see Safety & scope below.
Puppeteer MCP — @modelcontextprotocol/server-puppeteer:
Claude in Chrome, Browserbase, browser-use — not npx one-liners. Point the user to the right setup: Claude in Chrome via the Anthropic browser extension/connector; Browserbase via a Browserbase account + API key (see their docs for the current MCP package); browser-use via the browser-use project docs. On claude.ai / Claude Desktop, MCPs are added through the Connectors / Settings UI rather than the CLI, so direct the user there.
After the user installs, have them reload/restart the client (and run /mcp in Claude Code to confirm), then continue from Phase 1.
Staying current
This list reflects the landscape as of 2026 and the ecosystem moves fast. If the available tools don't match the table, or the user asks for an option not listed, search the web before answering — e.g. "browser automation MCP server 2026", "<tool> MCP install <client>", "<tool> MCP tools list" — and verify the package name and install command from the official repo or npm before recommending it. Prefer official/first-party servers over community forks.
Safety & scope
- Prefer a staging/preview/local target, or a dedicated test profile — avoid running destructive interactions against production.
- Never enter real production credentials, payment details, or other sensitive data into forms. For auth flows, have the user log in themselves (visible-browser MCPs make this easy) and continue from the authenticated state.
- Respect CAPTCHAs and bot-detection — don't try to bypass them.
- Get explicit confirmation before any irreversible action (real form submissions, purchases, posting, deleting). Smoke/visual/read-only checks need no confirmation.
- chrome-devtools-mcp and Claude-in-Chrome expose your live browser to the client; if you're logged into anything sensitive, use a separate Chrome profile or
--isolated.
Phase 1: Smoke test
- Navigate to the target URL.
- Collect console messages; filter known noise (analytics, third-party widgets) and flag real errors.
- Check network requests for any 4xx/5xx.
- Screenshot above-the-fold at desktop and mobile widths.
- Capture Core Web Vitals where the MCP supports it (LCP < 2.5s, CLS < 0.1, INP < 200ms). This is most reliable via chrome-devtools-mcp's performance trace; with Playwright/Puppeteer, note that the figures are approximate or skip them.
Phase 2: Interaction test
- Click every nav link — verify none are dead.
- Submit forms with valid data — verify the success state.
- Submit forms with invalid data — verify the error state shows.
- Test the auth flow: login → protected page → logout.
- Walk the critical user journeys (checkout, onboarding, search) for this app.
Phase 3: Visual regression
- Screenshot key pages at three breakpoints: 375px, 768px, 1440px.
- Compare against stored baselines if any exist.
- Flag layout shifts > 5px, missing elements, and overflow.
- Check dark mode if the app has it.
Phase 4: Accessibility
- Run axe-core (or the MCP's a11y check / inject axe via a script step) on each page.
- Flag WCAG AA violations (contrast, missing labels, focus order).
- Verify keyboard navigation works end-to-end.
- Check landmark/region structure for screen readers.
Output format
ALWAYS report using this template:
Capability → tool mapping (portable reference)
The phases describe capabilities, not one tool's function names. Map them to whichever MCP the user chose:
- navigate →
browser_navigate / navigate_page / puppeteer_navigate / navigate
- snapshot / read DOM →
browser_snapshot / take_snapshot / read_page / get_page_text
- screenshot →
browser_take_screenshot / puppeteer_screenshot
- console →
list_console_messages (chrome-devtools); else read via a JS evaluate step
- network →
list_network_requests (chrome-devtools); else inspect via the client's network tools
- resize / device emulation →
browser_resize / viewport options
- run JS (inject axe, read CWV) →
browser_evaluate / puppeteer_evaluate / evaluate
If a chosen tool lacks a capability (e.g. Puppeteer has no native a11y/perf), say so in the report rather than silently skipping, and suggest the tool that does (usually chrome-devtools-mcp for console/network/perf).