Testing & CI
Unit tests
Unit and integration tests use Vitest and live alongside the source they cover (e.g. tax.ts → tax.test.ts). There are 204 tests.
# Run all tests once
pnpm test
# Watch mode during development
pnpm test:unitMost 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:e2eLogging
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.
| Workflow | File | Purpose |
|---|---|---|
| CI | .github/workflows/ci.yml | Lint (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.yml | Seeds a throwaway SQLite database, then runs Playwright |