This documentation is available as Markdown. For the complete index, see llms.txt. Skip to content

Install & setup

For the complete documentation index, see llms.txt

Requirements

  • Node 20+ (for npx; you don’t need a Node project).
  • Web: any OS. iOS: macOS with Xcode + the iOS Simulator.

Set up a project

Terminal window
# web
npx @unotest/web init
npm install --prefix unotest
# iOS
npx @unotest/mobile install /path/to/Your.app --update-env

init / install scaffold the unotest/ layout, write unotest.config.*, and wire MCP config (.mcp.json / editor settings) so your agent finds the server automatically.

The tests are their own package

unotest/ is a separate npm package — its own package.json, lockfile and node_modules:

your-project/
├── package.json ← yours. init never touches it
└── unotest/
├── package.json ← pins @unotest/web and whatever your helpers import
├── unotest.config.mjs
└── e2e/

The runner is never a dependency of your application. Upgrading unotest cannot collide with your app’s dependency graph, and your app’s peer conflicts cannot break a test run — the two trees never meet.

npm specifically, and a committed unotest/package-lock.json: a box installs a pushed bundle with npm ci. Your application is free to use pnpm, yarn or bun — that half never travels and is never installed.

Where to run commands

From inside unotest/, where npx finds the pinned binary in unotest/node_modules/.bin and no version is ever guessed:

Terminal window
cd unotest
npx @unotest/web e2e welcome

They work from the project root too — the CLI locates the root by looking for unotest/e2e, the way git finds a repository. If you run them often from the root, one line in your own scripts saves the cd, and adds no dependency:

"scripts": { "e2e": "npm --prefix unotest exec unotest-web --" }

Choosing a browser (web)

During init you pick how Chromium is provided:

  • System Chrome / Edge — zero download. Sets channel: "chrome" (or "msedge") in unotest/unotest.config.mjs.
  • Bundled Chromium — Playwright’s build (~150 MB). Run npx @unotest/web install-chromium if you didn’t during init.

You can also run Firefox and WebKit — set browsers in config. Single browser in dev; CI can run all three.

Wire your editor

unotest is an MCP server. After init, these editors pick it up automatically:

  • Claude Code — via .mcp.json and project settings.
  • Cursor / Codex — via their MCP config.

See Connect your editor for details.

Verify

Terminal window
# web
cd unotest && npx @unotest/web e2e welcome
# iOS
npx @unotest/mobile doctor

If something’s off, the CLI prints a single actionable line — no stack traces in normal operation. Set UNOTEST_DEBUG=1 for full diagnostics.

Upgrading

  • 0.27 → 0.28: the suite became a package. unotest/ holds its own package.json, lockfile and config. Migrate with:

    Terminal window
    npx @unotest/web init
    git mv unotest.config.mjs unotest/unotest.config.mjs
    npm install --prefix unotest

    and drop @unotest/web from your application’s package.json. A config left at the project root is refused with these instructions rather than ignored. Two things to check once it runs: a unotest/jsconfig.json include written for the old layout points at ../node_modules (make it ./node_modules/), and a config that derives paths from its own location (dirname(fileURLToPath(import.meta.url))) now sits one level deeper, so those paths need a ...

  • 0.19: run history moved to date shards. The first run of a new version migrates the old flat unotest/.runs/<runId>/ layout by itself. To look first, npx @unotest/web runs migrate --dry-run reports and changes nothing; UNOTEST_RUNS_LEGACY=keep re-files old runs into date shards instead of removing them.

  • Playwright. After an upgrade that moves the pinned Playwright (@unotest/web and @unotest/viewer share it), run npx playwright install once if your browser cache predates it.