MCP Browser Testing — Known Issues
Issues encountered during E2E testing via the Claude Code MCP Playwright browser on Windows.
1. Browser Session Crashes (Fatal)
Symptom: All browser tool calls fail with:
Error: browserBackend.callTool: Target page, context or browser has been closedWhen it happens: After a page navigate triggers a full reload that Chrome doesn’t recover from, or after using browser_evaluate to call window.scrollTo followed immediately by another tool call.
Recovery: Cannot be recovered within the same conversation. Requires restarting the MCP server or reopening Claude Code.
Workaround: Avoid calling window.scrollTo via browser_evaluate — use browser_scroll if available, or navigate directly to the target URL with a hash anchor instead. Close extra tabs before long sessions.
2. browser_wait_for with time Generates Incorrect Code
Symptom: browser_wait_for with time: 3000 generates:
await new Promise(f => setTimeout(f, 3000 * 1000));This waits 3,000,000 ms (50 minutes) instead of 3 seconds. After the timeout the page sometimes navigated away on its own.
Workaround: Do not use browser_wait_for with a time value. Instead, navigate to the destination page directly and take a screenshot to check state. If waiting for an async operation, poll with repeated browser_navigate + screenshot calls.
3. Element Refs Go Stale Between Pages
Symptom: A ref captured in one browser_snapshot (e.g. e215) resolves to a completely different element after a page reload or navigation, causing clicks to fire on the wrong element.
Example: Clicking e215 (intended: notification bell) after a page reload clicked a competitor table row instead.
Workaround: Always take a fresh browser_snapshot after any navigation before using refs. Never reuse refs across page loads.
4. browser_fill_form Requires Exact JSON Array Format
Symptom: browser_fill_form throws a validation error if fields is not passed as a properly structured JSON array.
Workaround: Use browser_evaluate with the nativeInputValueSetter pattern to fill React-controlled inputs:
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
setter.call(input, value);
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));Direct .value = assignment does not trigger React’s synthetic event handlers and the form state does not update.
5. Clicking Elements Blocked by Overlay (fixed inset-0 z-40)
Symptom: browser_click times out with:
<div class="fixed inset-0 z-40"></div> intercepts pointer eventsThis happens when a modal or dropdown backdrop is rendered over the target element.
Workaround: Use browser_evaluate to find and .click() the target element programmatically, bypassing the pointer-event intercept:
const btn = Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Approve Context'));
btn.click();6. Socket.IO Live Status Not Working on Windows (127.0.0.1 CORS)
Symptom: The “Live Activity” banner and agent card pulse indicators on /settings/agents never appeared during agent runs, even though agents were actively processing.
Root cause: The Socket.IO CORS config in apps/api/src/socket/index.ts only allowed localhost origins:
["http://localhost:3000", "http://localhost:3001", "http://localhost:3002"]On Windows, the browser visits http://127.0.0.1:3000, which sends Origin: http://127.0.0.1:3000. This was rejected by the socket server, preventing the WebSocket handshake. The agent:event messages never reached the browser.
Fix applied: Replaced the static array with a regex function matching both localhost and 127.0.0.1:
(origin, cb) => {
if (!origin || /^http:\/\/(localhost|127\.0\.0\.1):\d+$/.test(origin)) {
cb(null, true);
} else {
cb(new Error("Not allowed by CORS"), false);
}
}Note: In-app notifications appeared to work because they are fetched via HTTP (/api/notifications) on page load — not pushed via Socket.IO. The socket push (notification:new) was also broken but not noticed since HTTP polling masked it.
7. window.scrollTo via browser_evaluate May Crash the Session
Symptom: After calling window.scrollTo(0, 0) via browser_evaluate, the page appeared to not scroll, and subsequent tool calls eventually led to a browser crash.
Workaround: Navigate directly to the page URL (with browser_navigate) instead of trying to scroll programmatically. This reloads from the top.
General Testing Tips (Windows)
- Always use
http://127.0.0.1:PORT— neverlocalhost— for both dashboard and API URLs - After every
browser_navigate, take abrowser_screenshotbefore attempting any interactions - Keep the number of open tabs low (≤2) to reduce crash risk
- Use
browser_evaluatewithdocument.querySelectorAll+ text matching for robust element selection rather than relying on snapshot refs