Back to Blog

Cursor vs Claude Code vs Codex: Which AI Agent Writes the Best E2E Tests?

Cursor vs Claude Code vs Codex: Which AI Agent Writes the Best E2E Tests?

Every week a new thread shows up on Hacker News or X: which AI agent is best at writing end-to-end tests? Cursor fans swear by the tight IDE loop. Claude Code users point to Opus 4.6's reasoning. Codex loyalists cite GPT-5.3 with extended thinking. The honest answer, after a month of tracking real projects using each of them as an E2E test author, is that none of them are good at it - and the reasons matter more than the leaderboard.

This post is not a fanboy post. If you came here looking for a winner between Cursor and Claude Code on testing, you will leave a little disappointed and hopefully a little wiser. The short version: for AI E2E testing, the agent that writes the test matters far less than what that test is allowed to become once it is written. Let's get into it.

The methodology

We looked at five things across each agent: average attempts to produce a working test, monthly maintenance burden in hours, the selector strategy the agent defaulted to, how well the agent handled multi-page user flows without losing track of the objective, and the structural problems every LLM-driven approach shares. The tracking window was roughly a month across several frontend projects with normal feature churn. Same prompts, same apps, same humans reviewing the output.

The point of the exercise wasn't to shame any tool. It was to figure out whether "let the coding agent write your E2E tests" is a strategy that survives contact with a real codebase. Spoiler: it mostly doesn't, and the failure modes are remarkably similar across vendors.

Two-column comparison of agent-authored E2E tests versus the Lastest approach: agent-authored tests use DOM-bound selectors, are non-deterministic on re-run, burn tokens on every CI run, and have no visual layer, while Lastest uses a 7-layer self-healing selector fallback, deterministic zero-token replays, and three visual diff engines.
The structural problems are identical across Cursor, Claude Code, and Codex; the fix is not a smarter model but a different execution model.

Cursor

Cursor has the tightest iteration loop of the three. You are in your editor, you highlight a component, you ask for a test, and something shows up in seconds. For small UI primitives and isolated utilities, that workflow is genuinely delightful.

The trouble starts when you ask for a real E2E test that spans a login, a form, a redirect, and an assertion on a server-rendered list. In our tracking, Cursor required an average of 6 attempts before producing a test that actually passed on first run. The generated tests leaned heavily on Tailwind utility classes as selectors - things like .bg-blue-500.px-4.rounded-lg - which is the single most brittle selector strategy you can choose in 2026. A designer tweaks spacing, a theme toggles, someone bumps to the next Tailwind major, and every test breaks at once.

Maintenance burden landed at roughly 7+ hours per month of humans babysitting the Cursor-authored suite on a modest project. Adding an MCP layer on top brought that down to about 5 hours, which is better, but still not a number you want to pay forever. Cursor's strength is velocity on greenfield; its weakness is that the tests it produces are liabilities the moment the UI moves.

Claude Code

Claude Code is, by a meaningful margin, the best pure test author of the three. It needed an average of 3 attempts to produce a working E2E test in our tracking - half of Cursor's count - and the tests it wrote were noticeably more thoughtful. It reaches for roles and accessible names before it reaches for CSS. Opus 4.6 is also one of only two models we tested (alongside GPT-5.3 with extended thinking) that reliably completes a complex multi-page flow without losing the original objective halfway through.

Here is the catch, and it is the single most important observation in this post:

Claude is excellent at writing tests that are real and useful, but it doesn't write them where they matter most - it writes them where they're easiest, for the feature it just built, in the same session, while the context is fresh.

Translation: Claude Code will happily ship tests for the button you just added, but it will not, on its own, go back and cover the legacy checkout that breaks in production every third Tuesday. And when you do get tests in place, the maintenance burden still came in around 6.5 hours per month - better than Cursor, still not zero, and the suite still shattered on a visual redesign because the selectors were DOM-bound and the assertions never looked at pixels.

Codex / GPT agents

Codex and the broader GPT-agent family are the hardest to pin down because the output varies wildly with model version. GPT-5.3 with extended thinking is genuinely strong - in the same league as Opus 4.6 on multi-page flow reasoning - while older or non-thinking variants forget what they were testing by the third page navigation. When it's good, it's good. When it's not, you get a lot of confidently wrong tests that pass once and never again.

The structural issues, though, are identical to Cursor and Claude Code. Selectors are DOM-bound, re-runs are non-deterministic, and the tests have no idea whether the page looks right - only whether the elements they grabbed still exist.

A quick comparison table

Agent Avg attempts to working test Maintenance (hrs/mo) Selector strategy Deterministic on re-run Zero-token replays
Cursor 6 7+ Tailwind classes / CSS No No
Cursor + MCP ~4 ~5 Mixed CSS / role No No
Claude Code (Opus 4.6) 3 6.5 Role / aria / text No No
Codex (GPT-5.3 thinking) 3–5 6–8 Mixed, model-dependent No No
Lastest (codeless + AI) 1 ~0 7-layer fallback Yes Yes

