Run the test lanes
SupaCloud runs its tests in named lanes. Each lane has one job, one honest coverage denominator, and one place it runs in CI. This page tells you which lane to run for the change you are making, and how to run it locally.
Pick your lane
Section titled “Pick your lane”| You changed… | Run this |
|---|---|
| Rust logic or persistence | cargo nextest run --workspace --features test-support |
| A Svelte component | npm run test:component (from web/) |
| Frontend TypeScript (stores, contracts, cli) | npx vitest run (from web/) |
| A user-visible flow end to end | npm run test:e2e:nightly against a booted stack |
| A script runtime, connector or other host boundary | the system-external lane (below) |
| The marketing site | npm run build && node scripts/smoke.mjs (from marketing/) |
| The agent runner | npm test (from agent-runners/unified/) |
Backend lanes
Section titled “Backend lanes”The nextest profiles split the Rust suite by what each test needs:
cd servercargo nextest run --workspace --features test-support -P hermetic-unit # no DBcargo nextest run --workspace --features test-support -P db-integration # needs Postgrescargo nextest run --workspace --features test-support -P contract # drift gatesPostgres for the DB lane comes from the repo compose file:
docker compose -f compose.test.yml up -d postgresexport TEST_DATABASE_URL="postgresql://supacloud:supacloud@127.0.0.1:55433/supacloud_test"The system-external lane
Section titled “The system-external lane”Some tests drive a real runtime: the WebAssembly script interpreters, the connector egress path, the FinTS component. They need those runtimes provisioned on disk. Provision them once, then run the lane:
bash scripts/build-script-runtimes.sh # builds js/ts (+ py when componentize-py is present)cd serverREQUIRE_SYSTEM_E2E=1 \SUPACLOUD_SCRIPT_RUNTIME_DIR="$PWD/assets/script-runtimes" \ cargo nextest run --workspace --features test-support -P system-external --run-ignored allComponent tests
Section titled “Component tests”Component tests mount the real Svelte component and drive its states
(loading / empty / error / permission / outcome) and its handlers. They live
next to the component as Foo.component.test.ts:
cd webnpm run test:component # the whole component lanenpm run coverage:component # + the honest all-files coverage report and its ratchetThe coverage denominator is every .svelte and .svelte.ts file — a
component nobody tests shows up as 0 %, never as absent. The ratchet only fails
on a drop below the committed baseline, so adding a new component never reds
the gate; letting coverage rot does.
Browser tests
Section titled “Browser tests”Two browser suites, two purposes:
- Mock suite (
npm run test:smoke) — self-contained: fixture data, scripted WebSocket, its own preview server. Fast, no backend needed. - Real suite (
npm run test:e2e:nightly) — a booted stack (server, database, seeded data). It covers the happy paths and the failure paths: wrong password, expired session, missing permission, validation conflict, server error, double submit, discarded edit.
Boot the real stack with bash scripts/e2e/boot-nightly-stack.sh, and tear it
down with bash scripts/e2e/cleanup-nightly-stack.sh when you are done.