Files
cv-site/tests/mjs/10-zoom-persistence.test.mjs
T
juanatsap 35a836adf3 fix: restore zoom level persistence on page load
Zoom level persistence was broken because hyperscript was setting the
container's value instead of the slider's value on page load.

Changes:
- Fix zoom-control.html line 10: set #zoom-slider's value (not 'my value')
- Add comprehensive zoom persistence test (10-zoom-persistence.test.mjs)
- Update cv-functions.js documentation to clarify hyperscript interop
- Add zoom control feature to README

Test results: 5/5 tests pass
- Zoom saves to localStorage when changed 
- Zoom restores correctly on page reload 
- Reset to 100% works and persists 

Architecture note:
- Hyperscript 'call' within _="" attributes requires global JS scope
- JavaScript wrappers bridge window exposure to hyperscript evaluate()
- Pattern: window.fn() → _hyperscript.evaluate('hyperscriptFn()')
2025-11-17 16:56:01 +00:00

225 lines
8.4 KiB
JavaScript
Executable File

#!/usr/bin/env bun
/**
* ZOOM PERSISTENCE TEST
* ======================
* Tests that zoom level is persisted to localStorage and restored on page load
*
* Test Flow:
* 1. Load page (desktop viewport >768px)
* 2. Show zoom control
* 3. Change zoom level to 150%
* 4. Verify localStorage updated
* 5. Reload page
* 6. Verify zoom level restored to 150%
* 7. Reset zoom to 100%
* 8. Reload page
* 9. Verify zoom level restored to 100%
*/
import { chromium } from "playwright";
const URL = "http://localhost:1999";
async function testZoomPersistence() {
console.log("🧪 ZOOM PERSISTENCE TEST\n");
console.log("=".repeat(70));
const browser = await chromium.launch({ headless: false });
// Use desktop viewport (>768px) to enable zoom control
const page = await browser.newPage({ viewport: { width: 1400, height: 1080 } });
const errors = [];
const testResults = [];
page.on('console', msg => {
const text = msg.text();
if (msg.type() === 'error') {
errors.push(text);
console.log(`❌ ERROR: ${text}`);
}
});
page.on('pageerror', err => {
errors.push(err.message);
console.log(`❌ PAGE ERROR: ${err.message}`);
});
// ========================================================================
// TEST 1: Show Zoom Control and Verify Initial State
// ========================================================================
console.log("\n1️⃣ Loading page and showing zoom control...");
await page.goto(URL);
await page.waitForTimeout(2000);
// Clear any existing zoom localStorage
await page.evaluate(() => {
localStorage.removeItem('cv-zoom');
localStorage.setItem('cv-zoom-visible', 'true');
});
// Reload to apply clean state
await page.reload();
await page.waitForTimeout(2000);
const zoomControl = await page.$('#zoom-control');
const isVisible = await zoomControl.evaluate(el => !el.classList.contains('zoom-hidden'));
console.log(` Zoom control visible: ${isVisible ? '✅ YES' : '❌ NO'}`);
testResults.push({ test: 'Zoom Control Visibility', passed: isVisible });
// ========================================================================
// TEST 2: Change Zoom to 150% and Verify localStorage
// ========================================================================
console.log("\n2️⃣ Setting zoom to 150%...");
const slider = await page.$('#zoom-slider');
if (slider) {
// Get initial zoom
const initialZoom = await slider.evaluate(el => el.value);
console.log(` Initial zoom: ${initialZoom}%`);
// Set zoom to 150%
await slider.evaluate(el => {
el.value = '150';
el.dispatchEvent(new Event('input', { bubbles: true }));
});
await page.waitForTimeout(500);
// Verify localStorage
const storedZoom = await page.evaluate(() => localStorage.getItem('cv-zoom'));
const displayedZoom = await page.$eval('#zoom-value-current', el => el.textContent);
const sliderValue = await slider.evaluate(el => el.value);
const test2Passed = storedZoom === '150' && displayedZoom === '150' && sliderValue === '150';
console.log(` Slider value: ${sliderValue}%`);
console.log(` Displayed zoom: ${displayedZoom}%`);
console.log(` localStorage: ${storedZoom}%`);
console.log(` ${test2Passed ? '✅ PASS' : '❌ FAIL'}`);
testResults.push({ test: 'Zoom Change and localStorage Save', passed: test2Passed });
} else {
console.log(` ❌ Zoom slider not found`);
testResults.push({ test: 'Zoom Change and localStorage Save', passed: false });
}
// ========================================================================
// TEST 3: Reload Page and Verify Zoom Restored
// ========================================================================
console.log("\n3️⃣ Reloading page to verify zoom persistence...");
await page.reload();
await page.waitForTimeout(2000);
const restoredSlider = await page.$('#zoom-slider');
if (restoredSlider) {
const restoredValue = await restoredSlider.evaluate(el => el.value);
const restoredDisplay = await page.$eval('#zoom-value-current', el => el.textContent);
const restoredLocalStorage = await page.evaluate(() => localStorage.getItem('cv-zoom'));
const test3Passed = restoredValue === '150' && restoredDisplay === '150' && restoredLocalStorage === '150';
console.log(` Restored slider: ${restoredValue}%`);
console.log(` Restored display: ${restoredDisplay}%`);
console.log(` localStorage: ${restoredLocalStorage}%`);
console.log(` ${test3Passed ? '✅ PASS - Zoom persisted correctly!' : '❌ FAIL'}`);
testResults.push({ test: 'Zoom Persistence After Reload', passed: test3Passed });
} else {
console.log(` ❌ Zoom slider not found after reload`);
testResults.push({ test: 'Zoom Persistence After Reload', passed: false });
}
// ========================================================================
// TEST 4: Reset Zoom and Verify Persistence
// ========================================================================
console.log("\n4️⃣ Testing zoom reset to 100%...");
const resetBtn = await page.$('#zoom-reset');
if (resetBtn) {
await resetBtn.click();
await page.waitForTimeout(500);
const resetValue = await page.$eval('#zoom-slider', el => el.value);
const resetDisplay = await page.$eval('#zoom-value-current', el => el.textContent);
const resetLocalStorage = await page.evaluate(() => localStorage.getItem('cv-zoom'));
const test4Passed = resetValue === '100' && resetDisplay === '100' && resetLocalStorage === '100';
console.log(` Reset slider: ${resetValue}%`);
console.log(` Reset display: ${resetDisplay}%`);
console.log(` localStorage: ${resetLocalStorage}%`);
console.log(` ${test4Passed ? '✅ PASS' : '❌ FAIL'}`);
testResults.push({ test: 'Zoom Reset to 100%', passed: test4Passed });
} else {
console.log(` ❌ Reset button not found`);
testResults.push({ test: 'Zoom Reset to 100%', passed: false });
}
// ========================================================================
// TEST 5: Reload and Verify 100% Persisted
// ========================================================================
console.log("\n5️⃣ Reloading page to verify 100% zoom persisted...");
await page.reload();
await page.waitForTimeout(2000);
const finalSlider = await page.$('#zoom-slider');
if (finalSlider) {
const finalValue = await finalSlider.evaluate(el => el.value);
const finalDisplay = await page.$eval('#zoom-value-current', el => el.textContent);
const finalLocalStorage = await page.evaluate(() => localStorage.getItem('cv-zoom'));
const test5Passed = finalValue === '100' && finalDisplay === '100' && finalLocalStorage === '100';
console.log(` Final slider: ${finalValue}%`);
console.log(` Final display: ${finalDisplay}%`);
console.log(` localStorage: ${finalLocalStorage}%`);
console.log(` ${test5Passed ? '✅ PASS' : '❌ FAIL'}`);
testResults.push({ test: 'Reset Zoom Persistence After Reload', passed: test5Passed });
} else {
console.log(` ❌ Zoom slider not found after reload`);
testResults.push({ test: 'Reset Zoom Persistence After Reload', passed: false });
}
// ========================================================================
// FINAL SUMMARY
// ========================================================================
console.log("\n" + "=".repeat(70));
console.log("📊 TEST SUMMARY\n");
const totalTests = testResults.length;
const passedTests = testResults.filter(r => r.passed).length;
const failedTests = totalTests - passedTests;
testResults.forEach(result => {
console.log(` ${result.passed ? '✅' : '❌'} ${result.test}`);
});
console.log(`\n Total: ${passedTests}/${totalTests} tests passed`);
if (errors.length === 0) {
console.log("\n✅ NO CONSOLE ERRORS");
} else {
console.log(`\n${errors.length} CONSOLE ERRORS FOUND:\n`);
errors.forEach((err, i) => {
console.log(`${i + 1}. ${err}`);
});
}
console.log("=".repeat(70) + "\n");
if (failedTests === 0 && errors.length === 0) {
console.log("🎉 ALL TESTS PASSED! Zoom persistence works correctly.");
} else {
console.log("⚠️ SOME TESTS FAILED - See details above");
}
console.log("\nBrowser will stay open for manual inspection.");
console.log("Press Ctrl+C when done.\n");
await new Promise(() => {}); // Keep browser open
}
await testZoomPersistence();