> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wednesdayai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Tests

# Tests

* Full testing kit (suites, live, Docker): [Testing](/help/testing)

* `pnpm test:force`: Kills any lingering gateway process holding the default control port, then runs the full Vitest suite with an isolated gateway port so server tests don’t collide with a running instance. Use this when a prior gateway run left port 18789 occupied.

* `pnpm test:coverage`: Runs the unit suite with V8 coverage (via `vitest.unit.config.ts`). Global thresholds are 70% lines/branches/functions/statements. Coverage excludes integration-heavy entrypoints (CLI wiring, gateway/telegram bridges, webchat static server) to keep the target focused on unit-testable logic.

* `pnpm test` runs two stages: first `pnpm test:scripts` (`node --test "scripts/**/*.test.mjs"`, the release/CI policy suites), and only if that passes, `node scripts/test-parallel.mjs`. A `test:scripts` failure short-circuits the `&&` and no Vitest lane runs at all.

* `scripts/test-parallel.mjs` then runs the enabled lanes in two groups. **Parallel**: unit, core, channels, extensions, and gateway (gateway is serial unless `OPENCLAW_TEST_PARALLEL_GATEWAY=1` or a high-memory local host). **Serial, after the parallel group**: e2e, plus gateway when it is not parallelized. Every lane is default-on; set `OPENCLAW_TEST_INCLUDE_CORE=0`, `OPENCLAW_TEST_INCLUDE_CHANNELS=0`, `OPENCLAW_TEST_INCLUDE_EXTENSIONS=0`, `OPENCLAW_TEST_INCLUDE_GATEWAY=0`, or `OPENCLAW_TEST_INCLUDE_E2E=0` to skip one. The parallel lanes all run to completion, then the runner exits with the first nonzero lane code **before starting the serial group**. So a failing run with no e2e output either failed `test:scripts` before any lane started, or failed in the parallel group — e2e was never reached, not skipped.

* Dedicated commands still exist for a single lane: `pnpm test:channels`, `pnpm test:extensions`, `pnpm test:gateway`, `pnpm test:e2e`.

* `pnpm test:e2e` (also the serial e2e lane inside `pnpm test`): gateway end-to-end smoke (multi-instance WS/HTTP/node pairing). `vitest.e2e.config.ts` uses `pool: "forks"` — not `vmForks`, because vmForks leaked the `vi.mock` module registry across files in a shared worker — with 1 worker locally and at most 2 in CI, silent unless `OPENCLAW_E2E_VERBOSE=1`. Tune with `OPENCLAW_E2E_WORKERS=<n>` (capped at 16). Files come from `test/**`, `src/**`, and `extensions/**` matching `*.e2e.test.ts`.

* `pnpm test` on Node 24+: OpenClaw auto-disables Vitest `vmForks` and uses `forks` to avoid `ERR_VM_MODULE_LINK_FAILURE` / `module is already linked`. You can force behavior with `OPENCLAW_TEST_VM_FORKS=0|1`.

* `pnpm test:live`: Runs provider live tests (minimax/zai). Requires API keys and `LIVE=1` (or provider-specific `*_LIVE_TEST=1`) to unskip.

## Local PR gate

For local PR land/gate checks, run:

* `pnpm check`
* `pnpm build`
* `pnpm test`
* `pnpm check:docs`

If `pnpm test` flakes on a loaded host, rerun once before treating it as a regression, then isolate with `pnpm vitest run <path/to/test>`. For memory-constrained hosts, use:

* `OPENCLAW_TEST_PROFILE=low OPENCLAW_TEST_SERIAL_GATEWAY=1 pnpm test`

## Model latency bench (local keys)

Script: [`scripts/bench-model.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-model.ts)

Usage:

* `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
* Optional env: `MINIMAX_API_KEY`, `MINIMAX_BASE_URL`, `MINIMAX_MODEL`, `ANTHROPIC_API_KEY`
* Default prompt: “Reply with a single word: ok. No punctuation or extra text.”

Last run (2025-12-31, 20 runs):

* minimax median 1279ms (min 1114, max 2431)
* opus median 2454ms (min 1224, max 3170)

## CLI startup bench

Script: [`scripts/bench-cli-startup.ts`](https://github.com/openclaw/openclaw/blob/main/scripts/bench-cli-startup.ts)

Usage:

* `pnpm tsx scripts/bench-cli-startup.ts`
* `pnpm tsx scripts/bench-cli-startup.ts --runs 12`
* `pnpm tsx scripts/bench-cli-startup.ts --entry dist/entry.js --timeout-ms 45000`

This benchmarks these commands:

* `--version`
* `--help`
* `health --json`
* `status --json`
* `status`

Output includes avg, p50, p95, min/max, and exit-code/signal distribution for each command.

## Onboarding E2E (Docker)

Docker is optional; this is only needed for containerized onboarding smoke tests.

Full cold-start flow in a clean Linux container:

```bash theme={"dark"}
scripts/e2e/onboard-docker.sh
```

This script drives the interactive wizard via a pseudo-tty, verifies config/workspace/session files, then starts the gateway and runs `openclaw health`.

## QR import smoke (Docker)

Ensures `qrcode-terminal` loads under Node 24+ in Docker:

```bash theme={"dark"}
pnpm test:docker:qr
```
