Files
cv-site/tests/TEST-SUMMARY.md
T
juanatsap 2ca13a218e feat: Extend skeleton loaders to all 13 CV sections with structural fidelity
Implemented comprehensive skeleton loaders for the entire CV curriculum,
providing smooth loading animations during language transitions across
all sections.

**Sections Implemented (13 total):**
- Header (title-badges + personal info)
- Education
- Skills Summary
- Experience (with company logos, descriptions, responsibilities)
- Awards (with logos, issuers, descriptions)
- Projects (with icons, descriptions, tech stacks)
- Courses (with icons, institutions, dates)
- Languages
- References
- Other Information
- Skills Sidebars (left and right)
- Footer

**Key Features:**
- Structural fidelity: Skeletons mirror exact HTML structure of actual content
- Each section has realistic placeholders (e.g., 3 experience items, 2 projects)
- Smooth CSS transitions with shimmer animations
- Zero layout shift
- Component-level architecture allows independent loading states

**Technical Implementation:**
- Modified all section templates in templates/partials/sections/
- Added .component-wrapper with .actual-content + .skeleton-content structure
- Extended skeleton.css with structural skeleton classes
- JavaScript event handlers in main.js already handle all sections via CSS cascade

**Testing:**
- Manual Playwright test: 13/13 component wrappers verified
- Automated test: 7/7 tests passing
- All skeleton loaders show during language switches
- No stuck loading states

**Documentation:**
- Updated tests/TEST-SUMMARY.md with all 13 sections
- Updated doc/2-MODERN-WEB-TECHNIQUES.md with comprehensive details
- Added structural fidelity table showing skeleton elements for each section

Files modified: 14 templates + CSS + 2 docs
2025-11-18 20:18:28 +00:00

12 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 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

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