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

# Testing

# Testing

HQ has automated tests across four runtimes and a manual integration test plan for Docker stack validation.

## Automated tests

Run the full automated suite locally:

```bash theme={null}
make test              # UI + Python + Shell (fast local gate, ~60s)
make test-coverage     # Same, with coverage reports + threshold enforcement
make ci-fast           # Lint + tests (mirrors the PR gate)
```

### What's tested

| Runtime          | Framework                              | Tests   | What it covers                                                                                                       |
| ---------------- | -------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| TypeScript (UI)  | Vitest + jsdom + React Testing Library | \~2,270 | Hooks, lib modules, components, server actions, API routes                                                           |
| Python (Gateway) | pytest                                 | 208     | All gateway daemons (command runner, dispatcher, embedder, secrets sync, source sync, plugin runner, file processor) |
| Shell (Scripts)  | bash runner                            | 11      | Gateway lifecycle scripts                                                                                            |
| Database         | psql assertions (CI only)              | \~50    | RLS policies, schema contracts, triggers                                                                             |

### CI pipeline

Every PR runs 8 parallel jobs: `ui-lint`, `ui-test`, `ui-build`, `worker`, `python-lint`, `python-test`, `shellcheck`, `shell-test`. Pushes to `main` add `db-contracts` (live Postgres) and `coverage-report` with artifact upload.

Coverage thresholds (statements: 40%, lines: 40%, branches: 35%, functions: 35%) are enforced in CI. If you add new source files, run `make test-coverage` locally to verify.

### Writing tests

