const { chromium } = require('playwright'); console.log('πŸ” FIND A TRAINER COMPREHENSIVE TESTING'); 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(); console.log('\n🌐 Loading Find a Trainer page...'); await page.goto(`${BASE_URL}/find-a-trainer/`); await page.waitForLoadState('networkidle', { timeout: 20000 }); // Test 1: Page loads successfully const title = await page.title(); addTest('Page loads with correct title', title.includes('Find') || title.includes('Trainer')); // Test 2: Search input has correct class console.log('\nπŸ” Testing search input...'); const searchInput = await page.locator('#hvac-trainer-search'); const searchInputExists = await searchInput.count() > 0; addTest('Search input exists', searchInputExists); if (searchInputExists) { const hasClass = await searchInput.getAttribute('class'); const hasCorrectClass = hasClass && hasClass.includes('hvac-search-input'); addTest('Search input has hvac-search-input class', hasCorrectClass, hasClass); // Test search functionality await searchInput.fill('test'); await page.waitForTimeout(1000); await searchInput.clear(); addTest('Search input can be typed in and cleared', true); } // Test 3: Filter buttons exist and are clickable console.log('\nπŸ”˜ Testing filter buttons...'); const filterButtons = await page.locator('.hvac-filter-btn, .hvac-filter-button'); const filterCount = await filterButtons.count(); addTest('Filter buttons found', filterCount > 0, `Found ${filterCount} buttons`); // Test 4: Training Format filter modal console.log('\nπŸ“‹ Testing Training Format filter...'); const formatButton = await page.locator('.hvac-filter-btn[data-filter="training_format"], .hvac-filter-button[data-filter="training_format"]'); const formatButtonExists = await formatButton.count() > 0; addTest('Training Format filter button exists', formatButtonExists); if (formatButtonExists) { await formatButton.click(); await page.waitForTimeout(1000); const modal = await page.locator('#hvac-filter-modal'); const modalVisible = await modal.isVisible(); addTest('Training Format modal opens', modalVisible); if (modalVisible) { const options = await page.locator('.hvac-filter-option').count(); addTest('Training Format has filter options', options > 0, `Found ${options} options`); // Close modal const closeBtn = await page.locator('.hvac-close-modal, .close'); if (await closeBtn.count() > 0) { await closeBtn.click(); await page.waitForTimeout(500); } } } // Test 5: Training Resources filter modal console.log('\nπŸ“š Testing Training Resources filter...'); const resourcesButton = await page.locator('.hvac-filter-btn[data-filter="training_resources"], .hvac-filter-button[data-filter="training_resources"]'); const resourcesButtonExists = await resourcesButton.count() > 0; addTest('Training Resources filter button exists', resourcesButtonExists); if (resourcesButtonExists) { await resourcesButton.click(); await page.waitForTimeout(1000); const modal = await page.locator('#hvac-filter-modal'); const modalVisible = await modal.isVisible(); addTest('Training Resources modal opens', modalVisible); if (modalVisible) { const options = await page.locator('.hvac-filter-option').count(); addTest('Training Resources has filter options', options > 0, `Found ${options} options`); // Test that options are not all clumped together const optionTexts = await page.locator('.hvac-filter-option label').allTextContents(); const uniqueOptions = [...new Set(optionTexts)]; addTest('Training Resources options are distinct', uniqueOptions.length > 1, `${uniqueOptions.length} unique options`); // Close modal const closeBtn = await page.locator('.hvac-close-modal, .close'); if (await closeBtn.count() > 0) { await closeBtn.click(); await page.waitForTimeout(500); } } } // Test 6: Map functionality console.log('\nπŸ—ΊοΈ Testing map functionality...'); const mapContainer = await page.locator('#hvac-trainer-map, .hvac-map-container, #map'); const mapExists = await mapContainer.count() > 0; addTest('Map container exists', mapExists); if (mapExists) { // Wait for map to potentially load await page.waitForTimeout(3000); // Check for map-related elements const mapControls = await page.locator('.leaflet-control, .amcharts-map, .ol-zoom').count(); addTest('Map controls/elements present', mapControls > 0, `Found ${mapControls} map elements`); } // Test 7: Check for JavaScript errors console.log('\nπŸ”§ Checking for JavaScript errors...'); const logs = await page.evaluate(() => { return window.console ? window.console.logs || [] : []; }); // Listen for console errors during page interaction let hasJSErrors = false; page.on('console', msg => { if (msg.type() === 'error') { hasJSErrors = true; console.log(` JS Error: ${msg.text()}`); } }); // Trigger some interactions to check for errors try { await page.locator('#hvac-trainer-search').fill('test search'); await page.waitForTimeout(1000); addTest('No JavaScript errors on search interaction', !hasJSErrors); } catch (e) { addTest('Search interaction without errors', false, e.message); } // Test 8: AJAX endpoints accessibility console.log('\nπŸ”„ Testing AJAX endpoints...'); try { const response = await page.evaluate(async () => { const formData = new FormData(); formData.append('action', 'hvac_filter_trainers'); formData.append('search_term', ''); formData.append('filters', JSON.stringify({})); const response = await fetch('/wp-admin/admin-ajax.php', { method: 'POST', body: formData }); return { status: response.status, ok: response.ok }; }); addTest('AJAX filter endpoint accessible', response.ok, `Status: ${response.status}`); } catch (e) { addTest('AJAX filter endpoint accessible', false, e.message); } } catch (error) { console.error('\nπŸ’₯ Critical Error:', error.message); addTest('Test suite execution', false, error.message); } finally { if (browser) { await browser.close(); } } // Final Results console.log('\nπŸ“Š TEST RESULTS'); console.log('==============='); console.log(`Total Tests: ${testResults.total}`); 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(t => !t.passed).forEach(test => { console.log(` β€’ ${test.name}${test.details ? ': ' + test.details : ''}`); }); } const success = testResults.failed === 0; console.log(`\n🎯 OVERALL RESULT: ${success ? 'βœ… ALL TESTS PASSED' : '❌ SOME TESTS FAILED'}`); process.exit(success ? 0 : 1); })();