## 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>
287 lines
No EOL
9.4 KiB
JavaScript
287 lines
No EOL
9.4 KiB
JavaScript
/**
|
|
* Test Script for Master Trainer Layout Fixes
|
|
* Verifies single-column layouts and navigation consistency
|
|
*/
|
|
|
|
const TEST_URLS = [
|
|
'/master-trainer/google-sheets/',
|
|
'/master-trainer/announcements/',
|
|
'/master-trainer/pending-approvals/',
|
|
'/master-trainer/trainers/'
|
|
];
|
|
|
|
const LAYOUT_TESTS = {
|
|
navigation: {
|
|
selector: '.hvac-trainer-menu-wrapper, .hvac-trainer-nav',
|
|
description: 'Navigation menu should be visible'
|
|
},
|
|
breadcrumbs: {
|
|
selector: '.hvac-breadcrumbs',
|
|
description: 'Breadcrumbs should be visible'
|
|
},
|
|
singleColumn: {
|
|
selectors: [
|
|
'.hvac-grid-2',
|
|
'.hvac-grid-3',
|
|
'.hvac-grid-4',
|
|
'.sync-options',
|
|
'.hvac-stats-tiles',
|
|
'.hvac-trainers-grid'
|
|
],
|
|
description: 'Elements should use single-column layout (grid-template-columns: 1fr)'
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Test single-column layout implementation
|
|
*/
|
|
function testSingleColumnLayout() {
|
|
console.log('Testing single-column layouts...');
|
|
|
|
const results = {
|
|
passed: 0,
|
|
failed: 0,
|
|
details: []
|
|
};
|
|
|
|
LAYOUT_TESTS.singleColumn.selectors.forEach(selector => {
|
|
const elements = document.querySelectorAll(selector);
|
|
|
|
elements.forEach(element => {
|
|
const computedStyle = getComputedStyle(element);
|
|
const gridColumns = computedStyle.gridTemplateColumns;
|
|
const display = computedStyle.display;
|
|
|
|
const test = {
|
|
selector: selector,
|
|
element: element,
|
|
computedStyle: {
|
|
display: display,
|
|
gridTemplateColumns: gridColumns
|
|
}
|
|
};
|
|
|
|
// Check if element uses single column layout
|
|
if (display === 'grid' && gridColumns === '1fr') {
|
|
results.passed++;
|
|
test.status = 'PASSED';
|
|
test.message = 'Single-column grid layout correctly applied';
|
|
} else if (display === 'flex' && computedStyle.flexDirection === 'column') {
|
|
results.passed++;
|
|
test.status = 'PASSED';
|
|
test.message = 'Single-column flex layout correctly applied';
|
|
} else if (display === 'block') {
|
|
results.passed++;
|
|
test.status = 'PASSED';
|
|
test.message = 'Block layout (inherently single-column)';
|
|
} else {
|
|
results.failed++;
|
|
test.status = 'FAILED';
|
|
test.message = `Multi-column layout detected: ${display} ${gridColumns}`;
|
|
}
|
|
|
|
results.details.push(test);
|
|
});
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Test navigation visibility
|
|
*/
|
|
function testNavigationVisibility() {
|
|
console.log('Testing navigation visibility...');
|
|
|
|
const results = {
|
|
passed: 0,
|
|
failed: 0,
|
|
details: []
|
|
};
|
|
|
|
Object.entries(LAYOUT_TESTS).forEach(([testName, testConfig]) => {
|
|
if (testName === 'singleColumn') return; // Skip, tested separately
|
|
|
|
const elements = document.querySelectorAll(testConfig.selector);
|
|
|
|
if (elements.length === 0) {
|
|
results.failed++;
|
|
results.details.push({
|
|
test: testName,
|
|
status: 'FAILED',
|
|
message: `No elements found for selector: ${testConfig.selector}`,
|
|
description: testConfig.description
|
|
});
|
|
return;
|
|
}
|
|
|
|
elements.forEach(element => {
|
|
const computedStyle = getComputedStyle(element);
|
|
const isVisible = computedStyle.display !== 'none' &&
|
|
computedStyle.visibility !== 'hidden' &&
|
|
computedStyle.opacity !== '0';
|
|
|
|
const test = {
|
|
test: testName,
|
|
selector: testConfig.selector,
|
|
element: element,
|
|
description: testConfig.description
|
|
};
|
|
|
|
if (isVisible) {
|
|
results.passed++;
|
|
test.status = 'PASSED';
|
|
test.message = 'Element is visible';
|
|
} else {
|
|
results.failed++;
|
|
test.status = 'FAILED';
|
|
test.message = `Element is hidden: display=${computedStyle.display}, visibility=${computedStyle.visibility}, opacity=${computedStyle.opacity}`;
|
|
}
|
|
|
|
results.details.push(test);
|
|
});
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Test responsive design
|
|
*/
|
|
function testResponsiveDesign() {
|
|
console.log('Testing responsive design...');
|
|
|
|
const viewports = [
|
|
{ width: 375, height: 667, name: 'Mobile' },
|
|
{ width: 768, height: 1024, name: 'Tablet' },
|
|
{ width: 1200, height: 800, name: 'Desktop' }
|
|
];
|
|
|
|
const results = {
|
|
passed: 0,
|
|
failed: 0,
|
|
details: []
|
|
};
|
|
|
|
viewports.forEach(viewport => {
|
|
// Simulate viewport resize (Note: this would need actual browser resize in real test)
|
|
console.log(`Testing ${viewport.name} (${viewport.width}x${viewport.height})`);
|
|
|
|
const elements = document.querySelectorAll('.hvac-grid-2, .hvac-grid-3, .hvac-grid-4, .sync-options');
|
|
|
|
elements.forEach(element => {
|
|
const computedStyle = getComputedStyle(element);
|
|
const gridColumns = computedStyle.gridTemplateColumns;
|
|
|
|
const test = {
|
|
viewport: viewport.name,
|
|
selector: element.className,
|
|
gridColumns: gridColumns
|
|
};
|
|
|
|
if (gridColumns === '1fr' || gridColumns === 'none') {
|
|
results.passed++;
|
|
test.status = 'PASSED';
|
|
test.message = 'Single-column maintained on mobile';
|
|
} else {
|
|
results.failed++;
|
|
test.status = 'FAILED';
|
|
test.message = `Multi-column layout on mobile: ${gridColumns}`;
|
|
}
|
|
|
|
results.details.push(test);
|
|
});
|
|
});
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Run all layout tests
|
|
*/
|
|
function runLayoutTests() {
|
|
console.log('='.repeat(50));
|
|
console.log('MASTER TRAINER LAYOUT TESTS');
|
|
console.log('='.repeat(50));
|
|
|
|
const currentUrl = window.location.pathname;
|
|
console.log(`Current URL: ${currentUrl}`);
|
|
|
|
// Check if we're on a Master Trainer page
|
|
const isMasterTrainerPage = TEST_URLS.some(url => currentUrl.includes(url));
|
|
|
|
if (!isMasterTrainerPage) {
|
|
console.warn('Not on a Master Trainer page. Navigate to one of these URLs to run tests:');
|
|
TEST_URLS.forEach(url => console.log(`- ${url}`));
|
|
return;
|
|
}
|
|
|
|
// Run all tests
|
|
const navigationResults = testNavigationVisibility();
|
|
const layoutResults = testSingleColumnLayout();
|
|
const responsiveResults = testResponsiveDesign();
|
|
|
|
// Summary
|
|
console.log('\n' + '='.repeat(30));
|
|
console.log('TEST RESULTS SUMMARY');
|
|
console.log('='.repeat(30));
|
|
|
|
console.log(`Navigation Tests: ${navigationResults.passed} passed, ${navigationResults.failed} failed`);
|
|
console.log(`Layout Tests: ${layoutResults.passed} passed, ${layoutResults.failed} failed`);
|
|
console.log(`Responsive Tests: ${responsiveResults.passed} passed, ${responsiveResults.failed} failed`);
|
|
|
|
const totalPassed = navigationResults.passed + layoutResults.passed + responsiveResults.passed;
|
|
const totalFailed = navigationResults.failed + layoutResults.failed + responsiveResults.failed;
|
|
|
|
console.log(`\nOVERALL: ${totalPassed} passed, ${totalFailed} failed`);
|
|
|
|
if (totalFailed === 0) {
|
|
console.log('✅ All layout tests PASSED!');
|
|
} else {
|
|
console.log('❌ Some layout tests FAILED. See details below.');
|
|
}
|
|
|
|
// Detailed results
|
|
console.log('\nDETAILED RESULTS:');
|
|
console.log('-'.repeat(20));
|
|
|
|
['Navigation', 'Layout', 'Responsive'].forEach((testType, index) => {
|
|
const results = [navigationResults, layoutResults, responsiveResults][index];
|
|
|
|
console.log(`\n${testType} Tests:`);
|
|
results.details.forEach(detail => {
|
|
const status = detail.status === 'PASSED' ? '✅' : '❌';
|
|
console.log(`${status} ${detail.message}`);
|
|
});
|
|
});
|
|
|
|
return {
|
|
navigation: navigationResults,
|
|
layout: layoutResults,
|
|
responsive: responsiveResults,
|
|
summary: {
|
|
totalPassed,
|
|
totalFailed,
|
|
success: totalFailed === 0
|
|
}
|
|
};
|
|
}
|
|
|
|
// Export for use in browser console
|
|
if (typeof window !== 'undefined') {
|
|
window.runLayoutTests = runLayoutTests;
|
|
window.testSingleColumnLayout = testSingleColumnLayout;
|
|
window.testNavigationVisibility = testNavigationVisibility;
|
|
window.testResponsiveDesign = testResponsiveDesign;
|
|
}
|
|
|
|
// Auto-run if script is loaded directly
|
|
if (typeof document !== 'undefined' && document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
console.log('Master Trainer Layout Test Script Loaded');
|
|
console.log('Run runLayoutTests() in console to test current page');
|
|
});
|
|
} else if (typeof document !== 'undefined') {
|
|
console.log('Master Trainer Layout Test Script Loaded');
|
|
console.log('Run runLayoutTests() in console to test current page');
|
|
} |