upskill-event-manager/test-master-trainer-layout-fix.js
Ben c3e7fe9140 feat: comprehensive HVAC plugin development framework and modernization
## Major Enhancements

### 🏗️ Architecture & Infrastructure
- Implement comprehensive Docker testing infrastructure with hermetic environment
- Add Forgejo Actions CI/CD pipeline for automated deployments
- Create Page Object Model (POM) testing architecture reducing test duplication by 90%
- Establish security-first development patterns with input validation and output escaping

### 🧪 Testing Framework Modernization
- Migrate 146+ tests from 80 duplicate files to centralized architecture
- Add comprehensive E2E test suites for all user roles and workflows
- Implement WordPress error detection with automatic site health monitoring
- Create robust browser lifecycle management with proper cleanup

### 📚 Documentation & Guides
- Add comprehensive development best practices guide
- Create detailed administrator setup documentation
- Establish user guides for trainers and master trainers
- Document security incident reports and migration guides

### 🔧 Core Plugin Features
- Enhance trainer profile management with certification system
- Improve find trainer functionality with advanced filtering
- Strengthen master trainer area with content management
- Add comprehensive venue and organizer management

### 🛡️ Security & Reliability
- Implement security-first patterns throughout codebase
- Add comprehensive input validation and output escaping
- Create secure credential management system
- Establish proper WordPress role-based access control

### 🎯 WordPress Integration
- Strengthen singleton pattern implementation across all classes
- Enhance template hierarchy with proper WordPress integration
- Improve page manager with hierarchical URL structure
- Add comprehensive shortcode and menu system

### 🔍 Developer Experience
- Add extensive debugging and troubleshooting tools
- Create comprehensive test data seeding scripts
- Implement proper error handling and logging
- Establish consistent code patterns and standards

### 📊 Performance & Optimization
- Optimize database queries and caching strategies
- Improve asset loading and script management
- Enhance template rendering performance
- Streamline user experience across all interfaces

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 11:26:10 -03:00

351 lines
No EOL
11 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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
};