upskill-event-manager/test-find-trainer-comprehensive.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

220 lines
No EOL
8.1 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.

const { chromium } = require('playwright');
console.log('🔍 FIND A TRAINER COMPREHENSIVE TESTING');
console.log('=====================================');
const BASE_URL = process.env.BASE_URL || 'https://upskill-staging.measurequick.com';
(async () => {
let browser;
let testResults = {
total: 0,
passed: 0,
failed: 0,
details: []
};
function addTest(name, passed, details = '') {
testResults.total++;
if (passed) {
testResults.passed++;
console.log(`${name}`);
} else {
testResults.failed++;
console.log(`${name}${details ? ': ' + details : ''}`);
}
testResults.details.push({ name, passed, details });
}
try {
browser = await chromium.launch({
headless: process.env.HEADLESS !== 'false',
timeout: 30000
});
const page = await browser.newPage();
console.log('\n🌐 Loading Find a Trainer page...');
await page.goto(`${BASE_URL}/find-a-trainer/`);
await page.waitForLoadState('networkidle', { timeout: 20000 });
// Test 1: Page loads successfully
const title = await page.title();
addTest('Page loads with correct title', title.includes('Find') || title.includes('Trainer'));
// Test 2: Search input has correct class
console.log('\n🔍 Testing search input...');
const searchInput = await page.locator('#hvac-trainer-search');
const searchInputExists = await searchInput.count() > 0;
addTest('Search input exists', searchInputExists);
if (searchInputExists) {
const hasClass = await searchInput.getAttribute('class');
const hasCorrectClass = hasClass && hasClass.includes('hvac-search-input');
addTest('Search input has hvac-search-input class', hasCorrectClass, hasClass);
// Test search functionality
await searchInput.fill('test');
await page.waitForTimeout(1000);
await searchInput.clear();
addTest('Search input can be typed in and cleared', true);
}
// Test 3: Filter buttons exist and are clickable
console.log('\n🔘 Testing filter buttons...');
const filterButtons = await page.locator('.hvac-filter-btn, .hvac-filter-button');
const filterCount = await filterButtons.count();
addTest('Filter buttons found', filterCount > 0, `Found ${filterCount} buttons`);
// Test 4: Training Format filter modal
console.log('\n📋 Testing Training Format filter...');
const formatButton = await page.locator('.hvac-filter-btn[data-filter="training_format"], .hvac-filter-button[data-filter="training_format"]');
const formatButtonExists = await formatButton.count() > 0;
addTest('Training Format filter button exists', formatButtonExists);
if (formatButtonExists) {
await formatButton.click();
await page.waitForTimeout(1000);
const modal = await page.locator('#hvac-filter-modal');
const modalVisible = await modal.isVisible();
addTest('Training Format modal opens', modalVisible);
if (modalVisible) {
const options = await page.locator('.hvac-filter-option').count();
addTest('Training Format has filter options', options > 0, `Found ${options} options`);
// Close modal
const closeBtn = await page.locator('.hvac-close-modal, .close');
if (await closeBtn.count() > 0) {
await closeBtn.click();
await page.waitForTimeout(500);
}
}
}
// Test 5: Training Resources filter modal
console.log('\n📚 Testing Training Resources filter...');
const resourcesButton = await page.locator('.hvac-filter-btn[data-filter="training_resources"], .hvac-filter-button[data-filter="training_resources"]');
const resourcesButtonExists = await resourcesButton.count() > 0;
addTest('Training Resources filter button exists', resourcesButtonExists);
if (resourcesButtonExists) {
await resourcesButton.click();
await page.waitForTimeout(1000);
const modal = await page.locator('#hvac-filter-modal');
const modalVisible = await modal.isVisible();
addTest('Training Resources modal opens', modalVisible);
if (modalVisible) {
const options = await page.locator('.hvac-filter-option').count();
addTest('Training Resources has filter options', options > 0, `Found ${options} options`);
// Test that options are not all clumped together
const optionTexts = await page.locator('.hvac-filter-option label').allTextContents();
const uniqueOptions = [...new Set(optionTexts)];
addTest('Training Resources options are distinct', uniqueOptions.length > 1, `${uniqueOptions.length} unique options`);
// Close modal
const closeBtn = await page.locator('.hvac-close-modal, .close');
if (await closeBtn.count() > 0) {
await closeBtn.click();
await page.waitForTimeout(500);
}
}
}
// Test 6: Map functionality
console.log('\n🗺 Testing map functionality...');
const mapContainer = await page.locator('#hvac-trainer-map, .hvac-map-container, #map');
const mapExists = await mapContainer.count() > 0;
addTest('Map container exists', mapExists);
if (mapExists) {
// Wait for map to potentially load
await page.waitForTimeout(3000);
// Check for map-related elements
const mapControls = await page.locator('.leaflet-control, .amcharts-map, .ol-zoom').count();
addTest('Map controls/elements present', mapControls > 0, `Found ${mapControls} map elements`);
}
// Test 7: Check for JavaScript errors
console.log('\n🔧 Checking for JavaScript errors...');
const logs = await page.evaluate(() => {
return window.console ? window.console.logs || [] : [];
});
// Listen for console errors during page interaction
let hasJSErrors = false;
page.on('console', msg => {
if (msg.type() === 'error') {
hasJSErrors = true;
console.log(` JS Error: ${msg.text()}`);
}
});
// Trigger some interactions to check for errors
try {
await page.locator('#hvac-trainer-search').fill('test search');
await page.waitForTimeout(1000);
addTest('No JavaScript errors on search interaction', !hasJSErrors);
} catch (e) {
addTest('Search interaction without errors', false, e.message);
}
// Test 8: AJAX endpoints accessibility
console.log('\n🔄 Testing AJAX endpoints...');
try {
const response = await page.evaluate(async () => {
const formData = new FormData();
formData.append('action', 'hvac_filter_trainers');
formData.append('search_term', '');
formData.append('filters', JSON.stringify({}));
const response = await fetch('/wp-admin/admin-ajax.php', {
method: 'POST',
body: formData
});
return {
status: response.status,
ok: response.ok
};
});
addTest('AJAX filter endpoint accessible', response.ok, `Status: ${response.status}`);
} catch (e) {
addTest('AJAX filter endpoint accessible', false, e.message);
}
} catch (error) {
console.error('\n💥 Critical Error:', error.message);
addTest('Test suite execution', false, error.message);
} finally {
if (browser) {
await browser.close();
}
}
// Final Results
console.log('\n📊 TEST RESULTS');
console.log('===============');
console.log(`Total Tests: ${testResults.total}`);
console.log(`Passed: ${testResults.passed}`);
console.log(`Failed: ${testResults.failed}`);
console.log(`Success Rate: ${Math.round((testResults.passed / testResults.total) * 100)}%`);
if (testResults.failed > 0) {
console.log('\n❌ Failed Tests:');
testResults.details.filter(t => !t.passed).forEach(test => {
console.log(`${test.name}${test.details ? ': ' + test.details : ''}`);
});
}
const success = testResults.failed === 0;
console.log(`\n🎯 OVERALL RESULT: ${success ? '✅ ALL TESTS PASSED' : '❌ SOME TESTS FAILED'}`);
process.exit(success ? 0 : 1);
})();