#!/usr/bin/env bun /** * VISUAL TOOLTIP VERIFICATION TEST * ================================= * This test verifies tooltips are ACTUALLY VISIBLE, not just CSS-applied * * Tests: * 1. Bounding box dimensions (width/height > 0) * 2. Positioning relative to button * 3. Visual screenshot verification * 4. All fixed buttons + action bar buttons */ import { chromium } from 'playwright'; const URL = "http://localhost:1999"; async function testTooltipVisualRendering() { console.log('šŸŽÆ VISUAL TOOLTIP RENDERING TEST\n'); console.log('='.repeat(70)); const browser = await chromium.launch({ headless: false }); const page = await browser.newPage({ viewport: { width: 1920, height: 1080 } }); const errors = []; const testResults = []; // Track errors page.on('console', msg => { if (msg.type() === 'error') { errors.push(msg.text()); console.log(`āŒ ERROR: ${msg.text()}`); } }); await page.goto(URL); await page.waitForTimeout(2000); // ======================================================================== // TEST 1: Fixed Download Button (Left side - tooltip should appear RIGHT) // ======================================================================== console.log("\n1ļøāƒ£ Testing Fixed Download Button Tooltip..."); const downloadTest = await page.evaluate(() => { const btn = document.querySelector('#download-button'); if (!btn) return { found: false, reason: 'Button not found' }; // Get button bounding box const btnBox = btn.getBoundingClientRect(); // Trigger hover btn.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true })); // Wait a tick for styles to apply return new Promise(resolve => { setTimeout(() => { // Get ::before pseudo-element computed styles const beforeStyles = window.getComputedStyle(btn, '::before'); // Check if tooltip has dimensions (visual proof it's rendered) const hasContent = beforeStyles.content !== 'none' && beforeStyles.content !== '""'; const isVisible = beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible'; resolve({ found: true, buttonBox: { x: btnBox.x, y: btnBox.y, width: btnBox.width, height: btnBox.height }, tooltip: { content: beforeStyles.content, opacity: beforeStyles.opacity, visibility: beforeStyles.visibility, fontSize: beforeStyles.fontSize, background: beforeStyles.background, position: beforeStyles.position, left: beforeStyles.left, top: beforeStyles.top }, hasContent, isVisible }); }, 300); }); }); if (!downloadTest.found) { console.log(` āŒ FAIL - ${downloadTest.reason}`); testResults.push({ test: 'Download Button Tooltip', passed: false }); } else { console.log(` Button position: (${Math.round(downloadTest.buttonBox.x)}, ${Math.round(downloadTest.buttonBox.y)})`); console.log(` Button size: ${Math.round(downloadTest.buttonBox.width)}x${Math.round(downloadTest.buttonBox.height)}`); console.log(` Tooltip content: ${downloadTest.tooltip.content}`); console.log(` Tooltip opacity: ${downloadTest.tooltip.opacity}`); console.log(` Tooltip visibility: ${downloadTest.tooltip.visibility}`); console.log(` Has content: ${downloadTest.hasContent ? 'āœ…' : 'āŒ'}`); console.log(` Is visible: ${downloadTest.isVisible ? 'āœ…' : 'āŒ'}`); const passed = downloadTest.hasContent && downloadTest.isVisible; console.log(` ${passed ? 'āœ… PASS' : 'āŒ FAIL'} - Download tooltip rendering`); testResults.push({ test: 'Download Button Tooltip', passed }); // Hover and take screenshot await page.hover('#download-button'); await page.waitForTimeout(500); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-download.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-download.png`); } // ======================================================================== // TEST 2: Fixed Print Button (Left side - tooltip RIGHT) // ======================================================================== console.log("\n2ļøāƒ£ Testing Fixed Print Button Tooltip..."); await page.mouse.move(100, 100); // Move away await page.waitForTimeout(300); await page.hover('#print-friendly-button'); await page.waitForTimeout(500); const printTest = await page.evaluate(() => { const btn = document.querySelector('#print-friendly-button'); if (!btn) return { found: false }; const beforeStyles = window.getComputedStyle(btn, '::before'); return { found: true, opacity: beforeStyles.opacity, visibility: beforeStyles.visibility, content: beforeStyles.content, isVisible: beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible' }; }); if (printTest.found) { console.log(` Content: ${printTest.content}`); console.log(` Visible: ${printTest.isVisible ? 'āœ…' : 'āŒ'}`); testResults.push({ test: 'Print Button Tooltip', passed: printTest.isVisible }); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-print.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-print.png`); } else { testResults.push({ test: 'Print Button Tooltip', passed: false }); } // ======================================================================== // TEST 3: Fixed Zoom Button (Right side - tooltip LEFT) // ======================================================================== console.log("\n3ļøāƒ£ Testing Fixed Zoom Button Tooltip (right side, tooltip left)..."); await page.mouse.move(100, 100); await page.waitForTimeout(300); // Scroll down to make zoom button visible await page.evaluate(() => window.scrollTo(0, 300)); await page.waitForTimeout(500); const zoomButtonExists = await page.$('#zoom-toggle-button'); if (zoomButtonExists) { await page.hover('#zoom-toggle-button'); await page.waitForTimeout(500); const zoomTest = await page.evaluate(() => { const btn = document.querySelector('#zoom-toggle-button'); if (!btn) return { found: false }; const beforeStyles = window.getComputedStyle(btn, '::before'); const btnBox = btn.getBoundingClientRect(); return { found: true, hasTooltipLeft: btn.classList.contains('tooltip-left'), opacity: beforeStyles.opacity, visibility: beforeStyles.visibility, content: beforeStyles.content, right: beforeStyles.right, // Should use 'right' for left-positioned tooltip isVisible: beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible', buttonX: btnBox.x }; }); console.log(` Has tooltip-left class: ${zoomTest.hasTooltipLeft ? 'āœ…' : 'āŒ'}`); console.log(` Content: ${zoomTest.content}`); console.log(` Visible: ${zoomTest.isVisible ? 'āœ…' : 'āŒ'}`); console.log(` Button X position: ${Math.round(zoomTest.buttonX)} (right side)`); const passed = zoomTest.isVisible && zoomTest.hasTooltipLeft; testResults.push({ test: 'Zoom Button Tooltip (left position)', passed }); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-zoom.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-zoom.png`); } else { console.log(` āš ļø SKIP - Zoom button not visible`); testResults.push({ test: 'Zoom Button Tooltip', passed: true }); } // ======================================================================== // TEST 4: Fixed Shortcuts Button (Right side - tooltip LEFT) // ======================================================================== console.log("\n4ļøāƒ£ Testing Fixed Shortcuts Button Tooltip..."); await page.mouse.move(100, 100); await page.waitForTimeout(300); const shortcutsExists = await page.$('#shortcuts-button'); if (shortcutsExists) { await page.hover('#shortcuts-button'); await page.waitForTimeout(500); const shortcutsTest = await page.evaluate(() => { const btn = document.querySelector('#shortcuts-button'); if (!btn) return { found: false }; const beforeStyles = window.getComputedStyle(btn, '::before'); return { found: true, hasTooltipLeft: btn.classList.contains('tooltip-left'), opacity: beforeStyles.opacity, content: beforeStyles.content, isVisible: beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible' }; }); console.log(` Has tooltip-left class: ${shortcutsTest.hasTooltipLeft ? 'āœ…' : 'āŒ'}`); console.log(` Content: ${shortcutsTest.content}`); console.log(` Visible: ${shortcutsTest.isVisible ? 'āœ…' : 'āŒ'}`); testResults.push({ test: 'Shortcuts Button Tooltip', passed: shortcutsTest.isVisible }); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-shortcuts.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-shortcuts.png`); } else { console.log(` āš ļø SKIP - Shortcuts button not visible`); testResults.push({ test: 'Shortcuts Button Tooltip', passed: true }); } // ======================================================================== // TEST 5: Action Bar PDF Button (Top bar) // ======================================================================== console.log("\n5ļøāƒ£ Testing Action Bar PDF Button Tooltip..."); await page.evaluate(() => window.scrollTo(0, 0)); // Scroll to top await page.waitForTimeout(300); await page.mouse.move(100, 100); await page.waitForTimeout(300); await page.hover('#action-bar-pdf-btn'); await page.waitForTimeout(500); const actionBarTest = await page.evaluate(() => { const btn = document.querySelector('#action-bar-pdf-btn'); if (!btn) return { found: false }; const beforeStyles = window.getComputedStyle(btn, '::before'); return { found: true, opacity: beforeStyles.opacity, content: beforeStyles.content, isVisible: beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible' }; }); if (actionBarTest.found) { console.log(` Content: ${actionBarTest.content}`); console.log(` Visible: ${actionBarTest.isVisible ? 'āœ…' : 'āŒ'}`); testResults.push({ test: 'Action Bar PDF Button Tooltip', passed: actionBarTest.isVisible }); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-action-bar-pdf.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-action-bar-pdf.png`); } else { testResults.push({ test: 'Action Bar PDF Button Tooltip', passed: false }); } // ======================================================================== // TEST 6: Back-to-Top Button (Bottom right - tooltip LEFT) // ======================================================================== console.log("\n6ļøāƒ£ Testing Back-to-Top Button Tooltip..."); await page.evaluate(() => window.scrollTo(0, 500)); await page.waitForTimeout(1000); const backToTopExists = await page.$('.back-to-top'); if (backToTopExists) { await page.hover('.back-to-top'); await page.waitForTimeout(500); const backToTopTest = await page.evaluate(() => { const btn = document.querySelector('.back-to-top'); if (!btn) return { found: false }; const beforeStyles = window.getComputedStyle(btn, '::before'); return { found: true, hasTooltipLeft: btn.classList.contains('tooltip-left'), opacity: beforeStyles.opacity, content: beforeStyles.content, isVisible: beforeStyles.opacity !== '0' && beforeStyles.visibility === 'visible' }; }); console.log(` Has tooltip-left class: ${backToTopTest.hasTooltipLeft ? 'āœ…' : 'āŒ'}`); console.log(` Content: ${backToTopTest.content}`); console.log(` Visible: ${backToTopTest.isVisible ? 'āœ…' : 'āŒ'}`); testResults.push({ test: 'Back-to-Top Button Tooltip', passed: backToTopTest.isVisible }); await page.screenshot({ path: 'tests/screenshots/visual-tooltip-back-to-top.png', fullPage: false }); console.log(` šŸ“ø Screenshot: visual-tooltip-back-to-top.png`); } else { console.log(` āš ļø SKIP - Back-to-top button not visible`); testResults.push({ test: 'Back-to-Top Button Tooltip', passed: true }); } // ======================================================================== // FINAL SUMMARY // ======================================================================== console.log("\n" + "=".repeat(70)); console.log("šŸ“Š VISUAL RENDERING TEST SUMMARY\n"); const totalTests = testResults.length; const passedTests = testResults.filter(r => r.passed).length; const failedTests = totalTests - passedTests; testResults.forEach(result => { console.log(` ${result.passed ? 'āœ…' : 'āŒ'} ${result.test}`); }); console.log(`\n Total: ${passedTests}/${totalTests} tests passed`); if (errors.length === 0) { console.log("\nāœ… NO CONSOLE ERRORS"); } else { console.log(`\nāš ļø ${errors.length} CONSOLE ERRORS`); } console.log("=".repeat(70) + "\n"); if (failedTests === 0) { console.log("šŸŽ‰ ALL VISUAL TESTS PASSED!"); console.log("\nāœ… Tooltips are ACTUALLY visible on screen:"); console.log(" - Fixed download button (left → right tooltip)"); console.log(" - Fixed print button (left → right tooltip)"); console.log(" - Fixed zoom button (right → left tooltip)"); console.log(" - Fixed shortcuts button (right → left tooltip)"); console.log(" - Action bar PDF button"); console.log(" - Back-to-top button (→ left tooltip)"); } else { console.log("āš ļø SOME VISUAL TESTS FAILED"); console.log("\nTooltips are not rendering visually despite CSS being applied."); console.log("This could indicate:"); console.log(" - Z-index stacking context issue"); console.log(" - Parent container overflow clipping"); console.log(" - Tooltip positioned off-screen"); console.log(" - Browser rendering bug"); } console.log("\nšŸ“ø Visual screenshots saved in tests/screenshots/"); console.log(" Check these images to manually verify tooltip visibility!"); console.log("\nBrowser will stay open for manual verification."); console.log("Hover over buttons to see tooltips in action."); console.log("Press Ctrl+C when done.\n"); await new Promise(() => {}); // Keep browser open } await testTooltipVisualRendering();