#!/usr/bin/env node /** * Test: Mobile Button Opacity - 50% default, 100% on hover * * Verifies that on mobile view (max-width: 900px): * - All fixed buttons have 50% opacity (0.5) by default * - Buttons become 100% opaque (1.0) on hover * - Buttons: download, print-friendly, shortcuts, theme-switcher, info */ import { chromium } from 'playwright'; const TEST_URL = 'http://localhost:1999'; const VIEWPORT_WIDTH = 375; // Mobile width const VIEWPORT_HEIGHT = 812; // iPhone X height async function testMobileButtonOpacity() { console.log('๐Ÿงช Testing Mobile Button Opacity (50% default, 100% hover)'); console.log('='.repeat(70)); const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ viewport: { width: VIEWPORT_WIDTH, height: VIEWPORT_HEIGHT }, deviceScaleFactor: 2, }); const page = await context.newPage(); // Disable cache to ensure fresh CSS await page.route('**/*', (route) => { route.continue({ headers: { ...route.request().headers(), 'Cache-Control': 'no-cache, no-store, must-revalidate', }, }); }); try { // Navigate to the page await page.goto(TEST_URL, { waitUntil: 'networkidle' }); console.log(`โœ… Navigated to ${TEST_URL}`); // Wait for page to be fully loaded await page.waitForTimeout(1000); // Test buttons const buttons = [ { selector: '.download-btn', name: 'Download' }, { selector: '.print-friendly-btn', name: 'Print Friendly' }, { selector: '.shortcuts-btn', name: 'Shortcuts' }, { selector: '.color-theme-switcher', name: 'Theme Switcher' }, { selector: '.info-button', name: 'Info' }, ]; console.log('\n๐Ÿ“ฑ Testing Mobile Button Opacities:'); console.log('-'.repeat(70)); let allTestsPassed = true; for (const button of buttons) { try { // Check if button exists const buttonElement = await page.$(button.selector); if (!buttonElement) { console.log(`โŒ ${button.name}: Button not found`); allTestsPassed = false; continue; } // Get default opacity const defaultOpacity = await page.evaluate((sel) => { const btn = document.querySelector(sel); return btn ? window.getComputedStyle(btn).opacity : null; }, button.selector); // Test default opacity (should be 0.5) const defaultOpacityNum = parseFloat(defaultOpacity); const isDefaultCorrect = Math.abs(defaultOpacityNum - 0.5) < 0.01; if (isDefaultCorrect) { console.log(`โœ… ${button.name}: Default opacity = ${defaultOpacity} (expected ~0.5)`); } else { console.log(`โŒ ${button.name}: Default opacity = ${defaultOpacity} (expected ~0.5)`); allTestsPassed = false; } // Hover over button and check opacity await buttonElement.hover(); await page.waitForTimeout(500); // Wait for transition const hoverOpacity = await page.evaluate((sel) => { const btn = document.querySelector(sel); return btn ? window.getComputedStyle(btn).opacity : null; }, button.selector); // Test hover opacity (should be 1.0) const hoverOpacityNum = parseFloat(hoverOpacity); const isHoverCorrect = Math.abs(hoverOpacityNum - 1.0) < 0.01; if (isHoverCorrect) { console.log(` โœ… Hover opacity = ${hoverOpacity} (expected ~1.0)`); } else { console.log(` โŒ Hover opacity = ${hoverOpacity} (expected ~1.0)`); allTestsPassed = false; } // Move mouse away to reset await page.mouse.move(0, 0); await page.waitForTimeout(500); } catch (error) { console.log(`โŒ ${button.name}: Error - ${error.message}`); allTestsPassed = false; } } console.log('-'.repeat(70)); if (allTestsPassed) { console.log('\nโœ… ALL TESTS PASSED - Mobile button opacity working correctly!'); console.log(' โ€ข Default opacity: 0.5 (50% transparent)'); console.log(' โ€ข Hover opacity: 1.0 (fully opaque)'); } else { console.log('\nโŒ SOME TESTS FAILED - Check output above for details'); } await browser.close(); process.exit(allTestsPassed ? 0 : 1); } catch (error) { console.error('\nโŒ Test error:', error); await browser.close(); process.exit(1); } } // Run the test testMobileButtonOpacity();