#!/usr/bin/env node /** * Test: Mobile Fixes Verification * * Verifies the three mobile fixes: * 1. Shortcuts button is hidden on mobile * 2. Action bar stays visible (no auto-hide on scroll) * 3. Footer has bottom padding to prevent text hiding behind buttons */ 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 testMobileFixes() { console.log('๐Ÿงช Testing Mobile Fixes (Action Bar, Shortcuts Hide, Footer Padding)'); 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 await page.route('**/*', (route) => { route.continue({ headers: { ...route.request().headers(), 'Cache-Control': 'no-cache, no-store, must-revalidate', }, }); }); try { await page.goto(TEST_URL, { waitUntil: 'networkidle' }); console.log(`โœ… Navigated to ${TEST_URL}`); await page.waitForTimeout(1500); let allTestsPassed = true; // TEST 1: Shortcuts button should be hidden on mobile console.log('\n๐Ÿ“Š TEST 1: Shortcuts button hidden on mobile'); console.log('-'.repeat(70)); const shortcutsBtn = await page.$('.shortcuts-btn'); if (shortcutsBtn) { const isVisible = await shortcutsBtn.isVisible(); if (!isVisible) { console.log('โœ… Shortcuts button is hidden on mobile (display: none)'); } else { console.log('โŒ Shortcuts button is visible on mobile (should be hidden)'); allTestsPassed = false; } } else { console.log('โœ… Shortcuts button not found in DOM (correctly hidden)'); } // TEST 2: Action bar should stay visible when scrolling console.log('\n๐Ÿ“Š TEST 2: Action bar stays visible on scroll (mobile)'); console.log('-'.repeat(70)); // Scroll down to trigger header-hidden class await page.evaluate(() => { window.scrollTo(0, 500); }); await page.waitForTimeout(500); const actionBarVisible = await page.evaluate(() => { const actionBar = document.querySelector('.action-bar'); if (!actionBar) return { exists: false }; const hasHiddenClass = actionBar.classList.contains('header-hidden'); const transform = window.getComputedStyle(actionBar).transform; return { exists: true, hasHiddenClass, transform, isTransformed: transform !== 'none' && transform !== 'matrix(1, 0, 0, 1, 0, 0)' }; }); if (actionBarVisible.exists) { if (!actionBarVisible.isTransformed) { console.log(`โœ… Action bar stays visible (transform: ${actionBarVisible.transform})`); console.log(` header-hidden class: ${actionBarVisible.hasHiddenClass}, but transform overridden`); } else { console.log(`โŒ Action bar is transformed away (transform: ${actionBarVisible.transform})`); allTestsPassed = false; } } else { console.log('โŒ Action bar not found'); allTestsPassed = false; } // TEST 3: Footer should have bottom padding on mobile console.log('\n๐Ÿ“Š TEST 3: Footer has bottom padding on mobile'); console.log('-'.repeat(70)); // Scroll to bottom await page.evaluate(() => { window.scrollTo(0, document.body.scrollHeight); }); await page.waitForTimeout(500); const footerPadding = await page.evaluate(() => { const footer = document.querySelector('footer.no-print'); if (!footer) return { exists: false }; const styles = window.getComputedStyle(footer); return { exists: true, paddingBottom: styles.paddingBottom, paddingBottomValue: parseInt(styles.paddingBottom, 10) }; }); if (footerPadding.exists) { // Expect at least 70px bottom padding (we set 80px) if (footerPadding.paddingBottomValue >= 70) { console.log(`โœ… Footer has adequate bottom padding: ${footerPadding.paddingBottom}`); } else { console.log(`โŒ Footer padding insufficient: ${footerPadding.paddingBottom} (expected >= 70px)`); allTestsPassed = false; } } else { console.log('โŒ Footer element not found'); allTestsPassed = false; } // TEST 4: Hamburger button should be visible console.log('\n๐Ÿ“Š TEST 4: Hamburger button visible on mobile'); console.log('-'.repeat(70)); // Scroll back to top to see action bar await page.evaluate(() => { window.scrollTo(0, 0); }); await page.waitForTimeout(500); const hamburgerBtn = await page.$('.hamburger-btn'); if (hamburgerBtn) { const isVisible = await hamburgerBtn.isVisible(); if (isVisible) { console.log('โœ… Hamburger button is visible on mobile'); } else { console.log('โŒ Hamburger button is hidden on mobile (should be visible)'); allTestsPassed = false; } } else { console.log('โŒ Hamburger button not found in DOM'); allTestsPassed = false; } console.log('-'.repeat(70)); if (allTestsPassed) { console.log('\nโœ… ALL TESTS PASSED!'); console.log(' โ€ข Shortcuts button hidden on mobile'); console.log(' โ€ข Action bar stays visible on scroll'); console.log(' โ€ข Footer has bottom padding (80px)'); console.log(' โ€ข Hamburger button visible on mobile'); } else { console.log('\nโŒ SOME TESTS FAILED - Check output above'); } await browser.close(); process.exit(allTestsPassed ? 0 : 1); } catch (error) { console.error('\nโŒ Test error:', error); await browser.close(); process.exit(1); } } testMobileFixes();