See [`TESTING.md`](https://github.com/yourhq/yourhq/blob/main/TESTING.md) in the repo root for the full guide: test structure, mock patterns, factories, and rules.

## Manual integration testing

Staged test plan for validating the Docker stack. Each stage is independently testable; stop at the first failure, debug, retry that stage.

## Environment

Recommended: **GitHub Codespaces** on this repo's default branch.

* Open the repo on GitHub → **Code → Codespaces → Create codespace**.
* Wait \~3 min for the devcontainer to boot.
* The `postCreateCommand` installs UI deps, copies `.env.example` → `.env`, and prints a quick-start banner.

Ports forwarded automatically: `3000` (UI). noVNC is proxied through the UI — no separate port needed.

You'll also need a **throwaway Supabase project** — do not point this at production while testing. Go to [supabase.com](https://supabase.com), create a free project, and run every SQL file in [`db/migrations/`](https://github.com/yourhq/yourhq/tree/main/db/migrations) in filename order. Then copy the URL, anon key, and service role key for browser onboarding.

## Stage 1 — UI build and run

Prove the UI Dockerfile is correct and the standalone build works in a container.

```bash theme={null}
docker compose build ui
docker compose up -d ui
docker compose logs -f ui
```

Expected:

* Build completes without errors (first build: 3–5 min — Next.js compile + optimize).
* `ui` container shows "Ready on [http://0.0.0.0:3000](http://0.0.0.0:3000)" in logs.
* Codespaces shows a notification for port 3000; click to open the URL.
* Browser loads the onboarding or login page. If the workspace registry is empty, onboarding is expected.

Common failures:

* `ENOENT ./public/...` → a COPY path in the Dockerfile is wrong.
* `Cannot find module ...` → a build-time dep didn't make it into the standalone bundle; check `next.config.ts` has `output: "standalone"`.

**Tear down:** `docker compose down ui`

## Stage 2 — UI backed by your throwaway Supabase

Prove the UI connects to Supabase and renders real data.

1. Start the UI and complete browser onboarding with the throwaway Supabase URL, anon key, and service role key.
2. Create or sign in with a Supabase auth user when prompted. You can also create one manually in Supabase → Authentication → Users → Add user.

```bash theme={null}
docker compose up -d ui
```

Expected:

* Open the UI, log in with the user you just created.
* Onboarding wizard appears (fresh workspace).
* Complete the wizard (welcome → intent → infrastructure → provider → agent). Workspace marked initialized, first agent created.
* Navigates to Tasks page with first task pre-filled. Dashboard loads. Sidebar footer says "HQ".

## Stage 3 — Gateway stack against the same Supabase

Bring up gateway + dispatcher + runner. UI stays off for this stage.

```bash theme={null}
docker compose --profile gateway up -d
docker compose logs -f gateway dispatcher runner embedder file-processor
```

Expected sequence in `gateway` logs:

1. `First boot — initializing bare repo at /home/openclaw/.openclaw/repo.git`
2. `Seeding templates from /opt/templates ... ✓ seeded branch default`, then 15 more templates (16 total).
3. `Starting Xtigervnc :1 ...`
4. `Running openclaw onboard ...` (may take 30–60s).
5. `Patching openclaw.json ...`
6. `Starting VNC server on :1 ...`
7. `Starting websockify on 127.0.0.1:6901 -> localhost:5901 ...`
8. `Registering gateway default in Supabase ... ✓ registered`
9. `Starting openclaw gateway ...`

Verify from the UI (bring UI up alongside):

```bash theme={null}
docker compose up -d ui
```

* Navigate to Settings → System. You should see one gateway `default` with status `online` and `last_seen_at` recent.

The `runner` container logs should show `Starting command runner for gateway=default (Primary gateway)`.

Common failures:

* Git clone failure on `GIT_REMOTE_URL` — expected if unset (templates seed locally instead).
* `openclaw onboard` exits non-zero — check Node version inside container (`docker compose exec gateway node --version` → must be 24).
* `Registering gateway ...` fails with 403 → `SUPABASE_SERVICE_ROLE_KEY` is wrong or the gateways table doesn't exist (re-run the migration).

## Stage 4 — Codex OAuth

One-time, writes the token into the `openclaw-state` volume shared by all agents on this gateway.

```bash theme={null}
docker compose exec gateway openclaw models auth login \
  --provider openai-codex --set-default
```

Follow the prompts: paste URL in a browser, paste the redirect back.

Expected: `Auth profile saved`.

## Stage 5 — Create an agent end-to-end

Through the UI: navigate to Agents → New Agent → pick the Cofounder template → give it a name/slug → choose a channel (e.g. Telegram) and enter credentials → click Create.

Watch `docker compose logs -f runner`:

* Command `provision` leased.
* `add-agent.sh cofounder-xyz --channel telegram --telegram-token ...` runs.
* Git worktree created at `/home/openclaw/.openclaw/workspace-.../`.
* `openclaw.json` patched with the agent entry and channel binding.
* Gateway restarted.

Agent should appear in the UI as `online` within a minute.

For Telegram/Discord: send a DM to the bot. Expect a pairing code reply. Paste the code into the agent's detail page. Command runner runs `openclaw pairing approve <channel> <code>`. Next message triggers the agent. For Slack: the agent is active immediately — no pairing step.

## Stage 6 — noVNC desktop view

Open the UI and navigate to an agent's detail page → click the **Desktop** button (or Settings → Gateways → Desktop).

Expected: the noVNC modal loads inside the UI. The XFCE desktop appears with (probably) the agent's Chrome window if an agent is running. The UI proxies noVNC through `/api/novnc` — no separate port needed.

## Tear down

```bash theme={null}
docker compose down           # stops containers, keeps volumes
docker compose down -v        # stops + removes volumes (clean slate)
```

## What this does NOT test

* Tailscale join — disabled in Codespaces (NET\_ADMIN + tun device behavior differs in the devcontainer env).
* Public HTTPS mode — needs a real domain + DNS record.
* Multi-arch builds — CI/GHCR catches that separately.
* The `curl | bash` installer flow — best tested on a fresh VPS (see below).

## After Codespaces: real-host validation

Once everything above passes, spin up a small VPS (\$5/mo on Hetzner) or EC2 t3.small. SSH in and run:

```bash theme={null}
curl -fsSL https://raw.githubusercontent.com/yourhq/yourhq/main/installer/install.sh | bash
```

This exercises the real OSS install UX. Validates: Docker install prereq check, interactive prompts, `.env` generation, image pull from GHCR, first-boot on a host you didn't pre-configure. Tear down the VPS after.
