Files
cv-site/tests
juanatsap 531433f54c fix: Remove toast notification from PDF download flow
Simplified PDF download UX to use only the modal loading overlay,
removing the redundant toast notification that appeared when the modal
was closed during download. Updated tests to reflect the new behavior.

Changes:
- Removed toast trigger logic from PDF modal download function
- Removed modal close event listener for toast display
- Updated toast notification test expectations
- Fixed recommended card outline styling
2025-11-20 14:35:22 +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

# 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:

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

#!/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-11-20 Test Count: 28 active tests (0-29 numbered + migration tests) Status: Production specification Responsibility: These tests define what "working" means