Files
cv-site/tests/mjs/33-mobile-tooltip-position-test.mjs
T

132 lines
4.4 KiB
JavaScript
Raw Normal View History

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