Skip to main content

Testing Guide

Six runners cover the stack, and one selector decides which of them your change actually needs. This page is the map, the everyday loop, and the commands per surface; the runners' own excellent docs cover everything deeper.

The test map​

RunnerWhat it provesWhere it livesLearn it
StorybookShared UI states, variants, and interactions in isolationStories beside shared components; live at design.greengoods.appstorybook.js.org/docs
VitestUnit and component behavior in shared, client, admin, and agent, plus the contracts package's script testssrc/__tests__/ in each packagevitest.dev
PlaywrightEnd-to-end flows and authentication across client and admintests/ at the root, projects in playwright.config.tsplaywright.dev
MochaIndexer handlers and contract eventspackages/indexer/test/mochajs.org
Foundry (forge)Contract behavior, invariants, gas, and upgrade safetypackages/contracts/test/ and its subfoldersgetfoundry.sh
Node test runnerThe docs generators and audits, the search index, the ontology checks, and the validation selector, all with Node's built-in node --testscripts/docs/*.test.mjs, docs/scripts/*.test.mjs, and scripts/quality/*.test.mjsnodejs.org/api/test

The everyday loop​

Ask the repository what your change needs, run exactly that, and escalate only when the selection says to:

bun run check --plan -- --intent qa

For cache-aware full-scope iteration after targeted proof, bun run test --cache runs everything turbo knows is affected. Two rules apply everywhere: always bun run test, never bun test (the orchestration depends on it), and the pre-push hook reruns the honest subset before anything leaves your machine.

Commands per surface​

Every command below runs from the repository root. --cwd points it at the package, so you can copy any single line on its own.

SurfaceEveryday proofWhen you need more
Clientbun run --cwd packages/client testbun run --cwd packages/client build when routes, rendering, or PWA packaging change
Adminbun run --cwd packages/admin testbun run --cwd packages/admin test --coverage for the fuller pass
Agentbun run --cwd packages/agent test and bun run --cwd packages/agent typecheckBoth, whenever a response shape changes
Sharedbun run --cwd packages/shared test and bun run --cwd packages/shared typecheckbun run --cwd packages/shared check:stories when UI foundations move
Indexerbun run --cwd packages/indexer check:indexing-boundary and bun run --cwd packages/indexer testbun run --cwd packages/indexer codegen first after schema or config changes, then bun run --cwd packages/indexer build
Contractsbun run --cwd packages/contracts test --suite solidity --profile match test/E2EWorkflow.t.sol for one behavior (swap in your test file)bun run --cwd packages/contracts test for the package, bun run --cwd packages/contracts test:audit full for the audit suite
Docsbun run --cwd docs test for the site scripts and components, and bun run check -- --intent qa --only docs-authority for the generators, the Mermaid diagram parser, the audits, and the generated-page drift checkbun run --cwd docs build when pages, generators, or the site config change; it runs the search-index check too

For end-to-end work, run the CI-parity Playwright project that matches your surface. This is the exact command CI runs:

PLAYWRIGHT_APP=client APP_ENV=test bunx playwright test --project=client-ci

Use admin-ci for admin work. bun run browser e2e --preset smoke boots a local web stack and runs the client and admin smoke specs in one go, and bun run browser e2e --help lists the deeper presets.

Manual QA​

  • Tour authenticated client surfaces without a wallet: https://localhost:3001/?mockAuth=steward&presentation=pwa from Getting Started.
  • Check shared UI in Storybook, locally on port 3004 or live at design.greengoods.app, including dark mode and viewport variants.
  • Structured product QA lives in Product QA, with the prioritized test cases and the QA app.
  • When a screenshot is your proof, say where it came from: mock auth on localhost, Storybook, CI Playwright, or a real signed-in browser. Mock auth and Storybook prove layout and states well. Wallet and passkey signing, sessions, the installed app, and offline uploads need a real signed-in browser; the browser evidence rules have the full list.

Reproducing CI locally​

CI Gate aggregates every workflow your change triggers; the GitHub Actions page is the generated inventory of them. The local equivalent of the gate is exactly what the pre-push hook runs. You can invoke it yourself, naming the test that proves your change. This example uses a client test; swap in your own package and test file:

bun run check -- --intent push --reuse-passing-receipts --test-path client:src/__tests__/bootFallback.test.tsx

If a CI check fails that didn't run locally, the selector chose differently under CI conditions; the failing workflow's log names the command to reproduce.

Writing new tests​

Put the test where its surface keeps them and copy the house style from a neighbor:

  • A shared unit test: packages/shared/src/__tests__/ontology/query.test.ts.
  • A client component test: packages/client/src/__tests__/bootFallback.test.tsx.
  • A contract test: packages/contracts/test/E2EWorkflow.t.sol.
  • An end-to-end spec: any file under tests/specs/, wired through playwright.config.ts.

Behavior changes ship with their test in the same PR; the First Contribution page shows where proving fits in the flow.

Next steps​