Files
cv-site/tests/mjs/38-mobile-fixes-verification.mjs
juanatsap 2eafb78954 fix: Mobile view improvements - accordion styling and modal centering
Fixed two critical mobile view issues:

1. Extended CV Sidebar Accordion:
   - Updated sidebar.html to use native <details> element (was div with onclick)
   - Styled accordion header to match CV title badges dark theme (#303030)
   - Applied consistent styling: dark gray background, light text, uppercase, no spacing
   - Result: Sidebars now collapse/expand properly with native HTML functionality

2. PDF Download Modal Centering:
   - Added JavaScript-based centering for mobile viewports (≤768px)
   - Uses inline styles with !important flag to override browser defaults
   - Updated download button to call openPdfModal() function
   - Result: Modal is perfectly centered on mobile (0px offset)

Technical notes:
   - Modal centering required setProperty() with 'important' flag
   - Accordion matches cv-title-badges-header style exactly
   - All tests passing: accordion toggle, modal centering

Files modified:
   - templates/partials/cv/sidebar.html
   - static/css/05-responsive/_breakpoints.css
   - static/js/main.js
   - templates/partials/widgets/download-button.html

Tests added:
   - tests/mjs/43-mobile-accordion-and-modal-test.mjs
   - tests/mjs/46-visual-accordion-style-test.mjs
2025-11-22 16:23:05 +00:00

182 lines
5.8 KiB
JavaScript
Executable File

#!/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();