#!/usr/bin/env bun /** * KEYBOARD SHORTCUTS TEST * ======================== * Tests keyboard shortcuts: L (length), I (icons), V (theme), ? (help) * - Verifies shortcuts work when NOT in input fields * - Verifies shortcuts are IGNORED in input/textarea fields * - Tests all three main toggles via keyboard */ import { chromium } from 'playwright'; const URL = "http://localhost:1999"; async function testKeyboardShortcuts() { console.log('⌨️ KEYBOARD SHORTCUTS 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 = []; page.on('console', msg => { if (msg.type() === 'error') { errors.push(msg.text()); console.log(`❌ ERROR: ${msg.text()}`); } }); console.log("\n1️⃣ Loading page..."); await page.goto(URL); await page.waitForTimeout(2000); // ======================================================================== // TEST 1: L key toggles CV length // ======================================================================== console.log("\n2️⃣ Testing 'L' Key (Toggle CV Length)..."); const lengthTest = await page.evaluate(async () => { const paper = document.querySelector('.cv-paper'); const initialLong = paper.classList.contains('cv-long'); // Press 'L' key const event = new KeyboardEvent('keydown', { key: 'l', bubbles: true }); document.body.dispatchEvent(event); await new Promise(r => setTimeout(r, 200)); const afterPress = paper.classList.contains('cv-long'); return { initialLong, afterPress, toggled: initialLong !== afterPress }; }); const lengthPassed = lengthTest.toggled; console.log(` Before: ${lengthTest.initialLong ? 'long' : 'short'}`); console.log(` After: ${lengthTest.afterPress ? 'long' : 'short'}`); console.log(` ${lengthPassed ? '✅ PASS' : '❌ FAIL'} - L key toggled CV length`); testResults.push({ test: 'L key - Toggle Length', passed: lengthPassed }); // ======================================================================== // TEST 2: I key toggles icons // ======================================================================== console.log("\n3️⃣ Testing 'I' Key (Toggle Icons)..."); const iconsTest = await page.evaluate(async () => { const paper = document.querySelector('.cv-paper'); const initialHasIcons = paper.classList.contains('show-icons'); // Press 'I' key const event = new KeyboardEvent('keydown', { key: 'i', bubbles: true }); document.body.dispatchEvent(event); await new Promise(r => setTimeout(r, 200)); const afterPress = paper.classList.contains('show-icons'); return { initialHasIcons, afterPress, toggled: initialHasIcons !== afterPress }; }); const iconsPassed = iconsTest.toggled; console.log(` Before: ${iconsTest.initialHasIcons ? 'visible' : 'hidden'}`); console.log(` After: ${iconsTest.afterPress ? 'visible' : 'hidden'}`); console.log(` ${iconsPassed ? '✅ PASS' : '❌ FAIL'} - I key toggled icons`); testResults.push({ test: 'I key - Toggle Icons', passed: iconsPassed }); // ======================================================================== // TEST 3: V key toggles theme // ======================================================================== console.log("\n4️⃣ Testing 'V' Key (Toggle Theme)..."); const themeTest = await page.evaluate(async () => { const body = document.body; const initialClean = body.classList.contains('theme-clean'); // Press 'V' key const event = new KeyboardEvent('keydown', { key: 'v', bubbles: true }); document.body.dispatchEvent(event); await new Promise(r => setTimeout(r, 200)); const afterPress = body.classList.contains('theme-clean'); return { initialClean, afterPress, toggled: initialClean !== afterPress }; }); const themePassed = themeTest.toggled; console.log(` Before: ${themeTest.initialClean ? 'clean' : 'default'}`); console.log(` After: ${themeTest.afterPress ? 'clean' : 'default'}`); console.log(` ${themePassed ? '✅ PASS' : '❌ FAIL'} - V key toggled theme`); testResults.push({ test: 'V key - Toggle Theme', passed: themePassed }); // ======================================================================== // TEST 4: Shortcuts are IGNORED in input fields // ======================================================================== console.log("\n5️⃣ Testing Keyboard Safety (Input Fields)..."); const inputSafetyTest = await page.evaluate(async () => { // Create a temporary input const input = document.createElement('input'); input.type = 'text'; input.id = 'test-input'; document.body.appendChild(input); input.focus(); const body = document.body; const initialClean = body.classList.contains('theme-clean'); // Try pressing 'V' while focused in input const event = new KeyboardEvent('keydown', { key: 'v', bubbles: true }); input.dispatchEvent(event); await new Promise(r => setTimeout(r, 200)); const afterPress = body.classList.contains('theme-clean'); document.body.removeChild(input); return { initialClean, afterPress, didNotToggle: initialClean === afterPress }; }); const safetyPassed = inputSafetyTest.didNotToggle; console.log(` Theme before: ${inputSafetyTest.initialClean ? 'clean' : 'default'}`); console.log(` Theme after: ${inputSafetyTest.afterPress ? 'clean' : 'default'}`); console.log(` ${safetyPassed ? '✅ PASS' : '❌ FAIL'} - Shortcuts correctly ignored in input fields`); testResults.push({ test: 'Input Field Safety', passed: safetyPassed }); // ======================================================================== // TEST 5: ? key opens shortcuts modal // ======================================================================== console.log("\n6️⃣ Testing '?' Key (Shortcuts Modal)..."); const modalTest = await page.evaluate(async () => { // Press '?' key const event = new KeyboardEvent('keydown', { key: '?', bubbles: true }); document.body.dispatchEvent(event); await new Promise(r => setTimeout(r, 300)); const modal = document.querySelector('#shortcuts-modal'); const isOpen = modal && modal.hasAttribute('open'); // Close modal if opened if (isOpen) { modal.close(); } return { isOpen }; }); const modalPassed = modalTest.isOpen; console.log(` ${modalPassed ? '✅ PASS' : '❌ FAIL'} - ? key opened shortcuts modal`); testResults.push({ test: '? key - Shortcuts Modal', passed: modalPassed }); // ======================================================================== // 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 KEYBOARD SHORTCUTS WORKING!"); } 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 testKeyboardShortcuts();