182 lines
5.8 KiB
JavaScript
182 lines
5.8 KiB
JavaScript
|
|
#!/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();
|