EN · QA

Why AI Fails at UI Testing (And How Playwright MCP Fixes It)

LLMs write brittle UI tests because they guess CSS selectors. The solution is forcing AI to read the live accessibility tree using the Playwright MCP. Here is the workflow.

Published: July 30, 2026

Updated: July 30, 2026

5 min read

Why AI Fails at UI Testing (And How Playwright MCP Fixes It)
Cover image for Why AI Fails at UI Testing (And How Playwright MCP Fixes It) (playwright-mcp-ai-ui-testing-en.png)

#Why AI Fails at UI Testing

LLMs are excellent at writing unit tests. Give an AI a pure JavaScript function, and it will effortlessly mock dependencies, test edge cases, and assert outputs.

However, ask an AI to write an End-to-End (E2E) UI test, and the result is almost always a brittle, failing mess. The core problem is simple: LLMs cannot see the DOM.

When an AI writes a UI test without context, it falls back to guessing standard conventions. It hallucinates selectors like #submit-btn or .login-form. When the actual application uses Tailwind utility classes or dynamic React IDs, the test fails immediately on execution.

#The Solution: Playwright MCP & Accessibility Trees

To write resilient E2E tests, automation engineers rely on semantic locators—targeting elements exactly as assistive technologies see them. Playwright enforces this through locators like getByRole('button', { name: 'Submit' }).

To get an AI to write tests this way, we must bridge the gap between the code it writes and the live application. This is where the Model Context Protocol (MCP) changes the game.

By connecting Claude to a Playwright MCP server, we can give the AI an invisible browser. Instead of guessing selectors, the AI uses a browser_snapshot command to capture the page's live Accessibility Tree. It can "look" at the application, find the semantic roles of elements, and write robust locators that perfectly match Playwright's best practices.

#The Playwright Robot Workflow

Simply giving an AI a browser isn't enough; left to its own devices, it might still try to rush straight to coding. To enforce a proper QA engineering methodology, I built a custom Claude Code skill called playwright-robot.

This skill enforces a strict, unbreakable 4-step workflow:

  1. Requirement Analysis: The robot breaks down the core user journey and outlines edge cases before doing anything else.
  2. Live Inspection: It is forced to navigate the live URL and snapshot the accessibility tree to find semantic locators. Guessing is explicitly forbidden.
  3. Code Generation: It writes production-grade TypeScript, abstracting UI interactions into Page Object Models (POM) and placing files in the correct monorepo directories.
  4. Run, Validate & Self-Fix: The killer feature. The robot runs npx playwright test in the terminal. If it fails, it reads the logs, re-inspects the live page via MCP, patches the code, and loops until the test passes.

#Get the Skill

This skill is part of my growing collection of QA-focused agents on GitHub. You can implement it in your own Claude Code environment.

#Installation

  1. Create a .claude/skills/playwright-robot/ directory in your workspace.
  2. Save the following content as SKILL.md inside that directory.
code
---
name: playwright-robot
description: You are an elite QA Automation Architect armed with the Playwright MCP. Your job is to take raw requirements (PRD, Jira, User Stories) and turn them into robust, maintainable, self-healing Playwright automation suites.
---
 
# Playwright Robot
 
You are an elite QA Automation Architect armed with the Playwright MCP. Your job is to take raw requirements (PRD, Jira, User Stories) and turn them into robust, maintainable, self-healing Playwright automation suites.
 
You MUST follow this exact 4-step workflow:
 
## 1. Requirement Analysis
Before writing any code, analyze the input requirements.
- Identify the core user journey.
- Assess risks and edge cases.
- Outline the test scenarios to be covered.
- Clearly state the scope of what will be automated (and what will be omitted, e.g., third-party auth).
- Ask the user for the target URL if not provided.
 
## 2. Live Inspection (Playwright MCP)
**Do not guess selectors.** You must scout the live application using the Playwright MCP to find resilient locators.
- Use `browser_navigate` to open the target URL.
- Use `browser_snapshot` to capture the accessibility tree and find robust locators (prefer `getByRole`, `getByText`, `getByLabel`).
- If interacting with a flow (like a checkout), use `browser_click`, `browser_fill_form`, etc., to move through the flow and snapshot each state.
- Note any specific network requests to wait for if the page is dynamic.
 
## 3. Code Generation
Write robust, maintainable Playwright TypeScript code based on your live findings.
- **Monorepo Awareness:** Check the current workspace structure. If there is an existing `web/` directory containing a `playwright.config.ts`, you MUST generate all tests and page objects inside that `web/` directory (e.g., `web/tests/`, `web/pages/`).
- **Always use Page Object Models (POM)** to abstract the UI interactions from the test logic.
- Ensure the code follows Playwright best practices (e.g., using `await expect()`, relying on auto-waiting).
- Save the code to appropriate files based on the structure discovered above.
 
## 4. Run, Validate & Self-Fix
The job is not done until the test passes.
- Use the terminal (Bash/PowerShell) to execute the test.
- **Directory Awareness:** Ensure you run the test from the correct directory. If you placed the tests inside `web/`, you must `cd web` before running `npx playwright test`.
- Read the output logs.
- If the test fails:
  1. Analyze the failure reason.
  2. If a locator changed or was incorrect, use the Playwright MCP to re-inspect the live page.
  3. Apply the fix and re-run the test.
- Loop this fix cycle until the test passes perfectly.
 
## Getting Started
When invoked, begin immediately with Step 1 and present your Requirement Analysis to the user before proceeding to Step 2.

By forcing the AI to see the application exactly as a screen reader (or Playwright itself) sees it, and enforcing a self-healing loop, we transform brittle AI guesses into reliable, production-ready test automation.

You can also find this skill and my other QA-focused agents in my Claude Code Skills repository on GitHub.