Claude Code + Playwright MCP: AI Can Finally "See" the Page
Table of Contents
One Bug, Five Failed Fixes
Here’s what happened.
My project has a VIP upgrade modal built with Ant Design Modal, containing two pricing cards — Free Plan and VIP Plan.
One day I noticed the two cards were overflowing the Modal boundary, with the bottom buttons getting clipped.
Pretty common CSS issue, right? I asked Claude Code to fix it.
First attempt: it added maxHeight: 'calc(100vh - 200px)'. Didn’t work.
Second attempt: it switched to overflow: auto. Ugly scrollbar appeared.
Third attempt: it replaced the Ant Design <List> component with plain <div> elements, trying to eliminate the virtual list scrollbar.
Fourth attempt: it removed the Modal body height constraint entirely.
Fifth attempt…
dfef989 fix(nweb): update VIP button color to match theme and fix modal overflow
d399709 fix(nweb): fix pricing modal body overflow with calc-based maxHeight
68395c4 fix(nweb): fix pricing modal body overflow with calc-based maxHeight
b736345 fix(nweb): remove modal body height constraint to fix scrollbar
b4118b2 fix(nweb): replace antd List with plain div to eliminate virtual-list scrollbar
5 fix commits. Problem still there.
Why Did It Keep Failing?
The reason is simple: Claude Code couldn’t see the page.
It could read code, analyze CSS properties, and reason about layout logic. But it had no idea what the page actually looked like when rendered.
It’s like a blindfolded plumber. You tell him “the pipe is leaking,” and he can guess a solution based on experience — but he can’t see where the water is actually coming from.
So every fix was a guess — guessing whether maxHeight was enough, guessing what overflow value to use, guessing whether the List component was the problem. After each change, it assumed the fix worked, but it had zero visibility into the actual result.
Playwright MCP: Giving AI Eyes
Then I remembered something: Playwright MCP.
Playwright is Microsoft’s open-source browser automation tool that can simulate user interactions with browsers. Playwright MCP is its MCP Server version. Once installed, Claude Code can:
- Open a browser and navigate to any URL
- Take screenshots to truly “see” the rendered page
- Click buttons to simulate user interactions
- Execute JavaScript to get actual DOM element dimensions
- Fill forms, drag elements, wait for elements to appear…
In short, Claude Code went from “an AI that can only read code” to “an AI that can open a browser and actually interact with the page.”
Installation
Setup is dead simple. Run the /mcp command to add the Playwright MCP Server:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@anthropic-ai/mcp-server-playwright@latest"]
}
}
}
After that, Claude Code gains a bunch of browser-related tools: browser_navigate, browser_click, browser_snapshot, browser_take_screenshot, browser_evaluate, and more.
Real Battle: One Shot, One Kill
With Playwright MCP installed, I asked Claude Code to fix the bug again.
Step 1: It started the dev server itself, then used Playwright to open http://localhost:3000:
await page.goto('http://localhost:3000');
Step 2: It found the “Upgrade VIP” button and clicked it to open the Modal:
await page.getByRole('button', { name: 'crown Upgrade VIP' }).click();
Step 3: It took a screenshot and actually “saw” the problem — both cards were indeed pressed against the Modal’s bottom edge.
Step 4: It used browser_evaluate to run JavaScript and directly measure DOM dimensions:
{
"modalBody": { "height": 480, "scrollHeight": 508 },
"cards": [{ "height": 506 }, { "height": 508 }]
}
Crystal clear: Modal body 480px, cards 508px — overflowing by 28px.
Step 5: It dug deeper, checking the Row, Col, and card size relationships:
{
"row": { "height": 456 },
"cols": [{ "height": 456 }, { "height": 456 }],
"cards": [{ "height": 506 }, { "height": 508 }]
}
Col height was 456px, but cards were 506/508px — cards were overflowing the Col. Root cause found: the cards had height: '100%' set, but their content was taller than the Col. height: 100% doesn’t constrain content — it actually prevents the Col from expanding to fit.
The final fix — two changes:
- Changed Row’s vertical gutter from
[24, 24]to[24, 0](horizontal layout doesn’t need vertical spacing) - Changed cards from
height: '100%'toflex: 1, addeddisplay: 'flex'to Col (letting flex layout expand naturally)
After the fix, it took another screenshot and measured again to verify:
{
"modalBody": { "height": 480, "scrollHeight": 480 },
"cards": [{ "height": 456 }, { "height": 456 }]
}
scrollHeight === height. Zero overflow. Problem completely solved.
Before vs After
Without Playwright MCP:
- Claude Code could only read code and guess at the problem
- 5 commits, trial and error
- Every time: “I think it should be fixed now” — but it wasn’t
With Playwright MCP:
- Screenshots revealed the actual rendering
- JavaScript measurements provided precise data
- Root cause identified in one pass, fixed in one shot
- Self-verified after the fix, confirmed zero overflow
When to Use Playwright MCP
Not every bug needs Playwright MCP. Pure logic bugs, API issues, and build errors — Claude Code handles those just fine by reading code.
But for these scenarios, I strongly recommend installing it:
- CSS layout issues: Overflow, alignment, responsive design — can’t guess accurately from code alone
- UI interaction bugs: Modals, dropdowns, animations — need actual interaction to reproduce
- Visual regression: Confirming the page isn’t broken after code changes
- E2E validation: Not just fixing code, but verifying the user flow works end to end
Takeaway
This bugfix gave me a profound realization:
AI is already very good at writing code, but its biggest weakness isn’t “can’t write” — it’s “can’t see.”
It can write correct CSS, but without seeing the rendered result, it can only guess. Guessing right is luck; guessing wrong means commit after commit of trial and error.
Playwright MCP fills that gap. Letting AI see the page, interact with the browser, and verify results — that’s the complete development loop.
If you’re using Claude Code for frontend development, this MCP is a must-have.
Related Articles
Claude Code Agent Loop: Dissecting the Heart of an AI Coding Assistant
How does Claude Code understand your requests, invoke tools, and self-recover step by step? A source-code deep dive into the Agent Loop's core architecture — streaming responses, parallel tool execution, auto-compaction, and error recovery.
Claude Code settings.json Explained (1): Where Config Files Live and Who Wins
A complete guide to Claude Code's configuration file system — five config sources, their file paths, priority rules, array merging vs value overriding, and enterprise managed settings delivery.
Claude Code settings.json Deep Dive (Part 2): The Permissions System
A thorough breakdown of Claude Code's permissions configuration — allow/deny/ask rule arrays, wildcard syntax, MCP tool permissions, defaultMode options, and additionalDirectories.
Claude Code settings.json Deep Dive (Part 3): The Hooks System
A thorough breakdown of Claude Code's hooks configuration — four hook types, core events (PreToolUse/PostToolUse/Stop/Notification), stdin/stdout protocol, exit code semantics, and practical examples.
Claude Code settings.json Deep Dive (4): env, Models, Auth, and Other Useful Fields
A comprehensive guide to the remaining settings.json fields in Claude Code — env variable injection, model configuration, authentication helpers, Git attribution, session cleanup, language and UI, thinking depth, auto-updates, memory system, and more.