This site is available as Markdown for AI agents. For the full index, see llms.txt.
AI-native E2E testing · for web

Your agent writes the E2E tests. You stay in control.

Describe a flow in plain English. Your AI agent drives your real app over MCP and writes a clean, reviewable .js test in your repo — readable on top, precise underneath. Not a black box.

$ npx @unotest/web init
See how it works

Works with Claude Code · Cursor · Codex · any backend stack · runs locally

big-table.test.js
passed

Click any step to expand it — every plain-English line is real, runnable DSL underneath.

How it works

Three steps. You review every one.

AI does the legwork — writing, running, repairing. The result is readable .js you own.

01 You

Describe the flow in words

Tell your agent what to test in plain English. It explores your live app over MCP — reading the semantic DOM, not pixels — clicking and filling like a user.

02 Agent

The agent writes and runs it

It records a clean scenario with stable locators (getByTestId → getByRole → …), drops it into unotest/e2e/*.js, and runs it end-to-end.

03 You + Agent

It breaks → the agent fixes, you approve

A failing step pauses mid-run. agent_fix bundles the context and a fix; the agent proposes a diff. You review and commit. Nothing is applied silently.

Built for both

Everything you'd want in a test tool — for humans and agents

A local IDE-style viewer for you. 33 MCP tools for the agent. One scenario format in between.

The scenario

Readable on top, precise underneath

Every step carries a plain-English intent. Inside it sit the exact DSL calls — one step can be several. The agent knows what a step means and how it runs, so it repairs only the broken part.

login.test.js
1 function test_login() {
2 step("Submit the sign-in form", () => {
3 fill(getByLabel("Email"), EMAIL);
4 fill(getByLabel("Password"), PASSWORD);
5 click(getByRole("button", { name: "Continue" }));
6 });
7 }

Debugging

One debugger, two users

A failing step freezes the run instead of crashing it. Inspect live DOM and variables, patch, resume from the same step — whether it's the agent driving or you.

debugger
paused · breakpoint · L15:4
Vars Call stack Trace
email"demo@example.com"
attempts2
isVisiblefalse
Continue Step Stop

Reuse

Reusable helpers & data

Two kinds, both plain JS. Flows replay a UI journey — sign-in, checkout. Mocks seed and reset data through DB and API before a test runs.

flow_*dbQuerydbExecapiCallshell
_helpers/flows.js
Flow
1 function flow_signin(email, password) {
2 goto("/login");
3 fill(getByLabel("Email"), email);
4 fill(getByLabel("Password"), password);
5 click(getByRole("button", { name: "Sign in" }));
6 }
_helpers/mocks.js
Mock
1 function seed_cart(userId) {
2 dbExec("INSERT INTO carts (uid) VALUES ($1)", userId);
3 apiCall("POST", "/test/checkout/reset");
4 }

Grouping

Collections — smoke & regress

Group scenarios and run them as a set. Reorder by drag, watch per-scenario status stream in, and abort the whole run in one click.

smoke · collection
6 scenarios 4 passed · 1 running
login
checkout
search
profile-edit
settings

History

Run history & failure artifacts

Every run is saved with status and duration. A failure bundles the evidence: screenshot, console, a semantic DOM snapshot and the full trace.

runs
checkout3.1s12:04
login2.4s12:01
screenshotconsoleDOMtrace
search1.8s11:58

Config

Variables & secrets

Keep credentials out of code. Reference bare UPPER_SNAKE; secrets stay masked in logs and artifacts. Run the same test on dev, staging or prod.

variables
dev staging prod
APP_BASE_URLhttps://staging.app.dev
TEST_USER_EMAILdemo@example.com
TEST_PASSWORD ‹secret›

In the viewer

AI right inside the viewer

A docked terminal with local, claude and codex sessions. Ask the agent to write or fix a test without leaving the window — and watch it run.

terminal
claude local codex
write an e2e test for sign-in
exploring app · reading semantic DOM…
recorded login.test.js · running…
3 steps · passed in 2.1s

Comfort

Light & dark themes

The viewer follows your taste and your system preference — every panel, the block view and the debugger included.

MCP-native

Plugs into the agent you already use

No new chat window. unotest is an MCP server — your editor's agent drives your real app through it and writes the test.

Claude CodeCursorCodex

33 MCP tools · a few of them

get_page_snapshotexplore_steprun_testinspect_runtimeresumeagent_fix

The agent sees a semantic snapshot of the DOM — roles, labels, test IDs — not screenshots. Cheap on tokens, stable across redesigns.

Full control

AI does the work. You keep control.

The whole point: speed from the agent, ownership stays with you.

Plain .js in your repo

Tests are ordinary JavaScript in unotest/e2e/*.js. Git, code review, CI — no proprietary format, no binary blob.

No silent fixes

agent_fix composes context and a suggestion — it never calls an LLM itself and never applies a patch on its own. You read the diff and commit.

Runs locally

Everything runs on your machine. Your app never leaves it. No cloud, no account.

Safe to run blindly

Scenarios execute in a sandboxed AST interpreter — no require, no fetch, no filesystem. AI-generated tests can run without surprises.

Frequently asked questions

What is unotest web?
AI-native end-to-end testing for web apps. Your AI agent drives your real app over MCP and writes clean, reviewable JavaScript tests in your repo. You review and commit.
Do I need to know Playwright?
No. The DSL borrows Playwright vocabulary so it reads naturally, but your agent writes the tests for you. Each step carries a plain-English intent with the exact DSL calls inside.
Where do the tests live?
As ordinary JavaScript files in your repository. They go through Git, code review and CI like any other code — no proprietary format and no binary blob.
Is it safe to run AI-generated tests?
Yes. The DSL executes in a sandboxed AST interpreter with no require, no fetch and no filesystem access, so AI-generated tests are safe to run.
Which editors and agents does it work with?
unotest is MCP-native and works with Claude Code, Cursor and Codex.

Let your agent write the first test

One command. Any stack. Runs locally, MCP wired up automatically.

$ npx @unotest/web init
Read the docs