Skip to Content
Core ConceptsCI & Observability

Testing & CI

Unit tests

Unit and integration tests use Vitest  and live alongside the source they cover (e.g. tax.tstax.test.ts). There are 204 tests.

# Run all tests once pnpm test # Watch mode during development pnpm test:unit

Most tests cover pure functions — price formatting, tax calculation, shipping rules, promotion logic, cart/wishlist cookies, order utilities. Some are DB-backed integration tests that run against a real migrated in-memory SQLite database: they mock $env/dynamic/private to point the db seam at :memory:, then createNodeDb runs the full drizzle/ migration chain (FTS table, seed defaults, stock triggers) so assertions hit real SQL.

vi.mock("$env/dynamic/private", () => ({ env: { DATABASE_URL: ":memory:" } })); import { db } from "../db/index.js";

End-to-end tests

E2E tests use Playwright  and live in e2e/ (11 tests across the smoke and checkout specs). pnpm test:e2e boots its own dev server (on a dedicated port) unless BASE_URL is set.

# Boots its own server pnpm test:e2e # Against an already-running server BASE_URL=http://localhost:5173 pnpm test:e2e

Logging

Server-side logging uses console.error in hooks.server.ts. The handleError hook catches uncaught errors, assigns a unique errorId, and logs structured context (URL, method, stack trace) before returning a generic message to the client.

// hooks.server.ts export const handleError: HandleServerError = async ({ error, event, status, message }) => { const errorId = crypto.randomUUID(); console.error("[error]", { id: errorId, status, url: event.url.pathname, error }); return { message: "An unexpected error occurred", errorId }; };

On the Cloudflare target, Workers observability is enabled in wrangler.jsonc, so logs are available in the Cloudflare dashboard.

Performance budgets

pnpm perf <url> [url...] (scripts/perf.mjs) runs Lighthouse (mobile, applied throttling) against the given URLs and fails when a budget (performance score, LCP, CLS, TBT) is exceeded. It warms the edge caches with two fetches per URL first, discards a bootstrap Lighthouse run, and retries a failed budget once so a single jittery run doesn’t fail the check.

CI workflows

Two GitHub Actions workflows run on pull requests to main. Both use pnpm and Node 22.

WorkflowFilePurpose
CI.github/workflows/ci.ymlLint (pnpm lint) + type check (pnpm check), unit tests (pnpm test), and a build matrix over both targets (node and cloudflare)
E2E Tests.github/workflows/e2e.ymlSeeds a throwaway SQLite database, then runs Playwright
Last updated on