|
| 1 | +# Phase 3: Testing — Quick Reference |
| 2 | + |
| 3 | +**Status:** ✅ Complete |
| 4 | +**Test Suite:** 139 Playwright + 30 Mocha unit tests |
| 5 | +**Build:** ✅ Passing |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Quick Navigation |
| 10 | + |
| 11 | +| Section | Purpose | |
| 12 | +|---------|---------| |
| 13 | +| [Running Tests](#running-tests) | Commands to run all test types | |
| 14 | +| [Test File Map](#test-file-map) | Where each test file lives and what it covers | |
| 15 | +| [Fixture Helpers](#fixture-helpers) | Shared utilities in setup.ts | |
| 16 | +| [Color Reference](#color-reference) | Current dark mode color values (post-WCAG fixes) | |
| 17 | +| [WCAG Requirements](#wcag-requirements) | Contrast ratio thresholds | |
| 18 | +| [Troubleshooting](#troubleshooting) | Common issues and fixes | |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Running Tests |
| 23 | + |
| 24 | +### E2E Tests (Playwright) |
| 25 | + |
| 26 | +```bash |
| 27 | +# All tests (Chromium + Firefox + WebKit) |
| 28 | +npx playwright test |
| 29 | + |
| 30 | +# With line reporter (CI-friendly) |
| 31 | +npx playwright test --reporter=line |
| 32 | + |
| 33 | +# Single spec file |
| 34 | +npx playwright test src/test/e2e/dark-mode/accessibility.spec.ts |
| 35 | + |
| 36 | +# Single test by name |
| 37 | +npx playwright test -g "primary text on main background" |
| 38 | + |
| 39 | +# Chromium-only (skip cross-browser compat tests) |
| 40 | +npx playwright test --project=chromium |
| 41 | + |
| 42 | +# Interactive UI mode |
| 43 | +npx playwright test --ui |
| 44 | +``` |
| 45 | + |
| 46 | +### Unit Tests (Mocha) |
| 47 | + |
| 48 | +```bash |
| 49 | +# ThemeManager unit tests |
| 50 | +npx ts-mocha src/test/modules/themeManager.ts --timeout 5000 |
| 51 | +``` |
| 52 | + |
| 53 | +### All Tests Together |
| 54 | + |
| 55 | +```bash |
| 56 | +# Unit + E2E |
| 57 | +npx ts-mocha src/test/modules/themeManager.ts --timeout 5000 && npx playwright test --reporter=line |
| 58 | +``` |
| 59 | + |
| 60 | +--- |
| 61 | + |
| 62 | +## Test File Map |
| 63 | + |
| 64 | +``` |
| 65 | +src/test/ |
| 66 | +├── e2e/ |
| 67 | +│ ├── fixtures/ |
| 68 | +│ │ └── setup.ts # Shared selectors, helpers, color maps |
| 69 | +│ └── dark-mode/ |
| 70 | +│ ├── theme-toggle.spec.ts # 6 tests — button, click, keyboard |
| 71 | +│ ├── theme-persistence.spec.ts # 14 tests — save/restore, edge cases |
| 72 | +│ ├── system-preference.spec.ts # 4 tests — prefers-color-scheme |
| 73 | +│ ├── components.spec.ts # 16 tests — CSS vars, rendered colors |
| 74 | +│ ├── no-fouc.spec.ts # 4 tests — flash prevention |
| 75 | +│ ├── accessibility.spec.ts # 26 tests — WCAG AA, keyboard, ARIA |
| 76 | +│ ├── performance.spec.ts # 12 tests — timing, CLS, architecture |
| 77 | +│ └── browser-compat.spec.ts # 19 tests × 3 browsers |
| 78 | +└── modules/ |
| 79 | + └── themeManager.ts # 30 tests — JSDOM unit tests |
| 80 | +``` |
| 81 | + |
| 82 | +### Playwright Config Projects |
| 83 | + |
| 84 | +| Project | Browser | Tests Run | |
| 85 | +|---------|---------|-----------| |
| 86 | +| `chromium` | Desktop Chrome | All specs **except** browser-compat | |
| 87 | +| `chromium-compat` | Desktop Chrome | browser-compat.spec.ts only | |
| 88 | +| `firefox-compat` | Desktop Firefox | browser-compat.spec.ts only | |
| 89 | +| `webkit-compat` | Desktop Safari | browser-compat.spec.ts only | |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## Fixture Helpers |
| 94 | + |
| 95 | +### setup.ts Exports |
| 96 | + |
| 97 | +```typescript |
| 98 | +// CSS selectors for dark mode elements |
| 99 | +export const selectors = { |
| 100 | + themeToggleButton: 'button.theme-toggle', |
| 101 | + sunIcon: 'svg.theme-toggle__icon--light', |
| 102 | + moonIcon: 'svg.theme-toggle__icon--dark', |
| 103 | + header: 'header.docs-header', |
| 104 | + sidebar: 'div.docs-sidebar', |
| 105 | + sidebarContent: 'aside.docs-sidebar__content', |
| 106 | + pageArticle: 'article.page', |
| 107 | + pageContent: 'section.page__content', |
| 108 | + authForm: 'form.auth-form', |
| 109 | +}; |
| 110 | + |
| 111 | +// localStorage key |
| 112 | +export const STORAGE_KEY = 'codex-docs-theme'; |
| 113 | + |
| 114 | +// Expected CSS variable values per theme |
| 115 | +export const themeColors = { |
| 116 | + light: { |
| 117 | + '--color-bg-main': '#fff', |
| 118 | + '--color-text-main': '#060c26', |
| 119 | + '--color-bg-light': '#f8f7fa', |
| 120 | + '--color-line-gray': '#e8e8eb', |
| 121 | + }, |
| 122 | + dark: { |
| 123 | + '--color-bg-main': '#18181b', |
| 124 | + '--color-text-main': '#e4e4e7', |
| 125 | + '--color-bg-light': '#27272a', |
| 126 | + '--color-line-gray': '#71717a', |
| 127 | + }, |
| 128 | +}; |
| 129 | + |
| 130 | +// Helper functions |
| 131 | +getCSSVariable(page, variable) // Get computed CSS var from :root |
| 132 | +getThemeAttribute(page) // Get data-theme attribute value |
| 133 | +goToThemedPage(page) // Navigate to /auth (has JS bundle) |
| 134 | +``` |
| 135 | + |
| 136 | +--- |
| 137 | + |
| 138 | +## Color Reference |
| 139 | + |
| 140 | +### Dark Mode Palette (Tailwind Zinc — current values) |
| 141 | + |
| 142 | +| Variable | Value | Usage | |
| 143 | +|----------|-------|-------| |
| 144 | +| `--color-bg-main` | `#18181B` | Page background | |
| 145 | +| `--color-bg-light` | `#27272A` | Surface/card backgrounds | |
| 146 | +| `--color-text-main` | `#E4E4E7` | Primary text | |
| 147 | +| `--color-text-second` | `#A1A1AA` | Secondary text | |
| 148 | +| `--color-line-gray` | `#71717A` | Borders, dividers | |
| 149 | +| `--color-button-primary` | `#2563EB` | Primary button bg | |
| 150 | +| `--color-button-warning` | `#C2410C` | Warning/delete button bg | |
| 151 | +| `--color-code-bg` | `#131316` | Code block background | |
| 152 | +| `--color-code-comment` | `#909099` | Code comments | |
| 153 | +| `--color-checkbox-border` | `#71717A` | Checkbox border | |
| 154 | + |
| 155 | +--- |
| 156 | + |
| 157 | +## WCAG Requirements |
| 158 | + |
| 159 | +### Contrast Ratios (WCAG 2.1 AA) |
| 160 | + |
| 161 | +| Type | Minimum Ratio | Examples | |
| 162 | +|------|---------------|----------| |
| 163 | +| Normal text (< 18pt) | **4.5:1** | Body text, labels, code comments | |
| 164 | +| Large text (≥ 18pt / 14pt bold) | **3:1** | Headings | |
| 165 | +| UI component boundaries | **3:1** | Borders, checkboxes, dividers | |
| 166 | +| Text on colored buttons | **4.5:1** | White text on button backgrounds | |
| 167 | + |
| 168 | +### How Contrast Tests Work |
| 169 | + |
| 170 | +Tests in `accessibility.spec.ts` extract CSS variable values live from the page, compute luminance using the WCAG formula, and calculate contrast ratios: |
| 171 | + |
| 172 | +```typescript |
| 173 | +function hexToLuminance(hex: string): number { |
| 174 | + // sRGB → linear RGB → relative luminance |
| 175 | +} |
| 176 | + |
| 177 | +function contrastRatio(hex1: string, hex2: string): number { |
| 178 | + return (lighter + 0.05) / (darker + 0.05); |
| 179 | +} |
| 180 | +``` |
| 181 | + |
| 182 | +--- |
| 183 | + |
| 184 | +## Troubleshooting |
| 185 | + |
| 186 | +### Tests fail with "Target page, context or browser has been closed" |
| 187 | + |
| 188 | +WebKit occasionally drops connections. This is a transient Playwright/WebKit issue. Re-run the tests — it typically passes on retry. |
| 189 | + |
| 190 | +### Tests fail with "Theme toggle button not found" |
| 191 | + |
| 192 | +The greeting page (`/`) with an empty database does NOT include `main.bundle.js`, so ThemeManager won't initialize. Tests use `/auth` which always includes the JS bundle. |
| 193 | + |
| 194 | +### Unit tests fail with "document is not defined" |
| 195 | + |
| 196 | +The JSDOM environment must be set up before importing ThemeManager. The unit test file handles this in `before()` hooks. Run with: |
| 197 | +```bash |
| 198 | +npx ts-mocha src/test/modules/themeManager.ts --timeout 5000 |
| 199 | +``` |
| 200 | + |
| 201 | +### Cross-browser tests are slow |
| 202 | + |
| 203 | +Firefox and WebKit tests run sequentially (1 worker). This is expected — 57 cross-browser tests add ~60s to the total run. Use `--project=chromium` to skip them during development. |
| 204 | + |
| 205 | +### "Port 7777 already in use" |
| 206 | + |
| 207 | +Kill any existing Node processes: |
| 208 | +```bash |
| 209 | +Get-Process -Name "node" -ErrorAction SilentlyContinue | Stop-Process -Force |
| 210 | +``` |
| 211 | + |
| 212 | +### Webpack rebuild required after CSS changes |
| 213 | + |
| 214 | +After modifying any `.pcss` file, rebuild before running tests: |
| 215 | +```bash |
| 216 | +npx webpack --mode=production |
| 217 | +``` |
0 commit comments