upskill-event-manager/test-certification-system.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

332 lines
No EOL
14 KiB
JavaScript
Raw 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.

/**
* Test script for the new trainer certification system
*
* This script will:
* 1. Create sample certification data via WordPress CLI
* 2. Test the trainer profile display with Playwright
* 3. Verify the new certification cards are working
*/
const { chromium } = require('playwright');
const { execSync } = require('child_process');
// Configuration
const BASE_URL = process.env.BASE_URL || 'https://upskill-staging.measurequick.com';
const HEADLESS = process.env.HEADLESS !== 'false';
// Test data for certifications
const testCertifications = [
{
trainer_id: null, // Will be set after finding a test trainer
certification_type: 'measureQuick Certified Trainer',
status: 'active',
issue_date: '2024-01-15',
expiration_date: '2026-01-15',
certification_number: 'MQT-2024-001',
notes: 'Initial certification - Test data'
},
{
trainer_id: null,
certification_type: 'measureQuick Certified Champion',
status: 'active',
issue_date: '2024-06-01',
expiration_date: '2025-01-15', // Expiring soon
certification_number: 'MQC-2024-015',
notes: 'Champion level certification - Test data'
},
{
trainer_id: null,
certification_type: 'measureQuick Certified Trainer',
status: 'expired',
issue_date: '2022-03-10',
expiration_date: '2024-03-10', // Already expired
certification_number: 'MQT-2022-045',
notes: 'Previous certification - Test data'
}
];
async function createSampleCertifications() {
console.log('🏗️ Creating sample certification data...');
try {
// First, find a test trainer user
console.log('🔍 Finding test trainer...');
const trainers = execSync(`
UPSKILL_STAGING_URL="${BASE_URL}" wp-cli.phar --url=$UPSKILL_STAGING_URL --ssh=root@upskill-staging.measurequick.com user list --role=hvac_trainer --fields=ID,user_login,user_email --format=json
`, { encoding: 'utf8' });
const trainersList = JSON.parse(trainers);
if (trainersList.length === 0) {
throw new Error('No trainers found to test with');
}
const testTrainer = trainersList[0];
console.log(`✅ Using test trainer: ${testTrainer.user_login} (ID: ${testTrainer.ID})`);
// Update test certification data with trainer ID
testCertifications.forEach(cert => {
cert.trainer_id = testTrainer.ID;
});
// Create sample certifications via WordPress
for (let i = 0; i < testCertifications.length; i++) {
const cert = testCertifications[i];
console.log(`📝 Creating certification ${i + 1}: ${cert.certification_type} (${cert.status})`);
try {
// Create the certification post via WP-CLI
const result = execSync(`
UPSKILL_STAGING_URL="${BASE_URL}" wp-cli.phar --url=$UPSKILL_STAGING_URL --ssh=root@upskill-staging.measurequick.com post create --post_type=trainer_certification --post_title="${cert.certification_type} - ${testTrainer.user_login}" --post_status=publish --meta_input='{"trainer_id":"${cert.trainer_id}","certification_type":"${cert.certification_type}","status":"${cert.status}","issue_date":"${cert.issue_date}","expiration_date":"${cert.expiration_date}","certification_number":"${cert.certification_number}","notes":"${cert.notes}"}' --porcelain
`, { encoding: 'utf8' });
const postId = result.trim();
console.log(`✅ Created certification post ID: ${postId}`);
} catch (error) {
console.log(`⚠️ Certification creation via WP-CLI failed, trying alternative method...`);
console.log(`Error: ${error.message}`);
// Alternative: Create via PHP script
const phpScript = `
<?php
// Load WordPress
require_once('/var/www/html/wp-config.php');
// Create certification post
$post_data = array(
'post_type' => 'trainer_certification',
'post_title' => '${cert.certification_type} - ${testTrainer.user_login}',
'post_status' => 'publish'
);
$post_id = wp_insert_post($post_data);
if ($post_id) {
update_post_meta($post_id, 'trainer_id', ${cert.trainer_id});
update_post_meta($post_id, 'certification_type', '${cert.certification_type}');
update_post_meta($post_id, 'status', '${cert.status}');
update_post_meta($post_id, 'issue_date', '${cert.issue_date}');
update_post_meta($post_id, 'expiration_date', '${cert.expiration_date}');
update_post_meta($post_id, 'certification_number', '${cert.certification_number}');
update_post_meta($post_id, 'notes', '${cert.notes}');
echo "Created certification post ID: " . $post_id . "\\n";
} else {
echo "Failed to create certification post\\n";
}
?>`;
// Save PHP script temporarily
require('fs').writeFileSync('/tmp/create_cert.php', phpScript);
// Execute PHP script on server
try {
const phpResult = execSync(`
ssh root@upskill-staging.measurequick.com 'cat > /tmp/create_cert.php' < /tmp/create_cert.php &&
ssh root@upskill-staging.measurequick.com 'cd /var/www/html && php /tmp/create_cert.php && rm /tmp/create_cert.php'
`, { encoding: 'utf8' });
console.log(`📋 PHP result: ${phpResult.trim()}`);
} catch (phpError) {
console.log(`❌ PHP script failed: ${phpError.message}`);
}
}
}
return {
trainerId: testTrainer.ID,
trainerLogin: testTrainer.user_login,
certificationsCreated: testCertifications.length
};
} catch (error) {
console.error('❌ Failed to create sample certifications:', error.message);
throw error;
}
}
async function testCertificationDisplay(testTrainer) {
console.log('🎭 Testing certification display with Playwright...');
const browser = await chromium.launch({ headless: HEADLESS });
const page = await browser.newPage();
try {
// Navigate to trainer profile or find-a-trainer page
console.log('📍 Navigating to find-a-trainer page...');
await page.goto(`${BASE_URL}/find-a-trainer/`);
await page.waitForLoadState('networkidle');
// Take screenshot of initial state
await page.screenshot({ path: '/tmp/certification-test-initial.png' });
console.log('📸 Screenshot saved: /tmp/certification-test-initial.png');
// Look for trainer profiles on the page
console.log('🔍 Looking for trainer profiles...');
await page.waitForTimeout(3000); // Allow JS to load
// Check if certification cards are being displayed
const certificationCards = await page.locator('.hvac-certification-card').count();
console.log(`🎴 Found ${certificationCards} certification cards`);
const certificationGrids = await page.locator('.hvac-certifications-grid').count();
console.log(`📱 Found ${certificationGrids} certification grids`);
// Check for legacy certification display
const legacyCerts = await page.locator('.hvac-certification-section').count();
console.log(`📜 Found ${legacyCerts} legacy certification sections`);
// Try to find specific trainer profile
if (testTrainer && testTrainer.trainerLogin) {
console.log(`🎯 Looking for specific trainer: ${testTrainer.trainerLogin}`);
// Look for trainer name or profile link
const trainerElements = await page.locator(`text=${testTrainer.trainerLogin}`).count();
console.log(`👤 Found ${trainerElements} references to trainer ${testTrainer.trainerLogin}`);
}
// Check console for any JavaScript errors
const consoleMessages = [];
page.on('console', msg => {
consoleMessages.push(`${msg.type()}: ${msg.text()}`);
});
// Reload page to catch any console messages
await page.reload();
await page.waitForLoadState('networkidle');
await page.waitForTimeout(2000);
if (consoleMessages.length > 0) {
console.log('📝 Console messages:');
consoleMessages.forEach(msg => console.log(` ${msg}`));
}
// Take final screenshot
await page.screenshot({ path: '/tmp/certification-test-final.png', fullPage: true });
console.log('📸 Full page screenshot saved: /tmp/certification-test-final.png');
// Test results
const results = {
certificationCards,
certificationGrids,
legacyCerts,
consoleErrors: consoleMessages.filter(msg => msg.startsWith('error:')).length,
testTrainer: testTrainer || null
};
return results;
} catch (error) {
console.error('❌ Test failed:', error.message);
await page.screenshot({ path: '/tmp/certification-test-error.png' });
console.log('📸 Error screenshot saved: /tmp/certification-test-error.png');
throw error;
} finally {
await browser.close();
}
}
async function verifyDatabaseData(trainerId) {
console.log('🔍 Verifying certification data in database...');
try {
// Check if certification posts were created
const posts = execSync(`
UPSKILL_STAGING_URL="${BASE_URL}" wp-cli.phar --url=$UPSKILL_STAGING_URL --ssh=root@upskill-staging.measurequick.com post list --post_type=trainer_certification --meta_key=trainer_id --meta_value=${trainerId} --fields=ID,post_title,post_status --format=json
`, { encoding: 'utf8' });
const certPosts = JSON.parse(posts);
console.log(`📊 Found ${certPosts.length} certification posts for trainer ${trainerId}:`);
certPosts.forEach(post => {
console.log(` - ${post.post_title} (ID: ${post.ID}, Status: ${post.post_status})`);
});
// Get meta data for first post
if (certPosts.length > 0) {
const firstPostId = certPosts[0].ID;
const metaData = execSync(`
UPSKILL_STAGING_URL="${BASE_URL}" wp-cli.phar --url=$UPSKILL_STAGING_URL --ssh=root@upskill-staging.measurequick.com post meta list ${firstPostId} --format=json
`, { encoding: 'utf8' });
const meta = JSON.parse(metaData);
console.log(`🏷️ Meta data for post ${firstPostId}:`);
meta.forEach(item => {
if (item.meta_key.startsWith('certification_') || item.meta_key === 'trainer_id' || item.meta_key === 'status') {
console.log(` - ${item.meta_key}: ${item.meta_value}`);
}
});
}
return certPosts;
} catch (error) {
console.error('❌ Database verification failed:', error.message);
return [];
}
}
async function cleanupTestData(trainerId) {
console.log('🧹 Cleaning up test certification data...');
try {
// Delete test certification posts
const result = execSync(`
UPSKILL_STAGING_URL="${BASE_URL}" wp-cli.phar --url=$UPSKILL_STAGING_URL --ssh=root@upskill-staging.measurequick.com post delete $(wp post list --post_type=trainer_certification --meta_key=trainer_id --meta_value=${trainerId} --field=ID) --force
`, { encoding: 'utf8' });
console.log('✅ Test certification data cleaned up');
console.log(`📋 Cleanup result: ${result.trim()}`);
} catch (error) {
console.log(`⚠️ Cleanup warning: ${error.message}`);
}
}
// Main test execution
async function main() {
console.log('🚀 Starting certification system test...\n');
let testTrainer = null;
try {
// Step 1: Create sample data
testTrainer = await createSampleCertifications();
console.log(`\n✅ Sample data created for trainer ${testTrainer.trainerLogin}\n`);
// Step 2: Verify database data
const dbResults = await verifyDatabaseData(testTrainer.trainerId);
console.log(`\n📊 Database verification: ${dbResults.length} posts found\n`);
// Step 3: Test display
const displayResults = await testCertificationDisplay(testTrainer);
console.log('\n🎭 Display test results:');
console.log(` - Certification cards: ${displayResults.certificationCards}`);
console.log(` - Certification grids: ${displayResults.certificationGrids}`);
console.log(` - Legacy sections: ${displayResults.legacyCerts}`);
console.log(` - Console errors: ${displayResults.consoleErrors}`);
// Test evaluation
if (displayResults.certificationCards > 0) {
console.log('\n✅ SUCCESS: New certification cards are being displayed!');
} else if (displayResults.legacyCerts > 0) {
console.log('\n⚠ PARTIAL: Only legacy certification display found');
} else {
console.log('\n❌ ISSUE: No certification display found');
}
} catch (error) {
console.error('\n💥 Test failed:', error.message);
process.exit(1);
} finally {
// Step 4: Cleanup
if (testTrainer) {
await cleanupTestData(testTrainer.trainerId);
}
}
console.log('\n🎉 Certification system test completed!');
}
// Run the test
main().catch(console.error);