Files
cv-site/tests/TEST-SUMMARY.md
juanatsap 949c9a0351 docs: Consolidate documentation into single doc/ folder
- Move docs/ contents to doc/ with proper numbering:
  - CONTACT-FORM-QUICKSTART.md → 17-CONTACT-FORM.md
  - SECURITY-AUDIT-REPORT.md → 18-SECURITY-AUDIT.md
  - SECURITY.md → 19-SECURITY-IMPLEMENTATION.md
- Delete duplicate/redundant files from docs/:
  - CMD-K-COMMAND-BAR.md (duplicate of 16-CMD-K-API.md)
  - CONTACT_FORM_IMPLEMENTATION.md (overlaps with quickstart)
  - SECURITY-IMPLEMENTATION-SUMMARY.md (summary of audit)
- Update doc/README.md with new document references
- Update test counts to 39 test files across all READMEs
- Update all "Last Updated" dates to 2025-12-01
- Add new API endpoints documentation (text, cmd-k, contact, toggles)
- Update PROJECT-MEMORY.md with new features and correct paths
2025-12-01 13:30:48 +00:00

13 KiB

CV Project - Test Suite Documentation

⚠️ SINGLE SOURCE OF TRUTH

These tests define what "working" means. If a test passes, the feature MUST work. If a feature breaks, a test MUST fail.

Complete testing infrastructure for the CV website application.

Quick Start

# Run all systematic 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
bun tests/mjs/14-button-positioning.test.mjs

Active Test Suite (tests/mjs/)

Systematic numbered tests - the source of truth for functionality verification.

0-zoom.test.mjs

Purpose: Zoom control functionality

  • Zoom control elements exist
  • Zoom toggle shows/hides control
  • Zoom slider changes page zoom
  • Real-time zoom updates (no refresh)

Run: bun tests/mjs/0-zoom.test.mjs

1-toggles.test.mjs

Purpose: Comprehensive toggle testing with real-time visual verification

  • Length toggle (Action Bar)
  • Icon toggle (Action Bar) - with screenshot verification
  • Theme toggle (Action Bar)
  • Length toggle (Menu + Sync)
  • Icon toggle (Menu + Sync) - verifies no refresh needed
  • Theme toggle (Menu + Sync)
  • localStorage persistence
  • Synchronization between action bar and menu

Critical: This test caught the icon toggle bug (class name mismatch: .show-logos vs .show-icons)

Run: bun tests/mjs/1-toggles.test.mjs

2-keyboard-shortcuts.test.mjs

Purpose: Keyboard shortcut functionality

  • L key - Toggle CV length
  • I key - Toggle icons
  • V key - Toggle theme
  • ? key - Open shortcuts modal
  • Input field safety (shortcuts ignored in input/textarea)

Run: bun tests/mjs/2-keyboard-shortcuts.test.mjs

3-hyperscript.test.mjs

Purpose: Hyperscript integrity and parse error detection

  • No parse errors on page load
  • Function definitions verified (toggleCVLength, toggleIcons, toggleTheme, handleKeyboardShortcut)
  • Keyboard event handlers work
  • Def statement count (≤3 limit)
  • Operator precedence validation

Run: bun tests/mjs/3-hyperscript.test.mjs

4-htmx.test.mjs

Purpose: HTMX functionality validation

  • HTMX library loaded
  • HTMX elements present (hx-get, hx-post, hx-swap, hx-target)
  • Request/response cycle
  • Loading indicators

Run: bun tests/mjs/4-htmx.test.mjs

5-language.test.mjs

Purpose: Language switching functionality

  • Language toggle controls exist
  • Default language (English)
  • Spanish via URL parameter (?lang=es)
  • Language toggle button
  • localStorage/cookie persistence

Run: bun tests/mjs/5-language.test.mjs

6-modals.test.mjs

Purpose: Modal functionality and accessibility

  • Modal elements exist (info, shortcuts, PDF)
  • Shortcuts modal opens with ? key
  • Info modal opens
  • PDF modal opens
  • ESC key closes modals
  • Accessibility attributes (role, aria-label, aria-modal)

Run: bun tests/mjs/6-modals.test.mjs

7-mobile-responsive.test.mjs

Purpose: Mobile viewport rendering and interactions

  • 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)

Run: bun tests/mjs/7-mobile-responsive.test.mjs

8-hover-sync.test.mjs

Purpose: Hover state synchronization between UI elements

  • PDF button hover sync (action bar ↔ menu)
  • Print button hover sync (action bar ↔ menu)
  • Zoom control highlight on hover
  • No refresh required for hover effects

Critical: Tests JavaScript wrapper → Hyperscript call pattern

