Test your web app without writing tests
You do not need a test suite to check that signup still works. You describe the journey in a sentence — sign up with a fresh address, verify the emailed code, confirm the dashboard loads — and the Claude you already pay for drives a real Chrome on your Mac through it, reading the page and the DOM as it goes, then writes up what broke.
What you need is a Mac running macOS 11 or newer, Chrome, and your own Claude — a Claude Desktop login or Claude Code. DeckTest is the MCP server between them. It includes no AI access of its own and adds no usage bill.
This page covers how a request is phrased, how each step is judged, what a run leaves on disk, how to repeat a flow without maintaining one, and where it does nothing. The quickstart covers installation.
Describing the journey in a sentence
A request is one to three sentences of plain English, typed into Claude Desktop or Claude Code. Three shapes that come up constantly:
- Sign up at staging.example.com with a fresh address, verify the code from the inbox, and confirm the dashboard loads. Report anything broken.
- Go through checkout on staging with the test card. Tell me whether the receipt shows the right amount, and whether anything errors in the console on the way.
- Open the billing page on staging, run an accessibility audit, and tell me which violations are serious or critical.
Underneath, Claude has a small set of browser verbs and chooses them as it goes: navigate, fill a field, click a selector or a piece of visible text, wait for an element, scroll, read the page text, read one element's HTML, take a screenshot, run an accessibility audit. Nothing is recorded in advance, so there is no recording to re-record when the page moves.
Each session gets its own coloured tab group in Chrome, auto-labelled after the first site it opens, and you can watch the run happen and follow the log in the app. The work happens beside your browsing rather than inside it, and two sessions running at once do not fight over the same tab.
Two readings of every step, and a third you ask for
A screenshot on its own is a weak witness: a form can render perfectly while the request behind it fails. A scenario run reads each step two ways by default. There is a third reading, and it is one you ask for rather than one you get.
- What it looks like. A screenshot is captured on every navigation, on every assertion, on any step that fails, and on any step you mark as evidence — so a failure arrives with the picture already attached.
- What the UI says. The real elements and text: does the heading exist, does the row exist, does the URL now contain /app, was the field cleared. Read out of the DOM rather than matched against pixels.
- What the console and network say. Not automatic. Console logs and failed requests are captured on request, as a fixed window of a few seconds, and only from the separate automation Chrome described below. It is the class of bug the first two readings cannot see at all, at the cost of asking for it.
Worth knowing which channel the third reading uses. The bridge extension that drives your everyday Chrome holds no debugger permission, so console and network capture run through a separate automation Chrome started with remote debugging on 127.0.0.1:9222. The app's status row tells you whether that Chrome is listening. It runs on its own profile directory, so it carries none of your everyday Chrome's logins — anything behind a sign-in wall needs you to sign in there once. When it is not running, you get the first two readings and not the third.
What comes back
A run writes a folder, not a log line: report.md for a person, run.json for anything you want to script against, and a screenshots directory beside them.
report.md opens with the verdict and a passed/failed count, then a table of every step — what it did, its status, how many milliseconds it took, and a link to its screenshot. Bugs follow, ordered blocker, critical, major, minor, cosmetic, each carrying what was expected, what actually happened, which dimension it belongs to, and the evidence. The report has a section for console and network anomalies, but it is written only when a run supplies them. A plain YAML scenario run does not, so on that path the section is simply absent.
The verdict rule is unforgiving on purpose. Every requested step has to pass; skipped and unknown statuses count as failures, and a report with no steps in it is never a pass. One blocker or critical bug fails the run on its own.
A failed assertion does not abort the run. It records the bug and carries on, so one broken step does not hide the four behind it and you learn everything in a single pass.
If the engine dies mid-run you get a FAIL with the reason attached — the engine stopped before finishing the run — rather than a step that spins forever.
Why does a hand-written test suite keep breaking?
Every selector in a test is a copy of a decision someone made in the markup. Rename a class, move a button inside a wrapper, change a form library, and a passing test turns red while the product behaves exactly as before. The test did not find a bug. It found an edit.
A suite only ever checks what its author thought of. If nobody wrote an assertion for the request behind the submit button, a 500 that the interface swallows will pass every run until a customer reports it. Green means the predictions held — not that the page works.
DeckTest's own scenario format keeps exactly four assertion types: url_contains, url_not_contains, exists and text_contains. That is deliberate. A short list is quick to write and impossible to lean on, so the judgement stays where it can adapt — in the model reading the page, not in the file.
Repeating a run without maintaining one
Conversation suits the first run and not the hundredth. Ask Claude to save the flow as a YAML scenario and you get a plain-text file of named steps — navigate, fill, click, wait_for, assert, resize, axe, get_email_code — rather than selectors wrapped in code. Re-run it before a deploy: same steps, fresh judgement each time.
Scenarios run in parallel, up to six at a time, each in its own Chrome window, and each writes its own report. Those windows share your everyday Chrome profile, so parallel runs share its logins — two scenarios cannot be signed in to the same site as different users at once.
The email step is the one most automation skips. get_email_code and get_email_link poll a mailbox over IMAP — three minutes by default — pull the OTP or magic link out of the message, and hand it to the next fill step. Nothing arriving in time is recorded as a blocker bug, Verification email not received, rather than quietly passing. That step needs IMAP credentials for a mailbox you control; in the conversational path Claude can instead open your webmail in the same browser and read the code off the page.
Where it does nothing
The limits here are structural rather than temporary, so they are worth reading before you buy.
- It needs a real machine. macOS 11 or newer, Google Chrome installed, your own Claude, and your own sites or apps — the app drives the browser on the Mac it is running on.
- Two runs of the same sentence are not the same test. In the conversational path Claude picks the browser actions as it goes, so a second run may check more, or less, than the first. A saved scenario pins the steps, but only four assertion types are checked mechanically — url_contains, url_not_contains, exists and text_contains. Everything past those is judgement, and judgement varies.
- A run starts when you or your Claude starts one. There is no hosted runner in the app and nothing in it watches a branch or gates a merge.
- The bridge extension declares a minimum Chrome version, so an old Chrome refuses to load it. Windows is not shipped.
- Captchas are not defeated. A readable image captcha is extracted for your Claude to read only on hosts you have listed, and out of the box that list is localhost and 127.0.0.1 — add your staging host before the first run. Behavioural challenges are flagged for a human, never faked.
- Testing native Mac apps needs the macOS Accessibility grant. Without it those tools return an explicit permission error instead of an empty window.
- You need your own Claude. DeckTest is the MCP server between Claude Desktop or Claude Code and the browser; it includes no AI access and resells none. With no Claude signed in, there is nothing to drive the run.
DeckTest is $29 once, for two Macs, with a 7-day refund and no trial. The browser, the runs, the screenshots and the reports stay on your Mac.
Point it at your own app
DeckTest is $29 once — two Macs, a 7-day refund, no trial and no subscription. The thinking runs on the Claude you already pay for, so there is no AI bill from us. You need macOS 11 or newer and Chrome.
Get DeckTest — $29, onceCommon questions
Can I really test a web app without writing any test scripts?
For a one-off run, yes: you describe the journey to Claude in plain English and it drives a real Chrome through it, choosing browser actions as it goes rather than replaying a recording. For a flow you want to repeat, you can ask Claude to save it as a YAML scenario — a plain-text list of named steps such as navigate, fill, click, wait_for and assert. That file is still something you keep, but it is a description of the journey rather than code full of selectors.
How does it catch a bug a screenshot cannot show?
Two readings happen on every step: what the page looks like in a screenshot, and what the DOM actually contains. A third reading — console logs and failed requests — is one you ask for, captured as a window of a few seconds rather than per step. It is how a swallowed 500 or an uncaught error surfaces. That reading comes from a separate automation Chrome running with remote debugging on 127.0.0.1:9222, on its own profile, and the app shows you whether that Chrome is up.
Does it replace CI?
No. There is no hosted runner in the app, nothing in it watches a branch, and nothing gates a merge. DeckTest needs a real Mac with Google Chrome installed, and a run happens when you or your Claude starts one. It is a way to check a flow before you ship, not a gate that checks it for you afterwards.
What does a run cost to run?
Nothing beyond the purchase. DeckTest is $29 one-time, covering two Macs, with a 7-day refund and no trial. The reasoning runs on the Claude subscription you already pay for, and DeckTest never sees, stores, meters or marks up that usage, so there is no AI bill from us.
Where do the reports go?
Each run writes its own folder containing report.md for reading, run.json for scripting against, and a screenshots directory. Everything stays on your Mac — the browser, the run, the screenshots and the report — and your Claude account talks to Anthropic directly under your own credentials.