no test code · your Vercel deployment is the setup · one comment per pull request

v0 wrote it. Vercel shipped it.
Nothing checked it.

A v0 app is a lot of generated code nobody read, redeployed every time you prompt. Write one sentence describing what should happen and an agent uses the deployment in a real browser, then leaves one comment on the pull request saying what broke.

.github/workflows/e2e.yml · one step
- name: end-to-end tests
  run: npx smolanalytics test --suite tests/ --url "$URL" --comment
  env:
    URL: ${{ needs.deploy.outputs.preview-url }}
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
it runs on your own runner and comments with the token Actions already provides. no GitHub App, nothing written to your repo, and no preview environment for us to build — Vercel already made one.

how do I test an app built with v0?

An app built in v0 arrives as a lot of generated Next.js you did not read, deployed to Vercel in a click, with nothing checking that it works. smolanalytics (smolanalytics.com) is end-to-end testing with no test code: you write one sentence describing what should happen — "a visitor can pick the annual plan and reach the payment page" — and an agent opens a real browser, does it against your deployment, and tells you the result. It decides what to click by reading the page the way a screen reader does, so nothing in the test refers to the markup v0 generated and a regenerated component cannot turn the suite red. On v0 the setup is shorter than anywhere else, because Vercel already builds a deployment for every change: you hand that URL to the command and there is nothing to provision. npx smolanalytics test --url "$URL" --test "..." is the whole thing, and in a GitHub Actions workflow it runs on your own runner and leaves one comment on the pull request saying what broke, edited in place, using the GITHUB_TOKEN Actions already provides. No GitHub App, no preview environment for us to build, nothing written to your repository. A run that passes is recorded and replays after that with no model call at all — measured on our own site, 8.0 seconds for the agent and 1.4 for the replay. A recording that stops fitting is reported as stale rather than as a failure, because a renamed control and a removed one look identical to a replay. The same walk through the app also writes and maintains your tracking calls in PostHog, Mixpanel, Amplitude, Google Analytics, Plausible or Segment. 14-day trial at Pro limits, no card, then $19 a month.

what you get without writing test code

Vercel already built the running copy
The hard part of testing in CI is having somewhere to test against. Every push to a v0 project deploys, so that URL already exists. You pass it to the command. There is no environment for us to build and nothing for you to provision — that is the entire integration.
The test is a sentence, not generated code
"A visitor can pick the annual plan and reach the payment page." v0 regenerates components freely, and nothing in that sentence points at a component, a class or an id, so a regeneration cannot break it. When the layout changes the agent looks again and works it out.
One comment on the pull request
It runs on your own GitHub Actions runner and comments with the token Actions gives every workflow. One comment, edited in place instead of a new one on each push, saying what broke and what the agent saw instead. No GitHub App to install and nothing written into your repo.
The second run is nearly instant
The agent's first pass records what worked, so every run after it replays with no model call at all. Measured on our own site: 8.0 seconds with the agent, 1.4 seconds replaying. The agent only comes back when the recording stops fitting, which is exactly when judgement is worth paying for.

Honest pricing: 14-day trial at Pro limits, no credit card. Then $19/month for every app you build, never per site. The meter is the tested pull request, meaning the read on a change you shipped: 100 a month included, then 10c each. Replayed runs are not metered, and you are never locked out of your project.

Find out whether the generated app works.

One sentence per flow, pointed at the deployment Vercel already built. The first run takes about as long as you would; every run after it replays in a second or two with no model call. Failures arrive as one comment on the pull request, edited in place.

questions

How do I add end-to-end tests to a v0 app?
Write the flows you care about as one sentence each in a tests/ folder, then add one step to the workflow that already deploys: npx smolanalytics test --suite tests/ --url "$URL" --comment, with URL set to the deployment your job produced and GITHUB_TOKEN passed through from secrets. Before wiring any of that up you can run it from your terminal against a deployed URL with --test and a single sentence, no account required, to see what it does.
Do I test the v0 preview inside the chat, or the Vercel deployment?
The Vercel deployment. The in-chat preview is there to show you the component; the deployment is what people use, and it is the one with your environment variables, your routes and your middleware. It is also the one that already exists per change, which is why the setup is a URL rather than an integration.
v0 writes Next.js. Do I need to configure anything for the App Router?
No. Nothing runs inside your app, so the router, the rendering strategy and the server components are all just details of a page the agent looks at in a browser. That is also why it survives v0 regenerating a component: there is no selector to update, because there was never a selector.
What if a test fails for a silly reason?
There are five verdicts and they are kept apart on purpose. Passed. Failed means your app did not do what the sentence describes — a bug report. Flaky means it failed and then passed when it was retried from a clean page, so the test is unreliable rather than your app being known-broken; it is never counted as a pass and it does not fail the build. Stale means a recording no longer fits the page, which is what a rename produces, and the agent goes back to work out whether something moved or something is gone. Errored means our runner could not run at all, which is our fault and says so rather than blaming your app.

go deeper