Run: bun tests/mjs/8-hover-sync.test.mjs

9-hyperscript-def-limit.test.mjs

Purpose: Verify NO 3-def limit with hyperscript 0.9.14+

  • Multiple def statements across multiple files
  • All hyperscript functions load correctly
  • Toggle functions work (toggleCVLength, toggleIcons, toggleTheme)
  • Hover sync functions work (syncPdfHover, syncPrintHover, highlightZoomControl)

Historical: Proves hyperscript 0.9.14+ has no def limit

Run: bun tests/mjs/9-hyperscript-def-limit.test.mjs

10-zoom-persistence.test.mjs

Purpose: Zoom level persistence across page reloads

  • Zoom saves to localStorage when changed
  • Zoom restores correctly on reload (e.g., 150%)
  • Reset to 100% works and persists
  • localStorage updates in real-time

Critical: Fixed bug where zoom-control.html:10 set wrong element's value

Run: bun tests/mjs/10-zoom-persistence.test.mjs

11-zoom-ui-exclusion.test.mjs

Purpose: Verify UI elements excluded from zoom

  • Footer outside zoom-wrapper (DOM structure)
  • Action bar outside zoom-wrapper
  • Menu outside zoom-wrapper
  • CV content inside zoom-wrapper
  • UI elements unchanged at 200% zoom
  • CV content properly zooms

Critical: Ensures only CV paper zooms, not UI chrome

Run: bun tests/mjs/11-zoom-ui-exclusion.test.mjs

Test Philosophy

Single Source of Truth: The 12 tests in tests/mjs/ (0-11) are the ONLY tests.

  • No archive, no legacy tests, no redundancy
  • Each test is systematic, comprehensive, and essential
  • If a test doesn't provide unique value, it doesn't exist

Test Infrastructure

Master Test Runner

File: tests/run-all.mjs

Runs all numbered tests in sequence, provides summary report.

bun tests/run-all.mjs

Screenshots

Toggle tests save screenshots to tests/screenshots/:

  • before-icon-toggle.png - Before clicking icon toggle
  • after-icon-toggle.png - After clicking icon toggle

Use these to visually verify real-time rendering changes.

Test Requirements

  • Server: Must be running on http://localhost:1999
  • Browser: Playwright launches Chromium (headed mode for manual verification)
  • Bun: All tests use #!/usr/bin/env bun
  • Exit: Press Ctrl+C after reviewing test results

Test Output Format

All tests provide:

  • Clear pass/fail indicators
  • 📊 Summary of results
  • Detailed error messages
  • 🎉 Success confirmation
  • 💡 Browser stays open for manual verification

Test Development Guidelines

Creating New Tests

  1. Numbering: Use next available number (3, 4, 5...)
  2. Naming: {number}-{feature}.test.mjs
  3. Structure: Follow pattern from existing tests
  4. Documentation: Update this file

Test Template

#!/usr/bin/env bun
/**
 * {FEATURE} TEST
 * ==============
 * Description of what this tests
 */

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 = [];

  // ... test implementation ...

  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}();

Future Enhancements (Optional)

Core functionality COMPLETELY covered. Optional future tests:

  • Print CSS validation (8-print.test.mjs)
  • PDF generation testing (9-pdf.test.mjs)
  • Performance benchmarks - Core Web Vitals
  • Cross-browser - Firefox, Safari
  • Accessibility audit - WCAG AA compliance
  • Advanced interactions - Hover states, scroll behavior

Historical Notes

Test Cleanup - Nov 17, 2025

  • DELETED entire archive directory (tests/archive/)
  • Eliminated 17+ redundant legacy test files
  • Kept ONLY 12 systematic tests (0-11) - single source of truth
  • 100% test redundancy eliminated
  • Zero tolerance for duplicate or unnecessary tests

Key Bug Fixes Caught By Tests

  1. Icon Toggle Bug (1-toggles.test.mjs)

    • Class name mismatch: .show-logos vs .show-icons
    • Required page refresh to see changes
    • Fixed by correcting class names in cv-functions.js
  2. Hyperscript Parser Limit (archived)

    • Max 3 def statements total across all files
    • Moved toggle functions to JavaScript
    • Upgraded hyperscript 0.9.12 → 0.9.14

Contributing

When adding tests:

  1. Keep tests focused (single responsibility)
  2. Make them self-documenting
  3. Provide clear pass/fail criteria
  4. Update this documentation
  5. Add to run-all.mjs automatically (it auto-discovers numbered tests)

