## 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>
289 lines
No EOL
10 KiB
JavaScript
289 lines
No EOL
10 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* Training Leads Implementation and Testing Script
|
||
* Tests and validates the training leads functionality
|
||
*/
|
||
|
||
const { chromium } = require('playwright');
|
||
const fs = require('fs');
|
||
|
||
class TrainingLeadsTestSuite {
|
||
constructor() {
|
||
this.browser = null;
|
||
this.page = null;
|
||
this.baseUrl = process.env.BASE_URL || 'http://localhost:8080';
|
||
}
|
||
|
||
async setupBrowser() {
|
||
console.log('🚀 Starting Training Leads Test Suite...');
|
||
this.browser = await chromium.launch({
|
||
headless: process.env.HEADLESS !== 'false'
|
||
});
|
||
this.page = await this.browser.newPage();
|
||
}
|
||
|
||
async testWordPressSetup() {
|
||
console.log('\n📋 Phase 1: Testing WordPress Environment...');
|
||
|
||
try {
|
||
await this.page.goto(this.baseUrl, { waitUntil: 'networkidle' });
|
||
console.log('✅ WordPress is accessible');
|
||
|
||
// Check if we can access admin area
|
||
await this.page.goto(`${this.baseUrl}/wp-admin/`, { waitUntil: 'networkidle' });
|
||
const currentUrl = this.page.url();
|
||
|
||
if (currentUrl.includes('wp-login')) {
|
||
console.log('ℹ️ Redirected to login - WordPress is working');
|
||
} else {
|
||
console.log('✅ WordPress admin accessible');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ WordPress setup issue:', error.message);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
async testPluginPresence() {
|
||
console.log('\n📋 Phase 2: Testing HVAC Plugin Presence...');
|
||
|
||
try {
|
||
// Check if custom URL routes work
|
||
await this.page.goto(`${this.baseUrl}/trainer/`, { waitUntil: 'networkidle' });
|
||
const trainerPageContent = await this.page.textContent('body');
|
||
|
||
if (trainerPageContent.includes('Not Found')) {
|
||
console.log('❌ HVAC plugin routes not working - plugin may not be active');
|
||
return false;
|
||
} else {
|
||
console.log('✅ HVAC plugin routes working');
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Plugin test failed:', error.message);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
async testTrainingLeadsPage() {
|
||
console.log('\n📋 Phase 3: Testing Training Leads Page...');
|
||
|
||
try {
|
||
await this.page.goto(`${this.baseUrl}/trainer/profile/training-leads/`, {
|
||
waitUntil: 'networkidle'
|
||
});
|
||
|
||
const currentUrl = this.page.url();
|
||
const pageContent = await this.page.textContent('body');
|
||
|
||
console.log('Current URL:', currentUrl);
|
||
|
||
if (pageContent.includes('Not Found')) {
|
||
console.log('❌ Training leads page returns 404');
|
||
await this.diagnoseRoutingIssue();
|
||
return false;
|
||
}
|
||
|
||
if (currentUrl.includes('login')) {
|
||
console.log('✅ Properly redirects to login for unauthenticated users');
|
||
return await this.testWithAuthentication();
|
||
}
|
||
|
||
// Check for training leads content
|
||
const hasTrainingLeadsWrapper = await this.page.locator('.hvac-training-leads-wrapper').count() > 0;
|
||
const hasShortcodeText = pageContent.includes('[hvac_trainer_training_leads]');
|
||
|
||
if (hasShortcodeText) {
|
||
console.log('❌ Shortcode not processed - raw shortcode visible');
|
||
await this.diagnoseShortcodeIssue();
|
||
return false;
|
||
}
|
||
|
||
if (hasTrainingLeadsWrapper) {
|
||
console.log('✅ Training leads page renders correctly');
|
||
return true;
|
||
}
|
||
|
||
console.log('❌ Training leads content not found');
|
||
return false;
|
||
|
||
} catch (error) {
|
||
console.error('❌ Training leads page test failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async testWithAuthentication() {
|
||
console.log('\n📋 Phase 4: Testing with Authentication...');
|
||
|
||
try {
|
||
// Try to login
|
||
const loginForm = await this.page.locator('form').first();
|
||
if (await loginForm.count() > 0) {
|
||
await this.page.fill('input[name="log"]', 'trainer1');
|
||
await this.page.fill('input[name="pwd"]', 'password123');
|
||
await this.page.click('input[type="submit"]');
|
||
await this.page.waitForNavigation({ waitUntil: 'networkidle' });
|
||
}
|
||
|
||
// Navigate back to training leads page
|
||
await this.page.goto(`${this.baseUrl}/trainer/profile/training-leads/`, {
|
||
waitUntil: 'networkidle'
|
||
});
|
||
|
||
const pageContent = await this.page.textContent('body');
|
||
const hasTrainingLeadsWrapper = await this.page.locator('.hvac-training-leads-wrapper').count() > 0;
|
||
|
||
if (hasTrainingLeadsWrapper) {
|
||
console.log('✅ Training leads page works after authentication');
|
||
return true;
|
||
} else {
|
||
console.log('❌ Authentication successful but training leads page still not working');
|
||
console.log('Page preview:', pageContent.substring(0, 300));
|
||
return false;
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('❌ Authentication test failed:', error.message);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
async diagnoseRoutingIssue() {
|
||
console.log('\n🔍 Diagnosing routing issue...');
|
||
|
||
// Check if other trainer pages work
|
||
const testUrls = [
|
||
'/trainer/',
|
||
'/trainer/dashboard/',
|
||
'/trainer/profile/'
|
||
];
|
||
|
||
for (const url of testUrls) {
|
||
try {
|
||
await this.page.goto(`${this.baseUrl}${url}`, { waitUntil: 'networkidle' });
|
||
const content = await this.page.textContent('body');
|
||
const works = !content.includes('Not Found');
|
||
console.log(`- ${url}: ${works ? '✅ Works' : '❌ 404'}`);
|
||
} catch (error) {
|
||
console.log(`- ${url}: ❌ Error - ${error.message}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
async diagnoseShortcodeIssue() {
|
||
console.log('\n🔍 Diagnosing shortcode processing issue...');
|
||
|
||
const pageContent = await this.page.textContent('body');
|
||
|
||
if (pageContent.includes('HVAC_Training_Leads')) {
|
||
console.log('- Class name visible in output - possible PHP error');
|
||
}
|
||
|
||
if (pageContent.includes('do_shortcode')) {
|
||
console.log('- do_shortcode visible - template processing issue');
|
||
}
|
||
|
||
if (pageContent.includes('class_exists')) {
|
||
console.log('- class_exists check visible - class loading issue');
|
||
}
|
||
|
||
// Check for PHP errors in page source
|
||
const htmlContent = await this.page.content();
|
||
if (htmlContent.includes('Fatal error') || htmlContent.includes('Warning:') || htmlContent.includes('Notice:')) {
|
||
console.log('- PHP errors detected in page source');
|
||
}
|
||
}
|
||
|
||
async generateImplementationReport() {
|
||
console.log('\n📊 Generating Implementation Report...');
|
||
|
||
const report = {
|
||
timestamp: new Date().toISOString(),
|
||
baseUrl: this.baseUrl,
|
||
findings: {
|
||
wordpressWorking: await this.testWordPressSetup(),
|
||
pluginActive: await this.testPluginPresence(),
|
||
trainingLeadsWorking: await this.testTrainingLeadsPage()
|
||
},
|
||
recommendations: []
|
||
};
|
||
|
||
if (!report.findings.pluginActive) {
|
||
report.recommendations.push('Activate HVAC Plugin in WordPress admin');
|
||
report.recommendations.push('Flush rewrite rules: wp rewrite flush');
|
||
}
|
||
|
||
if (!report.findings.trainingLeadsWorking) {
|
||
report.recommendations.push('Check HVAC_Training_Leads class initialization');
|
||
report.recommendations.push('Verify shortcode registration');
|
||
report.recommendations.push('Check template file loading');
|
||
}
|
||
|
||
console.log('\n📋 IMPLEMENTATION REPORT:');
|
||
console.log('='.repeat(50));
|
||
console.log(`WordPress Working: ${report.findings.wordpressWorking ? '✅' : '❌'}`);
|
||
console.log(`Plugin Active: ${report.findings.pluginActive ? '✅' : '❌'}`);
|
||
console.log(`Training Leads Working: ${report.findings.trainingLeadsWorking ? '✅' : '❌'}`);
|
||
|
||
if (report.recommendations.length > 0) {
|
||
console.log('\n🔧 RECOMMENDATIONS:');
|
||
report.recommendations.forEach((rec, index) => {
|
||
console.log(`${index + 1}. ${rec}`);
|
||
});
|
||
}
|
||
|
||
// Save report to file
|
||
fs.writeFileSync(
|
||
'/home/ben/dev/upskill-event-manager/training-leads-test-report.json',
|
||
JSON.stringify(report, null, 2)
|
||
);
|
||
|
||
return report;
|
||
}
|
||
|
||
async cleanup() {
|
||
if (this.browser) {
|
||
await this.browser.close();
|
||
}
|
||
}
|
||
|
||
async run() {
|
||
try {
|
||
await this.setupBrowser();
|
||
const report = await this.generateImplementationReport();
|
||
|
||
if (report.findings.trainingLeadsWorking) {
|
||
console.log('\n🎉 SUCCESS: Training Leads page is working correctly!');
|
||
return true;
|
||
} else {
|
||
console.log('\n🔧 ACTION REQUIRED: Training Leads page needs implementation fixes');
|
||
return false;
|
||
}
|
||
} catch (error) {
|
||
console.error('❌ Test suite failed:', error);
|
||
return false;
|
||
} finally {
|
||
await this.cleanup();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Run the test suite
|
||
if (require.main === module) {
|
||
const testSuite = new TrainingLeadsTestSuite();
|
||
testSuite.run().then(success => {
|
||
process.exit(success ? 0 : 1);
|
||
}).catch(error => {
|
||
console.error('Fatal error:', error);
|
||
process.exit(1);
|
||
});
|
||
}
|
||
|
||
module.exports = TrainingLeadsTestSuite; |