# CV Project - Test Suite ## ⚠️ CRITICAL: SINGLE SOURCE OF TRUTH **These tests ARE the specification. These tests ARE the requirements.** If a test passes but the feature doesn't work → **THE TEST IS WRONG** If a feature works but the test fails → **THE FEATURE IS WRONG** If something breaks and the test didn't catch it → **THE TEST IS INCOMPLETE** ### Non-Negotiable Rules 1. **NO CODE CHANGES without corresponding test validation** 2. **ALL bug fixes MUST include a test that would have caught the bug** 3. **EVERY feature MUST have test coverage before deployment** 4. **IF A TEST PASSES, THE FEATURE MUST WORK PERFECTLY** ## Quick Start ### Go Backend Tests ```bash # Run unit tests (fast, CI-safe) make test # Run ALL tests including integration (requires Chrome) make test-all # Run integration tests only make test-integration # Run with coverage report go test -v -race -coverprofile=coverage.txt ./... go tool cover -html=coverage.txt # View in browser ``` ### Frontend Tests (Playwright) ```bash # Run ALL frontend tests bun tests/run-all.mjs # Run individual test bun tests/mjs/0-zoom.test.mjs bun tests/mjs/1-toggles.test.mjs bun tests/mjs/2-keyboard-shortcuts.test.mjs bun tests/mjs/3-hyperscript.test.mjs bun tests/mjs/4-htmx.test.mjs bun tests/mjs/5-language.test.mjs bun tests/mjs/6-modals.test.mjs bun tests/mjs/7-mobile-responsive.test.mjs ``` --- ## Go Backend Test Structure Go tests are **colocated with source code** (Go convention): ``` internal/ ├── handlers/ │ ├── cv_pages.go │ ├── cv_pages_test.go # Handler tests │ ├── cv_contact_test.go │ ├── cv_htmx_test.go │ ├── cv_security_test.go │ ├── cv_text_test.go │ ├── cv_cmdk_test.go │ ├── pdf_test.go # PDF generation (integration tag) │ └── benchmarks_test.go ├── models/cv/ │ ├── loader_test.go # JSON loading tests │ └── validation_test.go # Data validation tests ├── middleware/ │ ├── preferences_test.go │ └── benchmarks_test.go ├── validation/ │ └── contact_test.go # Form validation tests ├── fileutil/ │ └── fileutil_test.go └── lang/ └── lang_test.go tests/ ├── integration/ │ └── email_test.go # SMTP integration (requires credentials) └── security/ └── contact_security_test.go # Security-focused tests ``` ### Go Test Categories | Category | Command | Description | |----------|---------|-------------| | Unit | `make test` | Fast, CI-safe (skips path-dependent tests) | | Local | `make test-local` | All unit tests (run from project root) | | Integration | `make test-integration` | Requires Chrome/SMTP | | All | `make test-all` | Complete suite with integration | | Benchmarks | `go test -bench=. ./...` | Performance tests | ### CI/CD Integration - **GitHub Actions**: `.github/workflows/test.yml` - **Coverage target**: 70% (warning if below) - **Artifacts**: coverage.txt, benchmark.txt uploaded --- ## Test Suite Structure ``` tests/ ├── mjs/ # 🎯 ACTIVE TESTS - SOURCE OF TRUTH │ ├── 0-zoom.test.mjs │ ├── 1-toggles.test.mjs │ ├── 2-keyboard-shortcuts.test.mjs │ ├── 3-hyperscript.test.mjs │ ├── 4-htmx.test.mjs │ ├── 5-language.test.mjs │ ├── 6-modals.test.mjs │ ├── 7-mobile-responsive.test.mjs │ └── README.md ├── archive/ # Historical tests (reference only) ├── screenshots/ # Visual verification ├── run-all.mjs # Master test runner └── TEST-SUMMARY.md # Complete documentation NO OTHER FILES. NO EXCEPTIONS. ``` ## The 8 Tests (Complete Specification) ### 0-zoom.test.mjs **What it validates:** - Zoom control elements exist and are accessible - Zoom toggle shows/hides control - Zoom slider changes page zoom - Real-time zoom updates (no page refresh) **If this fails:** Zoom functionality is broken ### 1-toggles.test.mjs **What it validates:** - Length toggle (short/long CV) - Icon toggle (show/hide icons) - **with screenshot verification** - Theme toggle (default/clean) - Action bar and menu synchronization - localStorage persistence - Real-time rendering (no refresh needed) **If this fails:** Toggle functionality is broken **Historical bug caught:** Icon toggle class mismatch (.show-logos vs .show-icons) ### 2-keyboard-shortcuts.test.mjs **What it validates:** - L key toggles CV length - I key toggles icons - V key toggles theme - ? key opens shortcuts modal - Shortcuts ignored in input/textarea fields **If this fails:** Keyboard navigation is broken ### 3-hyperscript.test.mjs **What it validates:** - No parse errors on page load - All functions defined (toggleCVLength, toggleIcons, toggleTheme, handleKeyboardShortcut) - Keyboard event handlers work - Def statement count ≤3 (hyperscript parser limit) - Proper operator precedence (parentheses around `or`/`and`) **If this fails:** Hyperscript integration is broken **Historical bug caught:** Exceeded 3 def statement limit ### 4-htmx.test.mjs **What it validates:** - HTMX library loaded - HTMX elements present (hx-get, hx-post, hx-swap, hx-target) - Request/response cycle works - Loading indicators configured **If this fails:** HTMX integration is broken ### 5-language.test.mjs **What it validates:** - Language toggle controls exist - Default language is English - Spanish loads via URL parameter (?lang=es) - Language toggle button works - localStorage/cookie persistence **If this fails:** Internationalization is broken ### 6-modals.test.mjs **What it validates:** - Modal elements exist (info, shortcuts, PDF) - ? key opens shortcuts modal - Info and PDF modals open correctly - ESC key closes modals - Accessibility attributes (role, aria-label, aria-modal) **If this fails:** Modal functionality is broken ### 7-mobile-responsive.test.mjs **What it validates:** - Mobile viewport (375px) - no horizontal scroll - Tablet viewport (768px) - proper layout - Touch interactions (hamburger menu) - Responsive breakpoints (320px - 1920px) - Viewport meta tag - Touch-friendly button sizes (≥44px) - Text readability (≥14px font) **If this fails:** Mobile experience is broken ## Test Output Format Every test provides: - ✅ Clear pass/fail indicators - 📊 Summary of results - ❌ Detailed error messages with file:line references - 🎉 Success confirmation - 💡 Browser stays open for manual verification ## When Tests Fail ### Investigation Protocol 1. **Read the test output** - It tells you EXACTLY what failed 2. **Look at the browser** - Tests leave browser open for inspection 3. **Check screenshots** (if test uses them) 4. **Read the test code** - It's the specification 5. **Fix the code OR fix the test** - One of them is wrong ### Fixing Tests vs Fixing Code **Fix the CODE if:** - The test correctly describes desired behavior - The implementation doesn't match the test - The test caught a real bug **Fix the TEST if:** - The test doesn't match actual requirements - The test has false positives/negatives - The test is outdated **After fixing EITHER, verify:** ```bash bun tests/run-all.mjs # ALL tests must pass ``` ## Adding New Tests ### Numbering Convention Tests are numbered 0-9 for execution order: - Use next available number (8, 9, ...) - Numbers indicate priority/dependency - Master runner auto-discovers numbered tests ### Test Template ```javascript #!/usr/bin/env bun /** * {FEATURE} TEST * ============== * What this validates and why it matters */ import { chromium } from 'playwright'; const URL = "http://localhost:1999"; async function test{Feature}() { console.log('🔍 {FEATURE} TEST\n'); console.log('='.repeat(70)); const browser = await chromium.launch({ headless: false }); const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); const errors = []; const testResults = []; // Track errors page.on('console', msg => { if (msg.type() === 'error') { errors.push(msg.text()); console.log(`❌ ERROR: ${msg.text()}`); } }); // ... test implementation ... // ALWAYS provide summary console.log("\n" + "=".repeat(70)); console.log("📊 TEST SUMMARY\n"); // ... summary ... console.log("\nBrowser will stay open for manual inspection."); console.log("Press Ctrl+C when done.\n"); await new Promise(() => {}); // Keep browser open } await test{Feature}(); ``` ### Required Test Components Every test MUST include: 1. **Clear purpose statement** - What does this test validate? 2. **Error tracking** - Capture console errors 3. **Test results array** - Track pass/fail for each assertion 4. **Summary output** - Show what passed/failed 5. **Browser stays open** - For manual verification 6. **File:line references** - When tests fail ## Test Requirements - **Server**: Running on http://localhost:1999 - **Browser**: Playwright Chromium (headed mode) - **Runtime**: Bun (`#!/usr/bin/env bun`) - **Exit**: Ctrl+C after manual verification ## Archive Directory `tests/archive/` contains 60+ historical tests organized by category: - toggles/ - Toggle implementation evolution - zoom/ - Zoom functionality iterations - hyperscript/ - Hyperscript debugging - htmx/ - HTMX behavior validation - keyboard/ - Keyboard shortcut iterations - language/ - Language switching attempts - visual/ - Visual regression tests - performance/ - Performance benchmarks - integration/ - Full integration tests - misc/ - One-off debugging tests **Purpose**: Historical reference and edge case documentation **Status**: Superseded by systematic test suite **Usage**: Reference only - DO NOT RUN ## Accountability Every time something breaks in production: 1. **Which test should have caught this?** - If test exists → Fix the test - If test missing → Write the test 2. **Why didn't the test catch it?** - Incomplete coverage → Expand test - False positive → Fix assertions - Wrong assumptions → Update spec 3. **How do we prevent this?** - Add regression test - Document in TEST-SUMMARY.md - Update this README ## Success Criteria ✅ All 8 tests pass ✅ Browser manual verification confirms ✅ No console errors ✅ Features work as specified **If any test fails, deployment is BLOCKED.** --- **Last Updated**: 2025-12-01 **Test Count**: 39 test files (comprehensive coverage including CMD+K, contact form, and PDF tests) **Status**: Production specification **Responsibility**: These tests define what "working" means