Files
cv-site/tests/mjs/33-mobile-tooltip-position-test.mjs
T
juanatsap ca758882ef fix: Position theme switcher and info button tooltips on TOP for mobile
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)
2025-11-20 20:01:57 +00:00

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();
})();