const { chromium } = require('playwright'); console.log('🌐 AMCHARTS CDN TIMEOUT FIX VALIDATION'); console.log('====================================='); const BASE_URL = process.env.BASE_URL || 'https://upskill-staging.measurequick.com'; (async () => { let browser; let testResults = { total: 0, passed: 0, failed: 0, details: [] }; function addTest(name, passed, details = '') { testResults.total++; if (passed) { testResults.passed++; console.log(`āœ… ${name}`); } else { testResults.failed++; console.log(`āŒ ${name}${details ? ': ' + details : ''}`); } testResults.details.push({ name, passed, details }); } try { browser = await chromium.launch({ headless: process.env.HEADLESS !== 'false', timeout: 30000 }); const page = await browser.newPage(); // Capture console messages for debugging const consoleMessages = []; page.on('console', msg => { consoleMessages.push(`[${msg.type()}] ${msg.text()}`); }); console.log('\nšŸ” Testing CDN Timeout Fix Implementation...'); // Test 1: Load find-a-trainer page console.log('\nšŸ“ Loading find-a-trainer page...'); await page.goto(`${BASE_URL}/find-a-trainer/`); await page.waitForLoadState('networkidle', { timeout: 20000 }); const title = await page.title(); addTest('Find-a-trainer page loads successfully', title.includes('Find') || title.includes('Trainer')); // Test 2: Check if MapGeo Safety system is loaded console.log('\nšŸ›”ļø Verifying MapGeo Safety system...'); const safetySystemLoaded = await page.evaluate(() => { return typeof window.HVACMapGeoSafety !== 'undefined'; }); addTest('MapGeo Safety system loaded', safetySystemLoaded); if (safetySystemLoaded) { // Test 3: Check CDN health checking functionality console.log('\nšŸ” Testing CDN health check functionality...'); const cdnCheckResult = await page.evaluate(async () => { try { const result = await window.HVACMapGeoSafety.checkCDN(); return { success: true, healthy: result }; } catch (e) { return { success: false, error: e.message }; } }); if (cdnCheckResult.success) { addTest('CDN health check executes successfully', true, `CDN healthy: ${cdnCheckResult.healthy}`); // Test 4: Verify appropriate UI state based on CDN health await page.waitForTimeout(2000); // Allow UI to settle const uiState = await page.evaluate(() => { const loading = document.getElementById('hvac-map-loading'); const fallback = document.getElementById('hvac-map-fallback'); const mapWrapper = document.querySelector('.hvac-mapgeo-wrapper'); return { loadingVisible: loading ? loading.style.display !== 'none' : false, fallbackVisible: fallback ? fallback.style.display !== 'none' : false, mapVisible: mapWrapper ? mapWrapper.style.display !== 'none' : false, loadingExists: !!loading, fallbackExists: !!fallback, mapExists: !!mapWrapper }; }); addTest('Enhanced UI elements exist', uiState.loadingExists && uiState.fallbackExists, `Loading: ${uiState.loadingExists}, Fallback: ${uiState.fallbackExists}`); // Test based on CDN health if (cdnCheckResult.healthy) { addTest('Map shows when CDN healthy', uiState.mapVisible && !uiState.fallbackVisible, `Map: ${uiState.mapVisible}, Fallback: ${uiState.fallbackVisible}`); } else { addTest('Fallback shows when CDN unhealthy', uiState.fallbackVisible && !uiState.mapVisible, `Fallback: ${uiState.fallbackVisible}, Map: ${uiState.mapVisible}`); } // Test 5: Check for no infinite loading state console.log('\nā° Verifying no infinite loading state...'); await page.waitForTimeout(3000); const noInfiniteLoading = await page.evaluate(() => { // Check if the old infinite loading message exists const bodyText = document.body.textContent || document.body.innerText || ''; const hasOldMessage = bodyText.includes('Interactive map is currently loading...'); // If it exists, it should be in fallback, not visible indefinitely if (hasOldMessage) { const fallback = document.getElementById('hvac-map-fallback'); return fallback && fallback.style.display !== 'none'; } return true; // No old message found, which is good }); addTest('No infinite loading state', noInfiniteLoading, 'Old loading message only appears in proper fallback context'); // Test 6: Verify retry button functionality (if fallback is shown) const retryButtonTest = await page.evaluate(() => { const retryButton = document.querySelector('.hvac-retry-map'); const fallback = document.getElementById('hvac-map-fallback'); if (fallback && fallback.style.display !== 'none') { return { buttonExists: !!retryButton, buttonEnabled: retryButton ? !retryButton.disabled : false, fallbackShown: true }; } return { fallbackShown: false, buttonExists: false, buttonEnabled: false }; }); if (retryButtonTest.fallbackShown) { addTest('Retry button available in fallback', retryButtonTest.buttonExists && retryButtonTest.buttonEnabled); } else { addTest('Retry functionality not needed (map loaded)', true, 'CDN healthy, map loading normally'); } // Test 7: Console error analysis console.log('\nšŸ“Š Analyzing console messages...'); const criticalErrors = consoleMessages.filter(msg => msg.includes('[ERROR]') && (msg.includes('amcharts') || msg.includes('MapGeo') || msg.includes('CDN')) ); const safetyMessages = consoleMessages.filter(msg => msg.includes('[MapGeo Safety]') ); addTest('No critical CDN/MapGeo errors', criticalErrors.length === 0, `Found ${criticalErrors.length} critical errors`); addTest('MapGeo Safety system active', safetyMessages.length > 0, `Found ${safetyMessages.length} safety messages`); // Display relevant console messages if (safetyMessages.length > 0) { console.log('\nšŸ” MapGeo Safety Messages:'); safetyMessages.slice(0, 5).forEach(msg => console.log(` ${msg}`)); } if (criticalErrors.length > 0) { console.log('\nāš ļø Critical Errors Found:'); criticalErrors.forEach(msg => console.log(` ${msg}`)); } } else { addTest('CDN health check executes successfully', false, cdnCheckResult.error); } } // Test 8: Cache functionality test console.log('\nšŸ’¾ Testing CDN cache functionality...'); const cacheTest = await page.evaluate(() => { if (typeof window.HVACMapGeoSafety !== 'undefined') { try { // Clear cache window.HVACMapGeoSafety.clearCDNCache(); // Check if sessionStorage access works const testKey = 'hvac_cdn_health'; const cached = sessionStorage.getItem(testKey); return { success: true, cacheCleared: cached === null }; } catch (e) { return { success: false, error: e.message }; } } return { success: false, error: 'HVACMapGeoSafety not available' }; }); addTest('CDN cache functionality works', cacheTest.success && cacheTest.cacheCleared, cacheTest.error || 'Cache cleared successfully'); } catch (error) { console.error('\nāŒ Test execution failed:', error); addTest('Test execution', false, error.message); } finally { if (browser) { await browser.close(); } } // Final results console.log('\n' + '='.repeat(50)); console.log('šŸ“Š CDN TIMEOUT FIX VALIDATION RESULTS'); console.log('='.repeat(50)); console.log(`āœ… Passed: ${testResults.passed}`); console.log(`āŒ Failed: ${testResults.failed}`); console.log(`šŸ“ˆ Success Rate: ${Math.round((testResults.passed / testResults.total) * 100)}%`); if (testResults.failed > 0) { console.log('\nšŸ’” Failed Tests:'); testResults.details .filter(test => !test.passed) .forEach(test => console.log(` • ${test.name}${test.details ? ': ' + test.details : ''}`)); } if (testResults.passed === testResults.total) { console.log('\nšŸŽ‰ ALL TESTS PASSED! CDN timeout fix is working correctly.'); console.log('\n✨ Key Improvements:'); console.log(' • Proactive CDN health checking prevents infinite loading'); console.log(' • Professional fallback UI with retry functionality'); console.log(' • Session-based caching optimizes performance'); console.log(' • Graceful degradation preserves trainer directory access'); } else { console.log('\nāš ļø Some tests failed. Please review the implementation.'); process.exit(1); } })();