Files
cv-site/tests/mjs/34-hyperscript-refactor-comprehensive.test.mjs
T
juanatsap ba44b435e7 refactor: Major hyperscript refactoring and JS elimination
Inline Hyperscript Refactoring:
- Body tag keyboard handlers: 20→8 lines (using helper functions)
- Zoom control handlers: 85→35 lines (using zoom._hs)
- PDF modal card selection: 90→6 lines (3 identical blocks eliminated)

New Hyperscript Files:
- zoom._hs: handleZoomInput, handleZoomReset, initZoomControl
- pdf-modal._hs: selectPdfCard, handlePdfCardKey

JavaScript Elimination (232 lines removed):
- cv-functions.js: REMOVED - hyperscript defs are globally available
- scroll-at-bottom-handler.js: REMOVED - duplicate of handleScroll()
- footer-buttons-interaction.js: REMOVED - moved to hyperscript

Added Tests:
- 32-hyperscript-multi-src.test.mjs: Verifies multi-file loading
- 33-keyboard-shortcuts-refactored.test.mjs: Keyboard shortcuts
- 34-hyperscript-refactor-comprehensive.test.mjs: Full test suite

Key Findings:
- No hyperscript multi-file bug in 0.9.14
- Hyperscript def statements are globally accessible
- Previous refactoring failures were syntax errors, not library bugs
2025-11-30 05:58:44 +00:00

201 lines
7.9 KiB
JavaScript

