ca758882ef
The theme switcher and info button tooltips were appearing on the RIGHT
in mobile view instead of on TOP (like macOS Dock style) because they
didn't have the .fixed-btn class and weren't included in the mobile
media query rules.
Changes:
- static/css/04-interactive/_tooltips.css: Add .color-theme-switcher and
.info-button selectors to mobile @media (max-width: 900px) rules
- Now tooltips appear ABOVE these buttons on mobile with bottom: calc(100% + 8px)
Testing:
- Added mobile tooltip position test
- Verified theme switcher and info tooltips now positioned on top on mobile
- Desktop behavior unchanged (tooltips still on right)
Mobile tooltip positioning now consistent across ALL buttons:
✅ All bottom dock buttons show tooltips on TOP (macOS Dock style)
132 lines
4.4 KiB
JavaScript
Executable File
132 lines
4.4 KiB
JavaScript
Executable File
#!/usr/bin/env bun
|
|
import { chromium } from 'playwright';
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ headless: false });
|
|
|
|
console.log('========================================');
|
|
console.log(' MOBILE TOOLTIP POSITION TEST');
|
|
console.log(' Testing tooltip appears ABOVE buttons');
|
|
console.log('========================================\n');
|
|
|
|
// Test with actual mobile viewport
|
|
const page = await browser.newPage({
|
|
viewport: { width: 375, height: 667 },
|
|
hasTouch: true,
|
|
isMobile: true
|
|
});
|
|
|
|
await page.goto('http://localhost:1999/');
|
|
await page.waitForLoadState('networkidle');
|
|
await page.waitForTimeout(2000);
|
|
|
|
const buttonsToTest = [
|
|
{ id: 'color-theme-switcher', name: 'Theme Switcher' },
|
|
{ id: 'info-button', name: 'Info Button' }
|
|
];
|
|
|
|
for (const btn of buttonsToTest) {
|
|
console.log(`\n🔍 Testing: ${btn.name}`);
|
|
console.log('─────────────────────────────');
|
|
|
|
const button = page.locator(`#${btn.id}`);
|
|
const exists = await button.count() > 0;
|
|
|
|
if (!exists) {
|
|
console.log(`❌ Button NOT FOUND in DOM`);
|
|
continue;
|
|
}
|
|
|
|
const isVisible = await button.isVisible();
|
|
console.log(`Button visible: ${isVisible ? '✅' : '❌'}`);
|
|
|
|
if (!isVisible) continue;
|
|
|
|
// Get button position
|
|
const buttonBox = await button.boundingBox();
|
|
console.log(`Button position: y=${Math.round(buttonBox.y)}, height=${buttonBox.height}`);
|
|
|
|
// Tap (touch) the button to trigger hover state
|
|
await button.tap();
|
|
await page.waitForTimeout(500);
|
|
|
|
// Get computed tooltip styles
|
|
const tooltipInfo = await page.evaluate((id) => {
|
|
const btn = document.getElementById(id);
|
|
if (!btn) return null;
|
|
|
|
const btnRect = btn.getBoundingClientRect();
|
|
const computed = window.getComputedStyle(btn, '::before');
|
|
|
|
// Parse transform to get actual Y offset
|
|
const transform = computed.transform;
|
|
let transformY = 0;
|
|
if (transform && transform !== 'none') {
|
|
const matrix = transform.match(/matrix\((.+)\)/);
|
|
if (matrix) {
|
|
const values = matrix[1].split(', ');
|
|
transformY = parseFloat(values[5] || 0);
|
|
}
|
|
}
|
|
|
|
return {
|
|
buttonTop: btnRect.top,
|
|
buttonBottom: btnRect.bottom,
|
|
opacity: computed.opacity,
|
|
visibility: computed.visibility,
|
|
display: computed.display,
|
|
bottom: computed.bottom,
|
|
top: computed.top,
|
|
left: computed.left,
|
|
position: computed.position,
|
|
content: computed.content,
|
|
transform: computed.transform
|
|
};
|
|
}, btn.id);
|
|
|
|
if (!tooltipInfo) {
|
|
console.log('❌ Could not get tooltip info');
|
|
continue;
|
|
}
|
|
|
|
console.log(`\nTooltip CSS:`);
|
|
console.log(` - Visibility: ${tooltipInfo.visibility}`);
|
|
console.log(` - Display: ${tooltipInfo.display}`);
|
|
console.log(` - Opacity: ${tooltipInfo.opacity}`);
|
|
console.log(` - Position: ${tooltipInfo.position}`);
|
|
console.log(` - Bottom: ${tooltipInfo.bottom}`);
|
|
console.log(` - Top: ${tooltipInfo.top}`);
|
|
console.log(` - Left: ${tooltipInfo.left}`);
|
|
console.log(` - Transform: ${tooltipInfo.transform}`);
|
|
|
|
// Check if tooltip is positioned ABOVE the button
|
|
// On mobile with our CSS, bottom should be calc(100% + 8px) which means
|
|
// the tooltip bottom edge is 8px above the button top
|
|
const bottomValue = parseFloat(tooltipInfo.bottom);
|
|
|
|
if (tooltipInfo.display === 'none') {
|
|
console.log('\n⚠️ Tooltip is HIDDEN (display: none) - Expected for touch devices');
|
|
} else if (tooltipInfo.bottom && tooltipInfo.bottom.includes('100%')) {
|
|
console.log('\n✅ Tooltip positioned ABOVE button (bottom: calc(100% + 8px))');
|
|
} else if (tooltipInfo.left && tooltipInfo.left.includes('100%')) {
|
|
console.log('\n❌ Tooltip positioned to RIGHT (should be ABOVE on mobile!)');
|
|
} else {
|
|
console.log('\n⚠️ Unclear positioning');
|
|
}
|
|
}
|
|
|
|
// Take screenshot
|
|
await page.screenshot({
|
|
path: '/Users/txeo/Git/yo/cv/tests/mjs/screenshots/mobile-tooltip-positions.png',
|
|
fullPage: true
|
|
});
|
|
console.log('\n📸 Screenshot saved\n');
|
|
|
|
console.log('========================================');
|
|
console.log(' TEST COMPLETE');
|
|
console.log('========================================\n');
|
|
|
|
await page.waitForTimeout(3000);
|
|
await browser.close();
|
|
})();
|