← Blog·ENGINEERINGFeb 20, 2026·11 min read

We Built an MCP Server on Playwright. Here's Why It's Not "Just Another Wrapper."

Playwright MCP gives you a browser remote control. We built an entire testing platform on top of it — with self-healing selectors, AI test generation, and org-wide pattern learning.

Let me save you 20 minutes of reading the Playwright MCP docs: it gives you a browser you can talk to through MCP. Navigate, click, fill, screenshot. That's it. That's the whole thing.

And honestly? For some use cases, that's enough. If you just need an LLM to poke around a web page and report what it sees, Playwright MCP does the job. It's fast, it's lightweight, it uses accessibility snapshots instead of screenshots so you don't need a vision model. Microsoft ships it, it works, end of story.

But here's where it falls apart: the moment you try to use it for actual, repeatable, production-grade testing.

The "run my tests" problem

When you say "run my tests" to an LLM with Playwright MCP attached, here's what actually happens: the LLM drives every single browser action in real time. Every click, every fill, every assertion — it's all going through the LLM. That means you're burning tokens on page.click('#login') like it's a creative writing prompt.

With FastTest, you say "run my tests" and the entire suite executes autonomously. FastTest fetches your test cases from the cloud, drives the browser directly (no LLM in the loop for mechanical actions), reports results incrementally, and returns a summary. One command. Done.

The difference isn't just cost — it's reliability. LLMs are stochastic. You don't want stochastic test execution. You want your page.click('[data-testid="checkout"]') to click the checkout button, not hallucinate a different selector because the model was feeling creative that afternoon.

Tests that exist after you close the terminal

Playwright MCP is stateless. Every session starts from zero. You can --save-session to preserve cookies, but there's no concept of a test case, a test suite, or a test run. You can't say "run the same tests we ran yesterday." There is no yesterday.

FastTest stores everything in a cloud database, scoped to your organization. Test cases have names, tags, priorities, steps, and assertions. They're versioned. They have provenance — you can trace any test case back to the conversation that created it. And they're bound to your repo via a .fasttest.json file, so when you open the project next week and say "run tests," it knows exactly which tests you mean.

This matters more than it sounds. The gap between "I can automate a browser" and "I have a test suite that my team trusts" is enormous. It's the gap between a demo and a product.

The healing thing (this is the big one)

I want to be specific about what happens when a selector breaks in Playwright MCP: absolutely nothing. The action fails. The LLM gets an error message. Maybe it tries a different selector, maybe it doesn't. There's no system. There's no memory. Tomorrow the same selector will break and the same nothing will happen.

FastTest has a 5-stage healing cascade that kicks in automatically when a step fails during execution:

// Healing cascade (in order)
Stage 0: Cloud pattern DB lookup — instant, O(log n)
Stage 1: data-testid probing confidence: 0.98
Stage 2: ARIA label matching confidence: 0.95
Stage 3: Text content search confidence: 0.90
Stage 4: Structural fallback confidence: 0.85
Stage 5: AI-generated (LLM analyzes DOM) confidence: 0.75

But the cascade is only half the story. The real trick is what happens after a heal succeeds.

Org-wide pattern learning

