← Toolsjsonui-test-runnerJSON-authored tests that drive a real running app. Screen tests, flow tests, and user-action tests — all in the same action / assertion DSL (targets found by `id`), executed by a per-platform driver so one test file runs against iOS simulator, Android emulator, and a headless browser.~8 min read
JSON test file shapeA test file targets one screen. Each case is a named sequence of steps. Every step is one of two shapes: an `action` (tap / input / scroll / waitFor / …) or an `assert` (visible / notVisible / text / count / state). The target element is identified by its `id` inside the step — there is no separate lookup verb — and the runner preserves state between steps.
tests/screens/learn/installation.test.json
{ "screen": "learn/installation", "cases": [ { "name": "renders_hero", "description": "Install page hero shows the one-liner.", "steps": [ { "assert": "visible", "id": "learn_installation_title" }, { "assert": "contains", "id": "learn_installation_cta_wrap", "text": "curl -fsSL" } ] } ]}The DSLKeep it small: the point of authoring tests as JSON is that an agent can read them, diff them, and regenerate them. Adding a new verb requires platform-driver changes across iOS / Android / Web, so we ration verbs aggressively. If you need something the DSL does not do, first ask whether the screen's spec should expose it instead.
Per-platform driversiOS driver talks to XCUITest. Android driver talks to UIAutomator / Compose Semantics. Web driver drives Playwright. The test file is identical; the driver translates each step into the platform-native idiom. Add a platform by implementing the driver contract — the tests you already have come along for free.
CI integrationShard by platform. iOS tests run on macOS runners with simulators; Android on Linux with emulators or Firebase Test Lab; web on any runner with a headless browser. Exit non-zero on any failure so the CI step fails loud. Keep test files short enough that a single shard runs in under 10 minutes — if a flow needs longer, split it into multiple cases.
.github/workflows/e2e.yml
# .github/workflows/e2e.yml excerptjobs: web-e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: jui build --web-only - run: jui verify --fail-on-diff --platform web - run: npx next start & - run: jsonui-test run --platform web --base http://localhost:3000Keep reading
jsonui-cliThe jsonui-test sub-CLI that executes these files./tools/cli
Writing screen testsTask-focused walk-through: the DSL, per-platform runners, recordings, and CI wiring./guides/testing