saasprokit
Testing

Testing Overview

Test strategy, coverage summary, and how to run tests in this SaaS boilerplate

Test Strategy

This project uses two levels of testing:

TypeToolLocationStatus
E2E TestsPlaywrightapps/web/e2e/See E2E Tests
Unit TestsVitest@repo/auth, apps/web, @repo/databaseSee Unit Tests
CLI testsVitestscripts/**/*.test.tspnpm test:cli (root vitest.config.mts) — not inside pnpm test
Integration TestsNot started

pnpm test is cached turbo test and only runs packages with a test script (app, @repo/auth, @repo/database). CI (.github/workflows/ci.yml) always runs unit + pnpm test:cli. Playwright is .github/workflows/e2e.yml, gated on the e2e PR label — default CI does not run it.

Coverage Summary

E2E Coverage by Feature Area

See E2E Tests for the file-by-file breakdown (npx playwright test --list in apps/web). Folders: public/, auth/, account/, admin/, dashboard/, members/, payment/, plus setup/, fixtures/, helpers/, and opt-in capture/.

Unit Test Coverage

See Unit Tests for the file-by-file list. @repo/storage and @repo/utils have no test files (and no Vitest config at all).

Package/AppFiles
@repo/authsee Unit Tests
apps/websee Unit Tests
@repo/databaseredact.test.ts
root CLIscripts/**/*.test.ts via pnpm test:cli

Uncovered Areas

AreaType NeededPriority
Plan comparison helpers (comparePlans, getPlanLimits, getAnnualSavingsPercent)UnitMedium
Storage quota validationUnitMedium
Slug generation & validationUnitLow
Date utilitiesUnitLow
Stripe webhook idempotency (claimWebhookEvent)IntegrationHigh
Auth middleware / session validation (middleware.ts)IntegrationMedium

Running Tests

E2E Tests (Playwright)

# E2E Postgres on 5433 + MailDev
docker compose -f docker-compose.e2e.yml up -d

# All default Playwright projects (not capture)
pnpm --filter app test:e2e

pnpm --filter app test:e2e:ui
pnpm --filter app test:e2e:auth   # --project=no-auth
pnpm --filter app test:e2e:app    # --project=authenticated
pnpm --filter app capture         # CAPTURE=1, e2e/capture/*.capture.ts

Unit Tests (Vitest)

# turbo test — app, @repo/auth, @repo/database only
pnpm test

# Setup CLI tests (not in turbo)
pnpm test:cli

pnpm --filter @repo/auth test
pnpm --filter app test
pnpm --filter @repo/database test

Test File Organization

E2E Tests

E2E specs live in domain folders under apps/web/e2e/: account/, admin/, auth/, dashboard/, members/, payment/, public/, plus fixtures/, helpers/, and setup/ for shared test infrastructure (e.g. the Maildev REST helper — see Local Development). See E2E Tests for the full file list.

Unit Tests

Unit tests are co-located with their source files:

packages/auth/permissions.test.ts
packages/auth/billing-authorize.test.ts
packages/auth/helpers.test.ts
packages/auth/admin-bootstrap.test.ts
packages/auth/ba-i18n.test.ts
packages/auth/two-factor-hooks.test.ts
packages/auth/server-wiring.test.ts
apps/web/lib/routes.test.ts
apps/web/lib/parsers.test.ts
apps/web/app/[locale]/(app)/admin/users/guards.test.ts
apps/web/hooks/use-action-result.test.ts
apps/web/lib/auth/action-error.test.ts
apps/web/lib/billing/checkout-queries.test.ts
apps/web/lib/seo-config.test.ts
packages/database/redact.test.ts

See Unit Tests for what each file covers.

How E2E is wired

Four Playwright projects in apps/web/playwright.config.ts by default — auth-setup and org-setup run first and gate authenticated, while no-auth runs without a login. A fifth capture project is prepended only when CAPTURE=1 (pnpm --filter app capture). Local infra: docker compose -f docker-compose.e2e.yml up (Postgres on 5433, Maildev). CI (.github/workflows/e2e.yml) is gated on the e2e PR label. Project-by-project table: E2E Tests.

On this page