v0Public beta · CLI for AI coding agents

Your AI tester.
Always on.

mockuser reads your git diff, opens a tunnel to your local app, and generates Playwright tests that actually click through the things your coding agent just changed.

$npm i -g @mockuser/cli
~30s
Diff → tests
0
Selectors written
1 CLI
Any framework
mockuser-cli — ~/projects/shop · zsh
01How it works

Three steps. No config.

Point mockuser at the port your dev server is running on. It handles the rest — tunneling, planning, writing, running.

STEP / 01
Read the diff
mockuser pulls your uncommitted changes from git diff HEAD — the exact surface area your tests need to cover.
diff --git a/checkout/page.tsx
@@ -42,7 +42,11 @@
const onSubmit = async () => {
- await submit(cart)
+ if (!cart.length) return
+ await submit(cart)
+ router.push("/thanks")
}
STEP / 02
Agent explores
An AI agent reads your source files, traces the UI, and plans test scenarios — happy path first, then the edge cases your diff introduced.
toolread_file checkout/page.tsx
toolsearch_files getByRole
toollist_dir components/
→ planning 3 scenarios
STEP / 03
Tests pass. Ship it.
Generated test files land on disk and run against your live dev URL. Results come back structured — pass, fail, or screenshot — ready for you or your coding agent to act on.
checkout.happy✓ 2.4s
checkout.empty-cart✓ 1.1s
checkout.declined✓ 3.2s
3 tests · 6.7sreport ready
02Diff in. Tests out.

One commit changes the form. mockuser writes the tests.

A real example. Left: a small change to a checkout submit handler. Right: the spec mockuser generated for it.

checkout/page.tsx
DIFF · +4 −1
41 const onSubmit = async () => {
42 // guard against empty cart submit
43 if (!cart.length) return
44 await submit(cart)
45 await submit(cart)
46 router.push('/thanks')
47 }
48
49 return (
50 <form onSubmit={onSubmit}>
51 <CartTotal />
52 <button type="submit">Place order</button>
53 </form>
54 )
55}
checkout-empty-cart.spec.ts
GENERATED · 27 lines
1import { test, expect } from '@playwright/test'
2
3test.describe('checkout — empty cart', () => {
4 test('blocks submit when cart is empty', async ({ page }) => {
5 await page.goto('/checkout')
6
7 // cart starts empty per fixture
8 const submit = page.getByRole('button', { name: 'Place order' })
9 await expect(submit).toBeVisible()
10
11 await submit.click()
12
13 // guard added in this diff
14 await expect(page).not.toHaveURL(/\/thanks/)
15 await expect(page.getByText('Your cart is empty'))
16 .toBeVisible()
17 })
18})
03Built like infrastructure

Everything you'd build yourself.
If you had a week.

Secure tunnels
Your local dev server becomes reachable from anywhere — no manual setup, no third-party accounts.
localhost → public url
Agentic exploration
An AI agent reads your codebase and plans test scenarios using the same signals a human tester would.
context-aware
Real browser tests
Output is a folder of standard test files you own. Run them, edit them, commit them. Nothing proprietary.
industry standard
Diff-aware
Tests target what changed — not 200 specs you have to throw away on the next refactor.
git diff HEAD
CI-ready output
Full run reports, screenshots, and structured results. Pipe the generated suite straight into your existing CI.
drop-in compatible
CLI + agent API
AI coding agents like Cursor or Claude Code can call mockuser to verify their own diffs before the PR lands.
agent-friendly
04For AI coding agents

The agent that tests what your agent just built.

Cursor, Claude Code, Codex — pair them with mockuser. They ship the diff; mockuser proves it works in a real browser before the PR lands.

A loop, not a checklist.

Your coding agent calls mockuser via MCP after every meaningful change. Tests run on the live tunnel. Failures come back as structured tool output the agent can read and act on.

  • MCP-nativeDrop one line into your agent's config. mockuser appears as a tool.
  • Structured failure outputSelectors, screenshots, and reasons — formatted for an LLM to consume.
  • Stateless per runEach invocation is fresh. No flaky test pollution between agent edits.
Coding agent
cursor · claude-code
mockuser · mcp
verify_diff()
Playwright
3 passed · 0 failed
Result → agent
trace + screenshots
05Pricing

Pay for runs. Not seats.

A run = one diff → test cycle. Tunnels, traces, and report hosting are included.

Hobby
$0/forever
For solo devs poking at a side project.
  • 50 runs / month
  • 1 tunnel at a time
  • 7-day trace retention
  • Community support
Start free
Team
Custom
For orgs running mockuser in CI at scale.
  • Volume run pricing
  • Self-hosted tunnels
  • SSO + audit log
  • SLA + dedicated Slack
Talk to us
06FAQ

Questions, briefly answered.

No. mockuser writes the .spec.ts files. They are plain Playwright though — you can read, edit, or commit them like any test you wrote by hand.
The agent reads your source files and finds the actual roles, labels, and text in your components. It prefers getByRole and getByLabel over brittle CSS selectors.
The agent itself runs on our backend. Your source code stays on your machine — the CLI streams only the tool results the agent asks for (file contents, directory listings). Tests are written to your local disk.
Yes — that is the whole point. mockuser exposes an MCP server, so Cursor, Claude Code, or any MCP-aware agent can call verify_diff() and read structured results back.
mockuser only writes tests for what the diff touched, so the suite stays small. Each spec is independent. We retry once on infra-level failures (tunnel hiccup) but never on assertion failures.
Anything that serves HTTP. Next.js, Remix, SvelteKit, Rails, Django, plain HTML. Point the CLI at the port, mockuser tunnels it.
07Install

Three commands. First test in 60 seconds.

Ready when you are.

No signup required to install. You'll get prompted for an API key after your first generate — free tier, no card.

Get an API key Star on GitHub
~/projects/your-appzsh
# 1. install the CLI
$npm i -g @mockuser/cli
# 2. authenticate
$mockuser auth <key>
# 3. generate against your running dev server
$mockuser generate -p 3000