Skip to content

Agent-driven browser verification means the coding agent executes a changed user flow in a real, isolated browser, checks it against written acceptance criteria, and records the actions, assertions, console errors, and network failures it saw. Critical flows then become deterministic Playwright tests in CI, because an agent’s browser run is evidence for one change, not a regression gate.

This page is for the developer whose agent now builds most of the frontend. Unit tests pass, the pull request says “verified in the browser”, and two days later someone finds that the Save button shows a success toast while the name never reaches the database. Nobody can say what the agent clicked, on which account, or whether it reloaded the page.

Scorecard Q16: How do you verify visual and end-to-end (E2E) browser functionality?

Max-score answer: the agent runs an acceptance-criteria browser flow, captures reproducible evidence, and promotes critical paths into deterministic CI tests.

What you’ll walk away with from agent browser verification

Section titled “What you’ll walk away with from agent browser verification”
  • A choice between Playwright MCP, Playwright CLI with its skill, and agent-browser, and when context cost should push you to a CLI
  • Setup for Claude Code, Codex, and Cursor that gives every agent an isolated, headless browser writing evidence to disk
  • A browser scenario format that the agent executes and cannot quietly reinterpret
  • Three copy-paste prompts: verify the flow, promote it into a Playwright test, and diagnose a failure
  • A way to prove the new test catches the bug without reading it line by line
  • The failure modes that turn browser checks into green theater, and how to recover from each

The organization-wide rule (which changes need which evidence, retention, protected tests) lives on the E2E policy page. Test-writing technique, such as page objects, authentication fixtures, and visual regression, lives on end-to-end test automation. This page is the developer’s loop between them.

The scorecard awards zero to three points. Each level adds a control, not a tool.

PointsYour answer todayThe next move
0No browser testing; manual clicking after deploymentWrite one browser scenario for the flow you changed last week and have the agent run it locally
1Manual click-through locally after the agent finishesGive the agent its own browser so the click-through happens, with evidence, before you look
2Playwright or Cypress suite run through terminal commandsTie each agent run to acceptance criteria and keep the evidence in the pull request
3Acceptance-criteria browser flow, reproducible evidence, critical paths promoted into deterministic CI testsKeep it honest: prove each new test fails without the fix, and protect it from silent edits

Which browser tool should the agent drive?

Section titled “Which browser tool should the agent drive?”

All three options below are deterministic drivers: the coding agent decides every click, and the tool reports what happened. Pick by how much context you can spend and by what your client supports.

ToolShapeBest forWatch out for
Playwright MCP (@playwright/mcp, Microsoft)MCP server over stdio; accessibility snapshots, screenshots optionalThe default for all three tools; console and network tools built inTool schemas and page snapshots consume context on every step
Playwright CLI (@playwright/cli, Microsoft)Shell commands plus an agent skillLong sessions where context matters; the Playwright MCP README itself suggests it for coding agentsNeeds a shell tool; the skill must be installed per workspace or globally
agent-browser (Vercel Labs)Rust CLI plus a thin skillFast QA passes with short element references (@e2)Short @eN refs and a thin skill keep context small, but it is a third tool to learn if your team already standardizes on Playwright

Claude Code and Codex also ship built-in browsers: Claude Code’s --chrome flag enables the Claude in Chrome integration (claude --help, v2.1.283), and Codex 0.157.1 ships browser_use and in_app_browser switched on (codex features list). Both drive a browser that can carry your own logged-in sessions. Use them to explore, and use an isolated browser for evidence you attach to a pull request.

For performance traces and Lighthouse audits, use Chrome DevTools MCP instead; the comparison is on browser MCP servers, and the MCP-versus-CLI trade-off is on Playwright MCP.

Connect an isolated browser to Claude Code, Codex, and Cursor

Section titled “Connect an isolated browser to Claude Code, Codex, and Cursor”

Run these in the repository root. The flags come from npx @playwright/mcp@0.0.83 --help: --isolated keeps the profile in memory, --headless needs no display, and --output-dir puts screenshots where the pull request can link them. A persistent profile serves one browser at a time, so parallel agents in separate worktrees need --isolated.

--scope project writes .mcp.json, so the team reviews and shares one pinned server.

Terminal window
claude mcp add --scope project playwright -- npx @playwright/mcp@0.0.83 \
--isolated --headless --output-dir .evidence/browser
claude mcp list # confirm the server connects

To use the CLI route instead, install it once and add its skill to the workspace. install --skills takes claude (the default) or agents, which writes to .agents/skills/.

Terminal window
npm install -g @playwright/cli@0.1.22 # checked with 0.1.22; not the deprecated unscoped "playwright-cli" package
playwright-cli install --skills claude # writes .claude/skills/playwright-cli/; or: --skills agents

Add .evidence/ to .gitignore; screenshots belong in CI artifacts or the pull request, not in history.

Run the changed flow from its acceptance criteria

Section titled “Run the changed flow from its acceptance criteria”