Last Updated: 2025-12-01 Test Count: 39 test files - Comprehensive coverage Coverage: Complete (UI, keyboard, HTMX, i18n, modals, mobile, zoom, hover-sync, hyperscript, skeleton loaders, color themes, button positioning, PDF modal, icons, dark theme, course icons, references, toast notifications) Status: SINGLE SOURCE OF TRUTH - Production specification Philosophy: Each test validates specific functionality and edge cases

12-skeleton-language-transitions.test.mjs

Purpose: Skeleton loader animations during language transitions for ALL 13 curriculum sections

  • Component wrapper structure (dual-state: actual + skeleton content) - 13 sections total
  • Skeleton CSS loaded (shimmer animation verified)
  • First language switch (EN → ES) - Loading class added/removed
  • Second language switch (ES → EN) - Consistent behavior
  • Third language switch (EN → ES) - Regression check
  • No stuck loading states (all containers clean after transition)
  • JavaScript event handlers configured (languageSwitching flag)

Sections with skeleton loaders (structural fidelity):

  1. Header (title-badges + personal info)
  2. Education
  3. Skills Summary
  4. Experience (with company logos, descriptions, responsibilities)
  5. Awards (with logos, issuers, descriptions)
  6. Projects (with icons, descriptions, tech stacks)
  7. Courses (with icons, institutions, dates)
  8. Languages
  9. References
  10. Other Information
  11. Skills Sidebar (left) - Technical Skills
  12. Skills Sidebar (right) - More Skills
  13. Footer

Implementation: JavaScript event handlers in static/js/main.js

  • htmx:beforeRequest - Adds .loading class to page containers
  • htmx:afterSettle - Removes .loading class after swap completes (100ms delay)
  • Structural fidelity: Each skeleton mirrors the exact structure of its actual content (logos, text lines, lists)

Critical: Migrated from hyperscript to JavaScript for reliable Playwright testing

Run: bun tests/mjs/12-skeleton-language-transitions.test.mjs

13-color-theme-switcher.test.mjs

Purpose: Color theme switcher with dynamic button colors

  • Button positioning (Download PDF and Print Friendly at top)
  • Theme cycling (auto → light → dark → auto)
  • Dynamic button colors per theme mode
    • Auto: Purple (#9b59b6) 💜
    • Light: Orange/Yellow (#f39c12) ☀️
    • Dark: Blue (#3498db) 🌙
  • Icon changes per theme (sun/moon/auto icons)
  • localStorage persistence
  • data-color-theme attribute updates

Run: bun tests/mjs/13-color-theme-switcher.test.mjs

14-button-positioning.test.mjs

Purpose: Button positioning & responsive layout across all viewport sizes

  • Desktop layout (>900px) - Vertical stacking on left side + back-to-top on right
  • Wide mobile (483-900px) - Horizontal layout at bottom + back-to-top on right
  • Narrow mobile (<483px) - Back-to-top moved UP to avoid overlap (still on right)
  • Button visibility - Zoom hidden in mobile, all buttons clickable
  • Accessibility validation - All buttons have proper attributes

Desktop Layout:

  • Download, Print, Shortcuts, Info → LEFT side, vertically stacked (22rem, 18rem, 6rem, 2rem)
  • Back-to-top → RIGHT side (2rem)
  • Zoom button → VISIBLE

Wide Mobile (483-900px):

  • Download, Print, Shortcuts, Info → Horizontal layout at bottom center
  • Back-to-top → RIGHT side (1.5rem bottom)
  • Zoom button → HIDDEN

Narrow Mobile (<483px):

  • Download, Print, Shortcuts, Info → Horizontal layout at bottom
  • Back-to-top → RIGHT side, MOVED UP (5.5rem bottom) to avoid overlap
  • Zoom button → HIDDEN

Critical: Verifies responsive button positioning fixes including:

  1. Back-to-top always on RIGHT (not left) in mobile
  2. Narrow mobile (<483px) moves back-to-top UP to prevent overlap
  3. Consistent hover effects across all buttons

Run: bun tests/mjs/14-button-positioning.test.mjs

New Tests (2025-11-17/18)

  • 8-hover-sync.test.mjs - JavaScript wrapper → Hyperscript call pattern
  • 9-hyperscript-def-limit.test.mjs - Proves no 3-def limit with 0.9.14+
  • 10-zoom-persistence.test.mjs - Zoom level localStorage persistence
  • 11-zoom-ui-exclusion.test.mjs - UI elements excluded from zoom
  • 12-skeleton-language-transitions.test.mjs - Skeleton loaders for language switch
  • 13-color-theme-switcher.test.mjs - Dynamic color theme switcher
  • 14-button-positioning.test.mjs - Button positioning & responsive layout