DEV Community

Cover image for Is Playwright alone enough for agentic testing?
Arun Kumar T
Arun Kumar T

Posted on

Is Playwright alone enough for agentic testing?

More teams now let an AI agent test their web app: "test the checkout", "check the signup flow". The agent drives a browser through Playwright, clicks through the flow, and reports back: all tests passed.

The problem is how the agent decides that. It looks at the page. If the page shows the success message it expected, the test passes. But a page can show success while the app is broken underneath: the API returned a 500, the server rejected the request, or it stored nothing at all. The test passes, and the bug ships.

I wanted to measure how often that happens, and whether a testing layer could catch these bugs without the agent (or a human tester) writing extra assertions. The result is Vedha, an open-source testing framework and MCP server built on Playwright.

A broken feature that passes its test

Here is an order form with a seeded bug: the order API returns 500 and stores nothing, but the page still shows "Order placed". The same test, with the same check (wait for "Order placed"), is run twice:

Playwright passes, Vedha fails the step on a silent 500, and the server stored 0 orders

Playwright  PASS   "Order placed" is on the page
Vedha       FAILED declared checks passed, but the page reported: POST /api/orders returned 500
Server      0 orders stored
Enter fullscreen mode Exit fullscreen mode

You can run it yourself in about 3 seconds: npx tsx examples/demo/run.ts in the repo.

A careful tester would catch this in Playwright too, by asserting on the network response. Most tests don't, and agents almost never do.

What Vedha adds to Playwright

Vedha keeps what Playwright does best (auto-waiting, locators, the browser itself) and adds a verification layer to every test step:

  • Every step gets a result: verified, failed, outcome_unknown, unverified or blocked. Never a silent pass.
  • Actions that change data are checked. Mark a step as mutating and Vedha watches the requests it sent. A 5xx, a rejected request or a page error fails the step even when the on-screen check passed. Where the API follows REST conventions, it also reads the data back to confirm it was stored.
  • No duplicate side effects from retries. If a click times out mid-submit, Vedha won't click "Place order" again and create a second order. It reports outcome_unknown until a read-only check settles it.
  • Agent explorations become regression tests. A verified flow can be exported as a plain @playwright/test spec for CI.
  • Safe defaults for agents. The MCP server won't start without a domain allowlist, treats page text as untrusted data, and redacts secrets you pass to it.

The numbers, and their limits

Every number comes from raw trial files in the repo, and each held-out test set was written before any run on it.

AI agent testing (Playwright MCP vs Vedha MCP, same model, same held-out test tasks):

Playwright MCP Vedha MCP
Seeded bugs missed (sets 2-4) 26 9
Healthy flows passed (set 4) 18/18 17/18
Median tokens, healthy flows (set 4) 76,018 52,990 (-30%)
Median wall time, healthy flows (set 4) 169 s 176 s (+4%)

Scripted tests, no model:

  • With typical text/URL-only checks, Vedha caught 60 of 140 seeded bugs; every Playwright and Selenium baseline caught 0.
  • A 1,120-trial audit after the last change had 0 false passes and 0 false fails.
  • Median overhead: 1.05x hand-written Playwright.

The limits:

  • The AI-agent results come from one free model, at 3 trials per task. That's a pilot, not a verdict.
  • When an expert writes every check by hand, Vedha and Playwright tie. Vedha's lead is with typical checks and with agents.
  • Read-back needs a REST-style read endpoint: the same path, or its singular/plural sibling. GraphQL, separate read endpoints and filtered or per-user collections aren't covered.
  • Vedha passed one fewer healthy flow than Playwright MCP on set 4, and it uses more tool calls.

Try it

With Claude Code:

claude mcp add vedha -- npx -y @vedhajs/mcp --allow-domain localhost
Enter fullscreen mode Exit fullscreen mode

Then ask: "test the checkout flow on localhost:3000".

Any MCP client takes the same command (npx -y @vedhajs/mcp --allow-domain localhost). There is also an agent skill (npx skills add HMAKT99/VEDHA), a CLI for scripted tests (npm i -D @vedhajs/cli), and an SDK that wraps an existing Playwright page.

Repo, benchmarks and raw data: https://github.com/HMAKT99/VEDHA (Apache-2.0)

I'd most like to hear about real apps where it gets things wrong: a false failure on a healthy flow, or a bug it should have caught.

Top comments (6)

Collapse
 
alexshev profile image
Alex Shev •

Playwright is a strong execution layer, but agentic testing also needs an oracle: a way to decide what should be true after the agent acts. Stable fixtures, observable side effects, and assertions over business state keep browser automation from becoming a convincing demo with weak guarantees.

Collapse
 
arun_kumart_22e9a9959b10 profile image
Arun Kumar T •

@alexshev , Agreed, the oracle is the hard part. Vedha's take: each step declares what should be true afterwards (expect), and for steps that change data it also checks the side effects on its own (the requests sent, their status, and a read-back of the stored record where the API allows it). The agent doesn't have to remember to assert on business state for the obvious failures. It doesn't replace domain assertions, but it catches the "convincing demo" case where the UI says success and the backend didn't do it. How do you handle the oracle in your setup?

Collapse
 
alexshev profile image
Alex Shev •

I treat the oracle as a layered contract: UI state is only one signal. For any state-changing flow, the test asserts the response, a read-after-write via the narrowest trusted interface, and the expected audit/event record when one exists. The assertions are versioned with the workflow; when product semantics are unclear, the agent must surface a human review instead of inventing an oracle.

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

Tokenade, the tool I build, looks at agentic tests from the token side. Each step reloads the page and the transcript, and the price rises with the length of the run. A scripted test pays none of that.

Collapse
 
arun_kumart_22e9a9959b10 profile image
Arun Kumar T •

@paul_irolla_6b5ae261d0224 , Good point on cost. Two things in Vedha help there: observations are compact deltas instead of a full page snapshot each step (about 30% fewer tokens than Playwright MCP in the pilot), and once the agent has verified a flow, vedha_promote turns it into a plain Playwright test. From then on you pay the scripted price in CI, not the agent price.

Collapse
 
robertpaschal profile image
Odinaka Robert Nnamani •

The silent 500 example is the clearest part. Checking a mutating step against what it actually stored beats trusting the success message on the page.