The agent verifies only what you wrote down. A vague criterion such as “settings work” lets it declare success after opening the page. Write the scenario before the agent starts building, next to the rest of the spec.

  1. Add a browser scenario to spec.md. Name the starting state, the actions, the observable outcome, and the evidence you expect:

    Scenario: an authenticated user renames the workspace
    Given: a disposable local account "qa+rename@example.test" with workspace "Acme"
    When: the user opens /settings, enters "Northstar" in "Workspace name", and clicks Save
    Then: a "Saved" status appears, and "Northstar" is still shown after a full reload
    Evidence: numbered actions, accessibility snapshot after reload, screenshot,
    console errors, status of the save request
  2. Seed a clean local or test environment. Never point an unattended browser agent at production data, real payments, or third-party accounts.

  3. Ask the agent to execute the scenario exactly, with the first prompt below. It returns PASS, FAIL, or BLOCKED and an evidence block.

  4. If the result is FAIL, switch to diagnosis with the third prompt. Do not let the same run edit code.

  5. If the flow is business-critical (sign-in, checkout, permissions, destructive actions), promote it into a Playwright test with the second prompt.

A good result reads like this, and it goes into the pull request unchanged:

Browser verification: PASS
Environment: local dev server, fresh seed
Actions: 1 open /settings · 2 fill "Workspace name" = "Northstar" · 3 click Save · 4 reload
Then: "Saved" status seen after step 3 · "Northstar" in the field after step 4
Console/network: no errors · PATCH /api/workspace 200
Files: .evidence/browser/settings-after-reload.png

Promote a stable flow into a Playwright test

Section titled “Promote a stable flow into a Playwright test”

An agent’s browser run proves the change once, on one machine. Critical flows need a test that runs on every later change, including changes made by agents that never read this scenario. Keep the test small and assert the outcome the user cares about, not the implementation:

tests/e2e/settings-rename.spec.ts
import { test, expect } from '@playwright/test';
test('workspace rename persists after reload', async ({ page }) => {
await page.goto('/settings');
await page.getByLabel('Workspace name').fill('Northstar');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('status')).toHaveText(/saved/i);
await page.reload();
await expect(page.getByLabel('Workspace name')).toHaveValue('Northstar');
});

Playwright also ships Test Agents: a planner, a generator, and a healer. npx playwright init-agents --loop=claude (with @playwright/test 1.63.0) writes three subagents to .claude/agents/, a playwright-test server entry to .mcp.json, a seed.spec.ts, and a specs/ folder for plans. --loop=codex writes the agents to .codex/agents/ instead. Version 1.63.0 has no Cursor loop (the choices are claude, codex, copilot, opencode, vscode, and vscode-legacy), so in Cursor use the MCP server above with the same prompts.

How do you know the browser check proved anything without watching it?

Section titled “How do you know the browser check proved anything without watching it?”

You do not need to read the agent’s transcript or every line of the test. You need four machine-checkable facts.

  1. The test fails without the change. Commit the change, check out the base branch in a separate worktree, run the new test there, and confirm it goes red; your own checkout stays untouched. A test that passes on the old code does not protect the flow. Oracle strength covers this check in depth.
  2. The test is stable. --repeat-each=5 --retries=0 passes five out of five. In CI, add --fail-on-flaky-tests so a retry can never turn a flaky test green.
  3. The evidence traces to a criterion. Every “Then” clause in the evidence block has an observation next to it, and the file paths exist in the CI artifacts.
  4. CI runs the test where the agent cannot edit it. The Playwright job runs on every pull request, and changes under tests/e2e/ need a named reviewer through CODEOWNERS.

Sign-off stays with people and CI: the CI job is the merge gate, and the reviewer checks the evidence block and the red-then-green proof instead of replaying the flow by hand. The full pull request contract is the evidence bundle.

What breaks in agent-driven browser verification?

Section titled “What breaks in agent-driven browser verification?”
FailureWhat you seeRecovery
Green theaterPASS after opening the page, or a screenshot with no actions listedReject evidence without numbered actions and one observation per “Then” clause; the first prompt enforces this
Toast-only assertionThe success message appears, but the data never persistedAdd a reload or a second page to the scenario and assert the value there
Shared browser profileParallel agents fail to launch the browser, or one agent sees another’s loginStart every server with --isolated, or give each worktree its own --user-data-dir
Wrong dev serverThe run passes against another worktree’s server on the default portPin each worktree’s port and have the prompt state the exact URL it must open
Healer weakens the testA red test turns green after an expect change or a test.fixme()Require review for any diff that touches assertions under tests/e2e/; rerun the red-then-green prompt
Flaky locator or timingPasses three times, fails in CIReplace CSS selectors and sleeps with role locators and web-first assertions; run --repeat-each before merge
Context exhaustionLong sessions slow down or lose earlier instructionsSwitch long flows to Playwright CLI, or split them into one scenario per session
Untrusted page contentText on a page tells the agent to do something outside the scenarioTest only local or disposable environments; --allowed-origins narrows requests, but its own help says it “does not serve as a security boundary”

Where to go next with browser verification

Section titled “Where to go next with browser verification”

Frequently asked questions

How does agent-driven browser verification work before merge?

The coding agent executes the changed user flow in a real, isolated browser against written acceptance criteria and records actions, assertions, console errors, and network failures as reproducible evidence.

Does an agent browser run replace deterministic Playwright tests in CI?

No, an agent browser run is evidence for a single change, whereas critical user flows must be promoted into deterministic Playwright tests in CI to serve as a standing regression gate.