When FastTest heals a broken selector, it computes a SHA-256 signature from three things: the failure type (ELEMENT_NOT_FOUND), the original selector (#submit-btn-old), and the URL path (query params stripped for stability). That signature gets stored in the cloud alongside the working replacement selector.

Next time anyone on your team hits the same broken selector on the same page, the pattern DB returns the fix instantly — before any DOM probing happens. Stage 0. One indexed database lookup. The four local strategies and the AI call are skipped entirely.

Let me be concrete about what "faster" means here. On the first failure, healing might take 2–5 seconds if it escalates to AI (Stage 5). On subsequent failures with a stored pattern, it takes the time of one HTTP round-trip plus a single page.$(selector) validation call. We're talking milliseconds. The LLM is never invoked.

There's a deliberate constraint: AI-generated patterns (confidence 0.75) are stored but never auto-reused. The reuse threshold is 0.80. Only patterns from deterministic strategies — data-testid, ARIA, text, structural — get the fast path. AI patterns require re-validation on every run. This is conservative by design. We'd rather re-run the AI than silently use a fix it hallucinated last Tuesday.

The system also knows when not to heal. If a test case passed in 2 out of its last 3 runs and now it's failing, the healer classifies it as a real bug and refuses to intervene. You don't want a clever selector fix masking the fact that your checkout flow is genuinely broken.

Plain English in, test suite out

Playwright MCP has no concept of test generation. You, the developer, have to know what to test and how to test it. The LLM is your hands, not your brain.

FastTest flips this. You say "test the checkout flow" and the AI agent — Claude Code, Codex, whatever you're using — drives the conversation:

AGENTBefore I generate tests, a few questions:
1. Does checkout require authentication, or should I test guest checkout too?
2. Are there promo codes I should validate?
3. Should I cover error states — expired card, out-of-stock items?
YOUBoth. Yes, use SUMMER20. And yes, cover payment failures.
AGENTGenerated 14 test cases across 3 flows. Approve to save and run.

Because FastTest is MCP-native, the host AI naturally handles this conversation — it reads your app's snapshot, reasons about what to test, and calls FastTest's save_suite tool with structured test cases. The AI adds 2–4 edge cases you didn't think of — empty cart submission, duplicate coupon application, session timeout during payment. These aren't random. They're inferred from the structure of your app and the testing domain.

Once you approve, the cases are persisted as structured data — steps, selectors, assertions, tags — not as a blob of Playwright code. They're runnable, editable, and healable. They belong to your project forever.

Exploration: the LLM as a QA engineer, not a keyboard

FastTest has an exploration mode that Playwright MCP has no equivalent for. You say "explore my app" and it crawls your site autonomously, using AI to identify testable flows — forms, navigation paths, error states. It captures page structure and screenshots, analyzes them, and produces a structured report of everything worth testing.

This isn't a crawler that follows links. It's an agent that understands what a login form is, notices that your settings page has a delete-account button that probably needs a confirmation dialog, and flags that your checkout flow doesn't handle the back button gracefully.

You can focus the exploration: forms to audit every input on your site, errors to hunt for uncaught exceptions, navigation to map your routing. Or just say all and let it roam.

GitHub PR comments

When you run your tests, you can pass a GitHub PR link — run my tests on PR #142 — and FastTest automatically posts a formatted comment on the pull request with the full execution summary: pass/fail counts, per-test results, timing, and a list of every selector that was auto-healed during the run. Your reviewer sees the test status inline, right where they're already looking.

Playwright MCP has no awareness that GitHub exists.

The honest comparison

I don't want to be unfair to Playwright MCP. It's a good tool for what it is — a browser automation interface for LLMs. If you're building a research agent that needs to browse the web, or a scraping pipeline, or a one-off demo, it's the right choice.

But if you're trying to build a testing workflow — something that generates tests, runs them repeatedly, heals them when they break, stores them across sessions, and reports results to your team — you need a platform, not a remote control.

PLAYWRIGHT MCP
FASTTEST
Browser automation
Yes
Yes
Test generation
No
AI from plain English
Test persistence
No
Cloud DB, org-scoped
Suite execution
LLM drives each step
One command, fully autonomous
Self-healing
No
5-stage cascade
Pattern learning
No
Org-wide, improves over time
GitHub PR integration
No
Built-in
Autonomous exploration
No
AI-driven discovery
Session persistence
--save-session flag
Named sessions per org
Assertions
None
8 typed assertion kinds

The bottom line

Playwright MCP is a browser remote control. FastTest is a testing platform that happens to speak MCP.

We use Playwright under the hood — as a library, not as an MCP server. We chose this deliberately because test execution should be deterministic, not dependent on an LLM correctly interpreting tool results in real time. The AI belongs in test design (generating cases from natural language, exploring your app, healing broken selectors). The execution itself should be boring and reliable.

If you're an engineer spending Friday afternoons debugging why #login-btn-v2 isn't matching anymore, or manually re-running the same Playwright script after every deploy, or explaining to your PM that yes, the tests are green, you just haven't run them in a week because the selectors broke — FastTest exists because we were that engineer.

$ npx -y @fasttest-ai/qa-agent install
Free tier. No credit card. Start testing in 60 seconds.
← PREVIOUS
I Tried Every AI Testing Tool So You Don't Have To
NEXT →
How Our 5-Stage Healing Cascade Fixes Broken Selectors Before You Wake Up
We use cookies for authentication and analytics. Privacy Policy