2025-11-17 13:41:46 +00:00
|
|
|
# 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
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# Run ALL tests (the complete specification)
|
|
|
|
|
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
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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.**
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2025-12-01 13:30:48 +00:00
|
|
|
**Last Updated**: 2025-12-01
|
|
|
|
|
**Test Count**: 39 test files (comprehensive coverage including CMD+K, contact form, and PDF tests)
|
2025-11-17 13:41:46 +00:00
|
|
|
**Status**: Production specification
|
|
|
|
|
**Responsibility**: These tests define what "working" means
|