/**
* Comprehensive test for all hyperscript refactoring
* Tests: keyboard shortcuts, zoom control, PDF modal card selection
*/
import puppeteer from 'puppeteer';
const BASE_URL = 'http://localhost:1999';
async function testAll() {
console.log('🧪 COMPREHENSIVE HYPERSCRIPT REFACTORING TEST\n');
console.log('=' .repeat(60) + '\n');
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox']
});
const page = await browser.newPage();
const errors = [];
page.on('pageerror', err => errors.push(err.message));
page.on('console', msg => {
if (msg.type() === 'error') errors.push(msg.text());
});
let allPass = true;
try {
await page.goto(BASE_URL, { waitUntil: 'networkidle2', timeout: 15000 });
// ==============================================================
// TEST 1: Hyperscript Functions Loaded
// ==============================================================
console.log('1️⃣ Testing hyperscript functions loaded...\n');
const funcs = await page.evaluate(() => ({
// Keyboard functions
handleToggleShortcut: typeof handleToggleShortcut === 'function',
openModalShortcut: typeof openModalShortcut === 'function',
// Zoom functions
initZoomControl: typeof initZoomControl === 'function',
handleZoomInput: typeof handleZoomInput === 'function',
handleZoomReset: typeof handleZoomReset === 'function',
// PDF modal functions
selectPdfCard: typeof selectPdfCard === 'function',
handlePdfCardKey: typeof handlePdfCardKey === 'function',
// Core functions
initScrollBehavior: typeof initScrollBehavior === 'function',
handleScroll: typeof handleScroll === 'function',
printFriendly: typeof printFriendly === 'function'
}));
const funcResults = Object.entries(funcs).map(([name, exists]) => {
const status = exists ? '✅' : '❌';
if (!exists) allPass = false;
return ` ${name}: ${status}`;
});
console.log(funcResults.join('\n'));
console.log();
// ==============================================================
// TEST 2: Keyboard Shortcuts
// ==============================================================
console.log('2️⃣ Testing keyboard shortcuts...\n');
// Test '?' shortcut
await page.keyboard.press('?');
await new Promise(r => setTimeout(r, 400));
const modalOpen = await page.evaluate(() => {
const m = document.getElementById('shortcuts-modal');
return m && m.open;
});
console.log(` '?' opens modal: ${modalOpen ? '✅' : '❌'}`);
if (!modalOpen) allPass = false;
if (modalOpen) {
await page.keyboard.press('Escape');
await new Promise(r => setTimeout(r, 200));
}
// Test 'L' shortcut
const lBefore = await page.evaluate(() => document.getElementById('lengthToggle')?.checked);
await page.keyboard.press('l');
await new Promise(r => setTimeout(r, 400));
const lAfter = await page.evaluate(() => document.getElementById('lengthToggle')?.checked);
const lWorks = lBefore !== lAfter;
console.log(` 'L' toggles length: ${lWorks ? '✅' : '❌'}`);
if (!lWorks) allPass = false;
console.log();
// ==============================================================
// TEST 3: Zoom Control Functions
// ==============================================================
console.log('3️⃣ Testing zoom control...\n');
// Test zoom slider functionality via function call
const zoomTest = await page.evaluate(() => {
const slider = document.getElementById('zoom-slider');
if (!slider) return { error: 'No slider found' };
// Set slider to 150
slider.value = 150;
handleZoomInput(slider);
const wrapper = document.getElementById('zoom-wrapper');
const valueDisplay = document.getElementById('zoom-value-current');
return {
sliderValue: slider.value,
wrapperZoom: wrapper ? wrapper.style.zoom : null,
displayValue: valueDisplay ? valueDisplay.textContent : null
};
});
const zoomSliderWorks = zoomTest.sliderValue === '150' && zoomTest.displayValue === '150';
console.log(` Zoom slider at 150%: ${zoomSliderWorks ? '✅' : '❌'}`);
if (!zoomSliderWorks) allPass = false;
// Test reset function
const resetTest = await page.evaluate(() => {
handleZoomReset();
const slider = document.getElementById('zoom-slider');
const valueDisplay = document.getElementById('zoom-value-current');
return {
sliderValue: slider ? slider.value : null,
displayValue: valueDisplay ? valueDisplay.textContent : null
};
});
const resetWorks = resetTest.sliderValue === '100' && resetTest.displayValue === '100';
console.log(` Zoom reset to 100%: ${resetWorks ? '✅' : '❌'}`);
if (!resetWorks) allPass = false;
console.log();
// ==============================================================
// TEST 4: PDF Modal Card Selection
// ==============================================================
console.log('4️⃣ Testing PDF modal card selection...\n');
// Open PDF modal
await page.evaluate(() => document.getElementById('pdf-modal').showModal());
await new Promise(r => setTimeout(r, 500));
const pdfModalOpen = await page.evaluate(() => {
const modal = document.getElementById('pdf-modal');
return modal && modal.open;
});
console.log(` PDF modal opens: ${pdfModalOpen ? '✅' : '❌'}`);
if (!pdfModalOpen) allPass = false;
if (pdfModalOpen) {
// Test card selection
const cardTest = await page.evaluate(() => {
const shortCard = document.querySelector('[data-cv-format="short"]');
if (!shortCard) return { error: 'Short card not found' };
// Click short card
selectPdfCard(shortCard);
return {
shortSelected: shortCard.classList.contains('selected'),
shortAriaChecked: shortCard.getAttribute('aria-checked'),
defaultNotSelected: !document.querySelector('[data-cv-format="default"]').classList.contains('selected'),
formatStored: window.selectedPdfFormat
};
});
const cardSelectWorks = cardTest.shortSelected && cardTest.shortAriaChecked === 'true' && cardTest.defaultNotSelected;
console.log(` Card selection works: ${cardSelectWorks ? '✅' : '❌'}`);
if (!cardSelectWorks) allPass = false;
// Close modal
await page.keyboard.press('Escape');
await new Promise(r => setTimeout(r, 200));
}
console.log();
// ==============================================================
// SUMMARY
// ==============================================================
console.log('=' .repeat(60));
console.log('\n📊 TEST SUMMARY\n');
console.log(` Overall: ${allPass ? '✅ ALL TESTS PASSED' : '❌ SOME TESTS FAILED'}`);
console.log(` Console errors: ${errors.length ? errors.join(', ') : 'None'}`);
console.log();
await browser.close();
process.exit(allPass && errors.length === 0 ? 0 : 1);
} catch (error) {
console.error('Test error:', error.message);
await browser.close();
process.exit(1);
}
}
testAll();