/** * Master Trainer Layout Fix Verification Test * * Tests that Master Trainer pages now have proper single-column layouts * and navigation/breadcrumbs in both Safari and non-Safari browsers. * * This test specifically validates the fix for Safari CSS loading issues * that were preventing hvac-page-templates.css from loading. */ const { chromium, webkit } = require('playwright'); /** * Test Configuration */ const TEST_CONFIG = { baseUrl: process.env.BASE_URL || 'http://localhost:8080', timeout: 30000, credentials: { master_trainer: { username: 'test_master', password: 'test_password_123' } } }; /** * Master Trainer pages to test */ const MASTER_TRAINER_PAGES = [ { name: 'Google Sheets Integration', path: '/master-trainer/google-sheets/', expectedTitle: 'Google Sheets Integration', layoutChecks: ['single-column', 'navigation', 'breadcrumbs'] }, { name: 'Announcements', path: '/master-trainer/announcements/', expectedTitle: 'Announcements', layoutChecks: ['single-column', 'navigation', 'breadcrumbs'] }, { name: 'Pending Approvals', path: '/master-trainer/pending-approvals/', expectedTitle: 'Pending Approvals', layoutChecks: ['single-column', 'navigation', 'breadcrumbs'] }, { name: 'All Trainers', path: '/master-trainer/trainers/', expectedTitle: 'All Trainers', layoutChecks: ['single-column', 'navigation', 'breadcrumbs'] } ]; /** * Login helper function */ async function loginAsMasterTrainer(page) { console.log('๐Ÿ” Logging in as master trainer...'); await page.goto(`${TEST_CONFIG.baseUrl}/training-login/`); await page.waitForSelector('#user_login', { timeout: 10000 }); await page.fill('#user_login', TEST_CONFIG.credentials.master_trainer.username); await page.fill('#user_pass', TEST_CONFIG.credentials.master_trainer.password); await page.click('#wp-submit'); // Wait for successful login await page.waitForURL(/dashboard|master-trainer/, { timeout: 15000 }); console.log('โœ… Successfully logged in as master trainer'); } /** * Check if page has single-column layout */ async function checkSingleColumnLayout(page, pageName) { console.log(` ๐Ÿ“ Checking single-column layout for ${pageName}...`); // Check that Master Trainer specific CSS fixes are applied const gridColumns = await page.evaluate(() => { const elements = document.querySelectorAll('.hvac-grid-2, .hvac-grid-3, .hvac-grid-4, .sync-options, .hvac-stats-tiles, .hvac-trainers-grid'); const columnCounts = []; elements.forEach(element => { const computedStyle = window.getComputedStyle(element); const gridColumns = computedStyle.getPropertyValue('grid-template-columns'); columnCounts.push(gridColumns); }); return columnCounts; }); // Check if any elements still have multi-column layouts const hasMultiColumn = gridColumns.some(columns => columns && !columns.includes('1fr') && (columns.includes('fr') || columns.includes('px')) ); if (hasMultiColumn) { console.log(` โŒ ${pageName} still has multi-column elements:`, gridColumns); return false; } console.log(` โœ… ${pageName} has proper single-column layout`); return true; } /** * Check if navigation is present and visible */ async function checkNavigation(page, pageName) { console.log(` ๐Ÿงญ Checking navigation for ${pageName}...`); const navigation = await page.$('.hvac-trainer-menu-wrapper, .hvac-master-navigation, .hvac-navigation'); if (!navigation) { console.log(` โŒ ${pageName} missing navigation element`); return false; } const isVisible = await navigation.isVisible(); if (!isVisible) { console.log(` โŒ ${pageName} navigation is not visible`); return false; } console.log(` โœ… ${pageName} has visible navigation`); return true; } /** * Check if breadcrumbs are present and visible */ async function checkBreadcrumbs(page, pageName) { console.log(` ๐Ÿž Checking breadcrumbs for ${pageName}...`); const breadcrumbs = await page.$('.hvac-breadcrumbs'); if (!breadcrumbs) { console.log(` โŒ ${pageName} missing breadcrumbs element`); return false; } const isVisible = await breadcrumbs.isVisible(); if (!isVisible) { console.log(` โŒ ${pageName} breadcrumbs are not visible`); return false; } console.log(` โœ… ${pageName} has visible breadcrumbs`); return true; } /** * Verify CSS files are loaded properly */ async function checkCSSLoading(page, browserType) { console.log(` ๐Ÿ“„ Checking CSS loading for ${browserType}...`); const cssFiles = await page.evaluate(() => { const links = document.querySelectorAll('link[rel="stylesheet"]'); return Array.from(links).map(link => ({ href: link.href, id: link.id })).filter(link => link.href.includes('hvac-')); }); // Check if hvac-page-templates.css or hvac-page-templates-safari.css is loaded const hasPageTemplatesCSS = cssFiles.some(css => css.href.includes('hvac-page-templates.css') || css.id.includes('page-templates') ); if (!hasPageTemplatesCSS) { console.log(` โŒ ${browserType} - Master Trainer layout CSS not loaded`); console.log(' Loaded CSS files:', cssFiles.map(css => css.href).join(', ')); return false; } console.log(` โœ… ${browserType} - Master Trainer layout CSS properly loaded`); return true; } /** * Test a single Master Trainer page */ async function testMasterTrainerPage(page, pageConfig, browserType) { console.log(`\n๐Ÿงช Testing ${pageConfig.name} (${browserType})...`); try { // Navigate to the page await page.goto(`${TEST_CONFIG.baseUrl}${pageConfig.path}`); await page.waitForLoadState('networkidle'); // Check for WordPress errors const hasError = await page.$('.error, .wp-die-message, .notice-error'); if (hasError) { const errorText = await hasError.textContent(); throw new Error(`WordPress error detected: ${errorText}`); } // Verify page title const title = await page.$('h1.page-title, h1.entry-title, h1'); if (title) { const titleText = await title.textContent(); console.log(` ๐Ÿ“ Page title: ${titleText}`); } let allChecksPass = true; // Perform layout checks for (const check of pageConfig.layoutChecks) { let checkResult = false; switch (check) { case 'single-column': checkResult = await checkSingleColumnLayout(page, pageConfig.name); break; case 'navigation': checkResult = await checkNavigation(page, pageConfig.name); break; case 'breadcrumbs': checkResult = await checkBreadcrumbs(page, pageConfig.name); break; } if (!checkResult) { allChecksPass = false; } } // Check CSS loading const cssLoaded = await checkCSSLoading(page, browserType); if (!cssLoaded) { allChecksPass = false; } if (allChecksPass) { console.log(`โœ… ${pageConfig.name} (${browserType}) - All checks passed`); } else { console.log(`โŒ ${pageConfig.name} (${browserType}) - Some checks failed`); } return allChecksPass; } catch (error) { console.log(`โŒ ${pageConfig.name} (${browserType}) - Error: ${error.message}`); return false; } } /** * Run tests for a specific browser */ async function runBrowserTests(browserType) { console.log(`\n๐ŸŒ Testing with ${browserType.toUpperCase()} browser`); console.log('=' .repeat(60)); const browser = browserType === 'safari' ? await webkit.launch({ headless: process.env.HEADLESS !== 'false' }) : await chromium.launch({ headless: process.env.HEADLESS !== 'false' }); const context = await browser.newContext(); const page = await context.newPage(); try { // Login as master trainer await loginAsMasterTrainer(page); let allTestsPass = true; // Test each Master Trainer page for (const pageConfig of MASTER_TRAINER_PAGES) { const result = await testMasterTrainerPage(page, pageConfig, browserType); if (!result) { allTestsPass = false; } } return allTestsPass; } finally { await browser.close(); } } /** * Main test runner */ async function runMasterTrainerLayoutTests() { console.log('๐Ÿš€ Master Trainer Layout Fix Verification Test'); console.log('=' .repeat(60)); console.log('Testing Master Trainer page layouts across browsers'); console.log('Verifying Safari CSS loading fix implementation'); let overallSuccess = true; try { // Test with Chrome (non-Safari) const chromeResults = await runBrowserTests('chrome'); // Test with Safari/WebKit const safariResults = await runBrowserTests('safari'); if (!chromeResults || !safariResults) { overallSuccess = false; } console.log('\n' + '=' .repeat(60)); console.log('๐Ÿ“Š TEST RESULTS SUMMARY'); console.log('=' .repeat(60)); console.log(`Chrome Browser Tests: ${chromeResults ? 'โœ… PASSED' : 'โŒ FAILED'}`); console.log(`Safari Browser Tests: ${safariResults ? 'โœ… PASSED' : 'โŒ FAILED'}`); console.log(`Overall Result: ${overallSuccess ? 'โœ… ALL TESTS PASSED' : 'โŒ SOME TESTS FAILED'}`); if (overallSuccess) { console.log('\n๐ŸŽ‰ Master Trainer layout fixes are working correctly!'); console.log('โœ… Single-column layouts enforced across all browsers'); console.log('โœ… Navigation and breadcrumbs properly displayed'); console.log('โœ… Safari CSS loading issues resolved'); } else { console.log('\nโš ๏ธ Some Master Trainer layout issues still exist'); console.log('โŒ Review the test output above for specific failures'); } return overallSuccess; } catch (error) { console.error('โŒ Test execution failed:', error); return false; } } // Run the tests if this script is executed directly if (require.main === module) { runMasterTrainerLayoutTests() .then(success => { process.exit(success ? 0 : 1); }) .catch(error => { console.error('Fatal error:', error); process.exit(1); }); } module.exports = { runMasterTrainerLayoutTests, testMasterTrainerPage, checkSingleColumnLayout, checkNavigation, checkBreadcrumbs };