···5454 - [Unit tests](#unit-tests)
5555 - [Component accessibility tests](#component-accessibility-tests)
5656 - [Lighthouse accessibility tests](#lighthouse-accessibility-tests)
5757+ - [Lighthouse performance tests](#lighthouse-performance-tests)
5758 - [End to end tests](#end-to-end-tests)
5859 - [Test fixtures (mocking external APIs)](#test-fixtures-mocking-external-apis)
5960- [Submitting changes](#submitting-changes)
···114115pnpm test:nuxt # Nuxt component tests
115116pnpm test:browser # Playwright E2E tests
116117pnpm test:a11y # Lighthouse accessibility audits
118118+pnpm test:perf # Lighthouse performance audits (CLS)
117119```
118120119121### Project structure
···641643642644# Or run a single color mode manually
643645pnpm build:test
644644-LIGHTHOUSE_COLOR_MODE=dark ./scripts/lighthouse-a11y.sh
646646+LIGHTHOUSE_COLOR_MODE=dark ./scripts/lighthouse.sh
645647```
646648647649This requires Chrome or Chromium to be installed. The script will auto-detect common installation paths. Results are printed to the terminal and saved in `.lighthouseci/`.
648650649651#### Configuration
650652651651-| File | Purpose |
652652-| ---------------------------- | --------------------------------------------------------- |
653653-| `.lighthouserc.cjs` | Lighthouse CI config (URLs, assertions, Chrome path) |
654654-| `lighthouse-setup.cjs` | Puppeteer script for color mode + client-side API mocking |
655655-| `scripts/lighthouse-a11y.sh` | Shell wrapper that runs the audit for a given color mode |
653653+| File | Purpose |
654654+| ----------------------- | --------------------------------------------------------- |
655655+| `.lighthouserc.cjs` | Lighthouse CI config (URLs, assertions, Chrome path) |
656656+| `lighthouse-setup.cjs` | Puppeteer script for color mode + client-side API mocking |
657657+| `scripts/lighthouse.sh` | Shell wrapper that runs the audit for a given color mode |
658658+659659+### Lighthouse performance tests
660660+661661+The project also runs Lighthouse performance audits to enforce zero Cumulative Layout Shift (CLS). These run separately from the accessibility audits and test the same set of URLs.
662662+663663+#### How it works
664664+665665+The same `.lighthouserc.cjs` config is shared between accessibility and performance audits. When the `LH_PERF` environment variable is set, the config switches from the `accessibility` category to the `performance` category and asserts that CLS is exactly 0.
666666+667667+#### Running locally
668668+669669+```bash
670670+# Build + run performance audit
671671+pnpm test:perf
672672+673673+# Or against an existing test build
674674+pnpm test:perf:prebuilt
675675+```
676676+677677+Unlike the accessibility audits, performance audits do not run in separate light/dark modes.
656678657679### End to end tests
658680
···11-#!/bin/bash
22-# Run Lighthouse accessibility tests in both light and dark mode
33-#
44-# This script runs lhci autorun twice, once for each color mode.
55-# The LIGHTHOUSE_COLOR_MODE env var is read by lighthouse-setup.cjs
66-# to set the appropriate theme before each audit.
77-88-set -e
99-1010-case "${LIGHTHOUSE_COLOR_MODE}" in
1111- dark)
1212- echo "🌙 Running Lighthouse accessibility audit (dark mode)..."
1313- pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/dark"
1414- ;;
1515- light)
1616- echo "☀️ Running Lighthouse accessibility audit (light mode)..."
1717- pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/light"
1818- ;;
1919- *)
2020- echo "⚠️ Missing or invalid LIGHTHOUSE_COLOR_MODE. Use 'dark' or 'light'."
2121- exit 1
2222- ;;
2323-esac
2424-2525-echo ""
2626-echo "✅ Accessibility audit completed"
+37
scripts/lighthouse.sh
···11+#!/bin/bash
22+# Run Lighthouse CI audits.
33+#
44+# Modes:
55+# - Accessibility (default): requires LIGHTHOUSE_COLOR_MODE (dark/light)
66+# - Performance: set LH_PERF=1 (no color mode needed)
77+#
88+# The LIGHTHOUSE_COLOR_MODE env var is read by lighthouse-setup.cjs
99+# to set the appropriate theme before each audit.
1010+1111+set -e
1212+1313+if [ -n "${LH_PERF}" ]; then
1414+ echo "⚡ Running Lighthouse performance audit (CLS)..."
1515+ pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/perf"
1616+ echo ""
1717+ echo "✅ Performance audit completed"
1818+ exit 0
1919+fi
2020+2121+case "${LIGHTHOUSE_COLOR_MODE}" in
2222+ dark)
2323+ echo "🌙 Running Lighthouse accessibility audit (dark mode)..."
2424+ pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/dark"
2525+ ;;
2626+ light)
2727+ echo "☀️ Running Lighthouse accessibility audit (light mode)..."
2828+ pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/light"
2929+ ;;
3030+ *)
3131+ echo "⚠️ Missing or invalid LIGHTHOUSE_COLOR_MODE. Use 'dark' or 'light'."
3232+ exit 1
3333+ ;;
3434+esac
3535+3636+echo ""
3737+echo "✅ Accessibility audit completed"