Files
cv-site/tests/TEST-SUMMARY.md
T
juanatsap f3cce51fb3 feat: implement color theme switcher with dynamic button colors
Complete color theme system (light/dark/auto) with dynamic UI:

Features:
- Color theme switcher with auto/light/dark modes
- Dynamic button colors on hover (purple/yellow/blue per theme)
- localStorage persistence across sessions
- Proper button positioning (desktop and mobile)
- Mobile: 5-button layout with theme before info button

Fixes:
- CSP updated to allow jsDelivr CDN for iconify icons
- Button repositioning: Download PDF and Print Friendly at top
- Hover-only colors (not persistent)
- Mobile button order corrected

Files:
- static/css/color-theme.css - Theme system with CSS variables
- static/js/color-theme.js - Theme switching logic
- templates/partials/color-theme-switcher.html - Button component
- internal/middleware/security.go - CSP fix for jsDelivr
- tests/mjs/13-color-theme-switcher.test.mjs - Comprehensive test
- tests/TEST-SUMMARY.md - Updated test documentation
2025-11-18 15:49:30 +00:00

10 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

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-11-18 Test Count: 14 active (0-13) - NO archive, NO legacy tests Coverage: Complete (UI, keyboard, libraries, i18n, modals, mobile, zoom, hover-sync, hyperscript, skeleton loaders, color themes) Status: SINGLE SOURCE OF TRUTH - Production specification Philosophy: Zero redundancy - Every test is essential and unique

12-skeleton-language-transitions.test.mjs

Purpose: Skeleton loader display during language transitions

  • Skeleton loaders appear during language switch
  • Content replaced without full page reload
  • Skeleton removed after content loads
  • No layout shift during transition

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

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