Testing: pnpm test and pnpm smoke

Two gates: pnpm test proves the scaffolder still produces every shape correctly; pnpm smoke proves a scaffolded app actually runs in a real browser. Run both before committing any template or scaffolder change.

pnpm test — the 17-shape matrix

pnpm test              # full matrix
pnpm test -- --fast    # skip vite builds (tsc only)

Scaffolds every shape into apps/ under __selftest-* names, installs once, then verifies each. The 17 shapes:

  • webapp-all — all features (+ vite build)
  • webapp-min — --features "" --layout header
  • webapp-macos — example,admin,inbox,feedback on the macos layout
  • webapp-windows — activity,team,billing,api-keys,ai,uploads on the windows layout
  • supabase-all — --db supabase, all features, header layout (+ vite build)
  • supabase-min — --db supabase --features example
  • website / website-blog / website-blog-docs (+ build) / single-page — the react site types
  • static-website / static-blog / static-blog-docs / static-single — the static-stack site types (structure + generated blog/docs files + no leaked tokens or markers)
  • demo-crm — --demo crm (+ vite build)
  • demo-tasks-mod — --demo tasks --fields "+points:number,-notes,-estimate" --features mcp (reshaped fields + MCP wiring)
  • demo-catalog-sb — --demo catalog --db supabase --fields "-sku,+brand:text:Brand" (the SQL variant)

React shapes must be tsc --noEmit clean; Convex shapes share one throwaway _generated created via an anonymous local convex dev --once — except the demo convex shapes (demo-crm, demo-tasks-mod), which run their OWN codegen because their generated schemas add tables and modules.

pnpm smoke <slug> — the runtime gate

pnpm install && pnpm exec playwright install chromium   # one-time prereq
pnpm smoke my-idea

Boots the app and drives Chromium through the happy path. What it proves per app kind:

  • convex webapp — marketing renders, sign up succeeds, the authed shell renders (any layout), example Items CRUD round-trips (if present), every nav page renders, records create + 8 view switches (if present), the demo round-trip (below, if the app was scaffolded with --demo), the 404 page works, zero page errors
  • react site — home renders; blog and docs pages render if present
  • static site — the same checks, served from plain files by a built-in server
  • supabase — marketing renders and the auth panel opens (the authed path needs real project keys, so it is skipped)

The demo round-trip

Apps scaffolded with --demo (or --fields) carry a .demo.json manifest; the smoke reads it and drives the primary generated entity: open its page, click "Load sample data" if the entity has seed rows, create a new row through the + New form, then switch through every available view (list, grid, board, gallery, timeline, calendar, stats, canvas, table — only the ones the config enables) and verify the created row survives. The check reports as "demo round-trip — <id>: seed + create + N views".

A full-page screenshot lands in /tmp/geenius-mvp-smoke/<slug>.png (or <slug>-FAIL.png on failure). Exit code 0 = all checks green.