## 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>
		
			
				
	
	
		
			270 lines
		
	
	
		
			No EOL
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			No EOL
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | ||
|  * Test script for certification display functionality
 | ||
|  * 
 | ||
|  * This script tests the trainer profile display with the new certification system
 | ||
|  * by checking existing data and testing the display components.
 | ||
|  */
 | ||
| 
 | ||
| const { chromium } = require('playwright');
 | ||
| 
 | ||
| // Configuration
 | ||
| const BASE_URL = process.env.BASE_URL || 'https://upskill-staging.measurequick.com';
 | ||
| const HEADLESS = process.env.HEADLESS !== 'false';
 | ||
| 
 | ||
| async function testCertificationDisplay() {
 | ||
|     console.log('🎭 Testing certification display components...');
 | ||
|     
 | ||
|     const browser = await chromium.launch({ headless: HEADLESS });
 | ||
|     const page = await browser.newPage();
 | ||
|     
 | ||
|     try {
 | ||
|         // First, test the find-a-trainer page to see trainer profiles
 | ||
|         console.log('📍 Navigating to find-a-trainer page...');
 | ||
|         await page.goto(`${BASE_URL}/find-a-trainer/`);
 | ||
|         await page.waitForLoadState('networkidle');
 | ||
|         await page.waitForTimeout(3000);
 | ||
|         
 | ||
|         // Check for various certification display elements
 | ||
|         console.log('🔍 Checking for certification display elements...');
 | ||
|         
 | ||
|         // New certification system elements
 | ||
|         const certificationCards = await page.locator('.hvac-certification-card').count();
 | ||
|         const certificationGrids = await page.locator('.hvac-certifications-grid').count();
 | ||
|         const certificationTitles = await page.locator('.hvac-certification-title').count();
 | ||
|         const certificationBadges = await page.locator('.hvac-certification-status-badge').count();
 | ||
|         const certificationExpiration = await page.locator('.hvac-certification-expiration').count();
 | ||
|         
 | ||
|         // Legacy certification elements
 | ||
|         const legacyCertSections = await page.locator('.hvac-certification-section').count();
 | ||
|         const legacyCertStatuses = await page.locator('.hvac-cert-status').count();
 | ||
|         
 | ||
|         // General trainer profile elements
 | ||
|         const trainerProfiles = await page.locator('.hvac-trainer-card, .trainer-profile, .hvac-profile-card').count();
 | ||
|         
 | ||
|         console.log('\n📊 Display elements found:');
 | ||
|         console.log(`   🎴 New certification cards: ${certificationCards}`);
 | ||
|         console.log(`   📱 New certification grids: ${certificationGrids}`);
 | ||
|         console.log(`   🏷️ New certification titles: ${certificationTitles}`);
 | ||
|         console.log(`   🏅 New certification badges: ${certificationBadges}`);
 | ||
|         console.log(`   ⏰ New expiration elements: ${certificationExpiration}`);
 | ||
|         console.log(`   📜 Legacy cert sections: ${legacyCertSections}`);
 | ||
|         console.log(`   🔖 Legacy cert statuses: ${legacyCertStatuses}`);
 | ||
|         console.log(`   👤 Trainer profiles: ${trainerProfiles}`);
 | ||
|         
 | ||
|         // Take screenshot of current state
 | ||
|         await page.screenshot({ path: '/tmp/find-trainer-certification-test.png', fullPage: true });
 | ||
|         console.log('📸 Screenshot saved: /tmp/find-trainer-certification-test.png');
 | ||
|         
 | ||
|         // Check page source for certification-related classes
 | ||
|         const content = await page.content();
 | ||
|         const hasNewCertClasses = content.includes('hvac-certification-card') || 
 | ||
|                                   content.includes('hvac-certifications-grid');
 | ||
|         const hasLegacyCertClasses = content.includes('hvac-certification-section') || 
 | ||
|                                     content.includes('hvac-cert-status');
 | ||
|         
 | ||
|         console.log('\n🔍 CSS classes detected:');
 | ||
|         console.log(`   ✨ New certification classes: ${hasNewCertClasses ? '✅ Found' : '❌ Not found'}`);
 | ||
|         console.log(`   📜 Legacy certification classes: ${hasLegacyCertClasses ? '✅ Found' : '❌ Not found'}`);
 | ||
|         
 | ||
|         // Try to find individual trainer profiles to test
 | ||
|         console.log('\n🎯 Looking for individual trainer profiles...');
 | ||
|         const profileLinks = await page.locator('a[href*="/trainer/"], a[href*="trainer-profile"], a[href*="/profile/"]').count();
 | ||
|         console.log(`   🔗 Found ${profileLinks} potential trainer profile links`);
 | ||
|         
 | ||
|         if (profileLinks > 0) {
 | ||
|             console.log('   🚀 Testing first trainer profile...');
 | ||
|             try {
 | ||
|                 await page.locator('a[href*="/trainer/"], a[href*="trainer-profile"], a[href*="/profile/"]').first().click();
 | ||
|                 await page.waitForLoadState('networkidle');
 | ||
|                 await page.waitForTimeout(2000);
 | ||
|                 
 | ||
|                 // Check certification display on individual profile
 | ||
|                 const profileCertCards = await page.locator('.hvac-certification-card').count();
 | ||
|                 const profileCertGrids = await page.locator('.hvac-certifications-grid').count();
 | ||
|                 const profileLegacyCerts = await page.locator('.hvac-certification-section').count();
 | ||
|                 
 | ||
|                 console.log(`   📊 Individual profile elements:)`);
 | ||
|                 console.log(`      🎴 Certification cards: ${profileCertCards}`);
 | ||
|                 console.log(`      📱 Certification grids: ${profileCertGrids}`);
 | ||
|                 console.log(`      📜 Legacy sections: ${profileLegacyCerts}`);
 | ||
|                 
 | ||
|                 // Take screenshot of individual profile
 | ||
|                 await page.screenshot({ path: '/tmp/individual-trainer-profile-test.png', fullPage: true });
 | ||
|                 console.log('   📸 Individual profile screenshot: /tmp/individual-trainer-profile-test.png');
 | ||
|                 
 | ||
|             } catch (profileError) {
 | ||
|                 console.log(`   ⚠️ Could not test individual profile: ${profileError.message}`);
 | ||
|             }
 | ||
|         }
 | ||
|         
 | ||
|         // Check for JavaScript errors
 | ||
|         const logs = [];
 | ||
|         page.on('console', msg => {
 | ||
|             if (msg.type() === 'error') {
 | ||
|                 logs.push(msg.text());
 | ||
|             }
 | ||
|         });
 | ||
|         
 | ||
|         // Reload to capture any console errors
 | ||
|         await page.reload();
 | ||
|         await page.waitForLoadState('networkidle');
 | ||
|         await page.waitForTimeout(1000);
 | ||
|         
 | ||
|         if (logs.length > 0) {
 | ||
|             console.log('\n❌ JavaScript errors detected:');
 | ||
|             logs.forEach(log => console.log(`   💥 ${log}`));
 | ||
|         } else {
 | ||
|             console.log('\n✅ No JavaScript errors detected');
 | ||
|         }
 | ||
|         
 | ||
|         return {
 | ||
|             newCertificationElements: {
 | ||
|                 cards: certificationCards,
 | ||
|                 grids: certificationGrids,
 | ||
|                 titles: certificationTitles,
 | ||
|                 badges: certificationBadges,
 | ||
|                 expiration: certificationExpiration
 | ||
|             },
 | ||
|             legacyElements: {
 | ||
|                 sections: legacyCertSections,
 | ||
|                 statuses: legacyCertStatuses
 | ||
|             },
 | ||
|             general: {
 | ||
|                 trainerProfiles,
 | ||
|                 profileLinks,
 | ||
|                 hasNewClasses: hasNewCertClasses,
 | ||
|                 hasLegacyClasses: hasLegacyCertClasses
 | ||
|             },
 | ||
|             errors: logs.length
 | ||
|         };
 | ||
|         
 | ||
|     } catch (error) {
 | ||
|         console.error('❌ Test failed:', error.message);
 | ||
|         await page.screenshot({ path: '/tmp/certification-display-test-error.png' });
 | ||
|         console.log('📸 Error screenshot: /tmp/certification-display-test-error.png');
 | ||
|         throw error;
 | ||
|     } finally {
 | ||
|         await browser.close();
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| async function testDirectProfileAccess() {
 | ||
|     console.log('\n🎯 Testing direct profile access...');
 | ||
|     
 | ||
|     const browser = await chromium.launch({ headless: HEADLESS });
 | ||
|     const page = await browser.newPage();
 | ||
|     
 | ||
|     try {
 | ||
|         // Try to access trainer dashboard or profile pages directly
 | ||
|         const testUrls = [
 | ||
|             `${BASE_URL}/trainer/dashboard/`,
 | ||
|             `${BASE_URL}/trainer/profile/`,
 | ||
|             `${BASE_URL}/training-login/`  // Login page to check if it exists
 | ||
|         ];
 | ||
|         
 | ||
|         for (const url of testUrls) {
 | ||
|             console.log(`   📍 Testing ${url}...`);
 | ||
|             
 | ||
|             try {
 | ||
|                 await page.goto(url, { timeout: 10000 });
 | ||
|                 await page.waitForLoadState('networkidle');
 | ||
|                 
 | ||
|                 const title = await page.title();
 | ||
|                 const statusCode = page.url();
 | ||
|                 
 | ||
|                 console.log(`      📄 Page title: ${title}`);
 | ||
|                 console.log(`      🌐 Final URL: ${statusCode}`);
 | ||
|                 
 | ||
|                 // Check for certification elements on this page
 | ||
|                 const certCards = await page.locator('.hvac-certification-card').count();
 | ||
|                 const certGrids = await page.locator('.hvac-certifications-grid').count();
 | ||
|                 
 | ||
|                 if (certCards > 0 || certGrids > 0) {
 | ||
|                     console.log(`      ✅ Found certification elements! Cards: ${certCards}, Grids: ${certGrids}`);
 | ||
|                     
 | ||
|                     await page.screenshot({ path: `/tmp/direct-access-${url.split('/').slice(-2, -1)[0]}.png` });
 | ||
|                     console.log(`      📸 Screenshot saved for ${url}`);
 | ||
|                 }
 | ||
|                 
 | ||
|             } catch (urlError) {
 | ||
|                 console.log(`      ❌ Failed to access ${url}: ${urlError.message}`);
 | ||
|             }
 | ||
|         }
 | ||
|         
 | ||
|     } finally {
 | ||
|         await browser.close();
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| // Main test function
 | ||
| async function main() {
 | ||
|     console.log('🚀 Starting certification display test...\n');
 | ||
|     
 | ||
|     try {
 | ||
|         // Test 1: Check display components on find-a-trainer
 | ||
|         const displayResults = await testCertificationDisplay();
 | ||
|         
 | ||
|         // Test 2: Try direct profile access
 | ||
|         await testDirectProfileAccess();
 | ||
|         
 | ||
|         // Evaluate results
 | ||
|         console.log('\n📋 Test Results Summary:');
 | ||
|         console.log('=' .repeat(50));
 | ||
|         
 | ||
|         const hasNewSystem = displayResults.newCertificationElements.cards > 0 || 
 | ||
|                             displayResults.newCertificationElements.grids > 0 ||
 | ||
|                             displayResults.general.hasNewClasses;
 | ||
|                             
 | ||
|         const hasLegacySystem = displayResults.legacyElements.sections > 0 ||
 | ||
|                                displayResults.legacyElements.statuses > 0 ||
 | ||
|                                displayResults.general.hasLegacyClasses;
 | ||
|         
 | ||
|         if (hasNewSystem) {
 | ||
|             console.log('✅ NEW CERTIFICATION SYSTEM: Active and displaying');
 | ||
|             console.log(`   🎴 Certification cards found: ${displayResults.newCertificationElements.cards}`);
 | ||
|             console.log(`   📱 Certification grids found: ${displayResults.newCertificationElements.grids}`);
 | ||
|         } else {
 | ||
|             console.log('❌ NEW CERTIFICATION SYSTEM: Not detected');
 | ||
|         }
 | ||
|         
 | ||
|         if (hasLegacySystem) {
 | ||
|             console.log('📜 LEGACY CERTIFICATION SYSTEM: Still active');
 | ||
|             console.log(`   📄 Legacy sections found: ${displayResults.legacyElements.sections}`);
 | ||
|         } else {
 | ||
|             console.log('✅ LEGACY CERTIFICATION SYSTEM: Not detected (expected)');
 | ||
|         }
 | ||
|         
 | ||
|         if (displayResults.general.trainerProfiles > 0) {
 | ||
|             console.log(`👥 TRAINER PROFILES: ${displayResults.general.trainerProfiles} found`);
 | ||
|         } else {
 | ||
|             console.log('❌ TRAINER PROFILES: None found (may need data)');
 | ||
|         }
 | ||
|         
 | ||
|         if (displayResults.errors > 0) {
 | ||
|             console.log(`❌ JAVASCRIPT ERRORS: ${displayResults.errors} detected`);
 | ||
|         } else {
 | ||
|             console.log('✅ JAVASCRIPT ERRORS: None detected');
 | ||
|         }
 | ||
|         
 | ||
|         // Overall assessment
 | ||
|         if (hasNewSystem && displayResults.errors === 0) {
 | ||
|             console.log('\n🎉 OVERALL ASSESSMENT: SUCCESS - New certification system is working!');
 | ||
|         } else if (hasLegacySystem && !hasNewSystem) {
 | ||
|             console.log('\n⚠️ OVERALL ASSESSMENT: LEGACY ONLY - New system not activated yet');
 | ||
|         } else {
 | ||
|             console.log('\n❓ OVERALL ASSESSMENT: MIXED RESULTS - May need investigation');
 | ||
|         }
 | ||
|         
 | ||
|     } catch (error) {
 | ||
|         console.error('\n💥 Test failed:', error.message);
 | ||
|         process.exit(1);
 | ||
|     }
 | ||
|     
 | ||
|     console.log('\n🏁 Certification display test completed!');
 | ||
|     console.log('\nScreenshots saved in /tmp/ for review:');
 | ||
|     console.log('   📸 /tmp/find-trainer-certification-test.png');
 | ||
|     console.log('   📸 /tmp/individual-trainer-profile-test.png (if available)');
 | ||
| }
 | ||
| 
 | ||
| // Run the test
 | ||
| main().catch(console.error); |