404748afb5
Replace simple search button with search bar design in action bar: - Semi-transparent styling integrated with dark action bar - Keyboard shortcut indicators (⌘ K) shown as individual kbd elements - Search icon and "Search" text for better discoverability - Responsive: kbd keys hidden on mobile (<900px) - Remove unused cmd-k-button.html partial template Update test to verify new search bar structure (styling, kbd elements, icon).
159 lines
6.3 KiB
JavaScript
159 lines
6.3 KiB
JavaScript
#!/usr/bin/env bun
|
|
/**
|
|
* CMD+K BUTTON FUNCTIONALITY TEST
|
|
* ================================
|
|
* Tests that the CMD+K search bar button:
|
|
* - Exists in the action bar with search bar styling
|
|
* - Has keyboard shortcut indicators (⌘ K)
|
|
* - Click handler opens ninja-keys
|
|
* - Has search icon and text
|
|
*/
|
|
|
|
import { chromium } from 'playwright';
|
|
|
|
const URL = "http://localhost:1999";
|
|
|
|
async function testCmdKButton() {
|
|
console.log('🎯 CMD+K SEARCH BAR BUTTON 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 search bar class
|
|
// ========================================================================
|
|
console.log('\n1️⃣ Testing button exists with search bar styling...');
|
|
|
|
const cmdKButton = await page.$('#cmd-k-button');
|
|
const buttonExists = cmdKButton !== null;
|
|
console.log(` Button exists: ${buttonExists}`);
|
|
|
|
let hasSearchBarClass = false;
|
|
if (buttonExists) {
|
|
hasSearchBarClass = await page.$eval('#cmd-k-button', el => el.classList.contains('search-bar-btn'));
|
|
console.log(` Has search-bar-btn class: ${hasSearchBarClass}`);
|
|
console.log(` ${hasSearchBarClass ? '✅ PASS' : '❌ FAIL'} - Button has search bar styling`);
|
|
}
|
|
testResults.push({ test: 'Button has search bar styling', passed: buttonExists && hasSearchBarClass });
|
|
|
|
// ========================================================================
|
|
// TEST 2: Button has keyboard shortcut keys (kbd elements)
|
|
// ========================================================================
|
|
console.log('\n2️⃣ Testing keyboard shortcut indicators...');
|
|
|
|
let hasKbdElements = false;
|
|
if (buttonExists) {
|
|
const kbdCount = await page.$$eval('#cmd-k-button kbd', els => els.length);
|
|
hasKbdElements = kbdCount === 2; // Should have ⌘ and K
|
|
console.log(` Kbd elements found: ${kbdCount}`);
|
|
|
|
if (kbdCount === 2) {
|
|
const kbdTexts = await page.$$eval('#cmd-k-button kbd', els => els.map(el => el.textContent.trim()));
|
|
console.log(` Kbd contents: ${kbdTexts.join(', ')}`);
|
|
}
|
|
console.log(` ${hasKbdElements ? '✅ PASS' : '❌ FAIL'} - Has ⌘ K keyboard indicators`);
|
|
}
|
|
testResults.push({ test: 'Has keyboard shortcut indicators', passed: hasKbdElements });
|
|
|
|
// ========================================================================
|
|
// TEST 3: Button has search icon
|
|
// ========================================================================
|
|
console.log('\n3️⃣ Testing search icon...');
|
|
|
|
let hasSearchIcon = false;
|
|
if (buttonExists) {
|
|
const icon = await page.$eval('#cmd-k-button iconify-icon', el => el.getAttribute('icon'));
|
|
hasSearchIcon = icon && icon.includes('magnify');
|
|
console.log(` Icon: ${icon}`);
|
|
console.log(` ${hasSearchIcon ? '✅ PASS' : '❌ FAIL'} - Has search/magnify icon`);
|
|
}
|
|
testResults.push({ test: 'Has search icon', passed: hasSearchIcon });
|
|
|
|
// ========================================================================
|
|
// TEST 4: Button click opens ninja-keys
|
|
// ========================================================================
|
|
console.log('\n4️⃣ Testing button click opens ninja-keys...');
|
|
|
|
// First click triggers lazy load of ninja-keys
|
|
await page.click('#cmd-k-button');
|
|
await page.waitForTimeout(3000); // Wait for module to load (lazy loading)
|
|
|
|
// Check if ninja-keys element was created and is open
|
|
const ninjaKeysState = await page.evaluate(() => {
|
|
const nk = document.getElementById('cmd-k-bar');
|
|
if (!nk) return { exists: false, isOpen: false };
|
|
// ninja-keys uses shadow DOM with .modal.visible class
|
|
const shadow = nk.shadowRoot;
|
|
const modal = shadow?.querySelector('.modal');
|
|
return {
|
|
exists: true,
|
|
isOpen: modal?.classList?.contains('visible') || nk.hasAttribute('open') || false
|
|
};
|
|
});
|
|
|
|
console.log(` Ninja-keys exists: ${ninjaKeysState.exists}`);
|
|
console.log(` Ninja-keys open: ${ninjaKeysState.isOpen}`);
|
|
const ninjaKeysOpened = ninjaKeysState.exists && ninjaKeysState.isOpen;
|
|
console.log(` ${ninjaKeysOpened ? '✅ PASS' : '❌ FAIL'} - Click opens ninja-keys`);
|
|
testResults.push({ test: 'Click opens ninja-keys', passed: ninjaKeysOpened });
|
|
|
|
// Close ninja-keys
|
|
await page.keyboard.press('Escape');
|
|
await page.waitForTimeout(300);
|
|
|
|
// ========================================================================
|
|
// TEST 5: Button has Search text
|
|
// ========================================================================
|
|
console.log('\n5️⃣ Testing Search text...');
|
|
|
|
let hasSearchText = false;
|
|
if (buttonExists) {
|
|
const searchText = await page.$eval('#cmd-k-button .search-bar-text', el => el.textContent.trim());
|
|
hasSearchText = searchText.toLowerCase() === 'search';
|
|
console.log(` Search text: "${searchText}"`);
|
|
console.log(` ${hasSearchText ? '✅ PASS' : '❌ FAIL'} - Has "Search" text`);
|
|
}
|
|
testResults.push({ test: 'Has Search text', passed: hasSearchText });
|
|
|
|
// ========================================================================
|
|
// 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();
|