Your agent writes the E2E tests.
You review and commit.
unotest is AI-native end-to-end testing. Your AI agent drives your real app over MCP and writes clean, reviewable tests in your repo — for web and for iOS.
Works with Claude Code · Cursor · Codex
unotest web
E2E for web apps. Playwright-vocabulary DSL on a sandboxed engine, driven by your agent over MCP.
unotest mobile
E2E for iOS apps (React Native + native Swift). The agent drives the Simulator through the accessibility tree.
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 to start.
Safe to run blindly
Scenarios execute in a sandboxed AST interpreter — no require, no fetch, no filesystem. AI-generated tests can run without surprises.
What's new
unotest 0.43.1
Released 29 September 2026.
Secret field values stay out of failures and replies
An assertValue failure on a password or one-time-code field now reports only the lengths of the two values, and the same fields show as hidden in a failure's page HTML and in the grounding capture. MCP replies mask registered secrets by name. If you ran 0.43.0 or earlier, search your MCP client's transcripts and your saved run failures for your secrets and credentials, and rotate any you find. Screenshots are not masked.
Handing the wheel over is confirmed, not assumed
take_wheel and release_wheel answer ok only once the paused run has actually handed the wheel over, and abort_runtime answers ok only once the runner has stopped. When the run does not act, the tools answer wheel-not-accepted or stop-not-accepted with what to do next, so an agent no longer clicks in a run it has just given back.
Box commands find the environment themselves
box runs, box run, box queue, box screenshot, bundle push --run and the box_* MCP tools no longer need --env when the box serves a single environment. With several, the refusal lists them.
Revocation lists no longer carry customers' machine names
The list of revoked access that every box reads now carries only token ids, times and a fixed reason. Fixed on the service on 27 September; nothing to install.