#!/usr/bin/env bun /** * CMD+K BUTTON FUNCTIONALITY TEST * ================================ * Tests that the CMD+K button: * - Has a distinct icon from zoom button * - Click handler opens ninja-keys * - At-bottom illumination works * - Has distinct color from zoom button */ import { chromium } from 'playwright'; const URL = "http://localhost:1999"; async function testCmdKButton() { console.log('🎯 CMD+K BUTTON FUNCTIONALITY TEST\n'); console.log('='.repeat(70)); const browser = await chromium.launch({ headless: process.env.HEADLESS === 'true' }); const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); const testResults = []; await page.goto(URL); await page.waitForTimeout(2000); // ======================================================================== // TEST 1: Button exists with distinct icon // ======================================================================== console.log('\n1️⃣ Testing button exists with distinct icon...'); const cmdKButton = await page.$('#cmd-k-button'); const buttonExists = cmdKButton !== null; console.log(` Button exists: ${buttonExists}`); let iconsDistinct = false; if (buttonExists) { const cmdKIcon = await page.$eval('#cmd-k-button iconify-icon', el => el.getAttribute('icon')); const zoomIcon = await page.$eval('#zoom-toggle-button iconify-icon', el => el.getAttribute('icon')); console.log(` CMD+K icon: ${cmdKIcon}`); console.log(` Zoom icon: ${zoomIcon}`); iconsDistinct = cmdKIcon !== zoomIcon; console.log(` ${iconsDistinct ? '✅ PASS' : '❌ FAIL'} - Icons are distinct`); } testResults.push({ test: 'Icons are distinct', passed: buttonExists && iconsDistinct }); // ======================================================================== // TEST 2: Button click opens ninja-keys // ======================================================================== console.log('\n2️⃣ Testing button click opens ninja-keys...'); await page.click('#cmd-k-button'); await page.waitForTimeout(500); const ninjaKeysOpen = await page.$eval('#cmd-k-bar', el => el.hasAttribute('open')); console.log(` Ninja-keys open: ${ninjaKeysOpen}`); console.log(` ${ninjaKeysOpen ? '✅ PASS' : '❌ FAIL'} - Click opens ninja-keys`); testResults.push({ test: 'Click opens ninja-keys', passed: ninjaKeysOpen }); // Close ninja-keys await page.keyboard.press('Escape'); await page.waitForTimeout(300); // ======================================================================== // TEST 3: At-bottom illumination // ======================================================================== console.log('\n3️⃣ Testing at-bottom illumination...'); // Scroll to very top - use scroll() which fires event naturally await page.evaluate(() => window.scrollTo(0, 0)); await page.waitForTimeout(100); // Trigger handleScroll manually via hyperscript's behavior await page.evaluate(() => window.dispatchEvent(new Event('scroll'))); await page.waitForTimeout(300); const atTopClass = await page.$eval('#cmd-k-button', el => el.classList.contains('at-bottom')); console.log(` At top - has at-bottom class: ${atTopClass}`); // Scroll to bottom using mouse wheel to trigger actual scroll await page.mouse.wheel(0, 100000); await page.waitForTimeout(1000); const atBottomClass = await page.$eval('#cmd-k-button', el => el.classList.contains('at-bottom')); const zoomAtBottomClass = await page.$eval('#zoom-toggle-button', el => el.classList.contains('at-bottom')); const infoAtBottomClass = await page.$eval('#info-button', el => el.classList.contains('at-bottom')); console.log(` At bottom - CMD+K has at-bottom: ${atBottomClass}`); console.log(` At bottom - Zoom has at-bottom: ${zoomAtBottomClass}`); console.log(` At bottom - Info has at-bottom: ${infoAtBottomClass}`); const illuminationWorks = !atTopClass && atBottomClass; console.log(` ${illuminationWorks ? '✅ PASS' : '❌ FAIL'} - At-bottom illumination works`); testResults.push({ test: 'At-bottom illumination', passed: illuminationWorks }); // ======================================================================== // TEST 4: Distinct color from zoom button // ======================================================================== console.log('\n4️⃣ Testing distinct color at bottom...'); const cmdKBgColor = await page.$eval('#cmd-k-button', el => window.getComputedStyle(el).backgroundColor); const zoomBgColor = await page.$eval('#zoom-toggle-button', el => window.getComputedStyle(el).backgroundColor); console.log(` CMD+K bg color: ${cmdKBgColor}`); console.log(` Zoom bg color: ${zoomBgColor}`); const colorsDistinct = cmdKBgColor !== zoomBgColor; console.log(` ${colorsDistinct ? '✅ PASS' : '❌ FAIL'} - Colors are distinct`); testResults.push({ test: 'Colors are distinct', passed: colorsDistinct }); // ======================================================================== // 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`); console.log("=".repeat(70) + "\n"); if (failedTests === 0) { console.log("🎉 ALL CMD+K BUTTON TESTS PASSED!"); } else { console.log("⚠️ SOME TESTS FAILED - See details above"); } // Auto-close after tests if HEADLESS env is set if (process.env.HEADLESS === 'true') { await browser.close(); process.exit(failedTests === 0 ? 0 : 1); } else { console.log("\nBrowser will stay open for manual inspection."); console.log("Press Ctrl+C when done.\n"); await new Promise(() => {}); // Keep browser open } } await testCmdKButton();