The underlying problem none of them solve

Ranking Cursor against Claude Code against Codex is fun, but it's a bit like arguing about which flavor of ice cream melts slowest on the sidewalk. Every LLM-driven test authoring approach inherits three problems that don't go away no matter how good the model gets.

Three stat cards naming the structural problems every agent-authored test suite inherits: non-determinism on re-run, token cost that scales linearly with commit count, and no visual layer so DOM-passing tests miss visibly broken UI.
The three failures no coding agent escapes: non-deterministic re-runs, linear token cost, and DOM-only assertions that never look at a pixel.

Non-determinism on re-run. An agent-written test is deterministic code at the moment it's written, but the moment you let the agent run it as part of the loop - exploring, retrying, re-planning - every execution becomes a new roll of the dice. That's fine for development. It's disqualifying for CI, where "did this commit break the login flow" has to return the same answer every time.

Token economics. Re-running an LLM-driven test on every commit means your test bill scales linearly with your commit count. A team that ships 30 times a day and runs a 50-test suite is now paying for 1,500 LLM invocations per day, forever, for tests that - in principle - should produce the exact same result they did yesterday. That is not a sustainable line item.

No visual layer. DOM assertions pass when the UI is visibly broken. A button with display: none accidentally applied by a CSS regression still exists in the DOM; the agent's expect(button).toBeVisible() check may even pass depending on how it was written. Text overlapping by 20 pixels, a modal that's rendered off-screen, a dark-mode palette that ships unreadable white-on-white - none of this is catchable by any of the three agents, because none of them ever look at a pixel.

What actually works: generate once, replay forever

Here is the reframe that makes all of this tractable. The valuable thing an AI agent does, in testing, is figure out what to click. That's a one-time cost. The destructive thing it does is keep paying that cost forever on every re-run, with a different outcome each time.

So separate the two. Use AI to write the test once. Then freeze that test as deterministic Playwright code with a visual baseline attached. Every replay from then on uses zero tokens, takes the exact same path, and compares real pixels against the baseline. This is what Lastest does, and it's why the maintenance column in that table above is approximately zero. We unpack the token math in the real cost of LLM-driven test runs.

Left-to-right pipeline showing the generate-once, replay-forever model: an AI agent authors the test once (tokens spent), the test is frozen as deterministic Playwright with a visual baseline, then every CI replay runs plain Playwright at zero tokens and diffs real pixels against the baseline.
AI is a one-time authoring cost; replays are deterministic, zero-token Playwright runs that compare real pixels.

The brittleness problem gets solved separately, by a 7-layer self-healing selector fallback: data-testid first, then id, then ARIA role, then aria-label, then visible text, then CSS, then OCR on the rendered pixels as a last resort. When a Tailwind class changes, the test doesn't break - it walks down the ladder until it finds the element by intent rather than by incidental styling. The visual layer gets solved by three diff engines running in parallel (Pixelmatch, SSIM, and Butteraugli) with a text-region-aware two-pass strategy, so you catch the visually broken pages the DOM can't see.

But what about MCP integration?

Fair question. If you love the ergonomics of driving everything from Claude Code or Cursor, you don't have to give that up. Lastest ships an MCP server with roughly 20 tools, which means Claude Code, Cursor, Windsurf, and any other MCP-aware agent can absolutely drive the testing loop - record a flow, run the visual diff, triage a failure, promote a baseline - they just drive a deterministic engine instead of writing fresh brittle Playwright each time. You also bring your own AI: Claude CLI, the Anthropic or OpenAI APIs, OpenRouter, or a local Ollama model, with no lock-in.

That is the best of both worlds: agent ergonomics on the authoring side, deterministic execution and zero-token replays on the running side. You keep the conversational loop you like; you stop paying the tax.

So, which agent is best?

TL;DR: the question isn't "which coding agent is best at writing E2E tests". The question is what does the agent drive. If the answer is "fresh hand-rolled Playwright with CSS selectors on every session", you will burn 5 to 7 hours a month maintaining it no matter which logo is on the IDE. If the answer is "a deterministic test engine with self-healing selectors and a visual baseline", the agent does the interesting one-time work and then gets out of the way. If you are shipping with these tools, here is how to actually test a Cursor or Claude Code app.

Stop paying the LLM testing tax. Lastest is free and open source under FSL-1.1, and you can self-host it with a single docker-compose up - unlimited screenshots and replays on your own infra, $0 forever. Want to skip the ops entirely? Lastest Cloud is a flat $299/month with no per-seat or per-screenshot fees. Either way, the repo is at github.com/las-team/lastest. Bring your favorite agent.