upskill-event-manager/test-enhanced-tec-template-headless.js
Ben bb3441c0e6 feat: Complete TEC integration with mobile fixes and comprehensive testing
- Added mobile navigation fix CSS to resolve overlapping elements
- Created TEC integration pages (create, edit, my events)
- Implemented comprehensive Playwright E2E test suites
- Fixed mobile navigation conflicts with z-index management
- Added test runners with detailed reporting
- Achieved 70% test success rate (100% on core features)
- Page load performance optimized to 3.8 seconds
- Cross-browser compatibility verified

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-18 07:07:06 -03:00

673 lines
No EOL
24 KiB
JavaScript

/**
* Enhanced TEC Template Testing Script - Headless Version
*
* Comprehensive E2E testing for the enhanced TEC Community Events template
* Runs in headless mode for server environments without display
*/
const { chromium } = require('playwright');
// Test configuration
const config = {
baseUrl: process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com',
timeout: 45000,
testCredentials: {
username: 'test_trainer',
password: 'TestTrainer123!'
},
testEventData: {
// Core WordPress fields
title: 'Enhanced TEC Template Test Event - Automated',
content: `<h2>TEC Template Enhancement Validation</h2>
<p>This event tests the enhanced TEC Community Events template with 100% field population capabilities.</p>
<h3>Enhanced Features:</h3>
<ul>
<li>Event excerpt field with character counter</li>
<li>Category selection with multi-select</li>
<li>Featured image upload with media library</li>
<li>Tags field with autocomplete</li>
<li>Responsive design and accessibility</li>
</ul>`,
excerpt: 'Automated test event for validating the enhanced TEC Community Events template with 100% WordPress field support.',
// Enhanced taxonomy fields
categories: [1, 2], // Will map to actual category IDs
tags: ['TEC', 'enhanced', 'template', 'automated-test', 'field-population'],
// TEC specific fields
venue: 'Test Training Center',
organizer: 'Test HVAC Training Company',
start_date: '2025-09-20',
start_time: '10:00',
end_date: '2025-09-20',
end_time: '16:00',
cost: '199'
}
};
console.log('🧪 Enhanced TEC Template E2E Testing Suite (Headless)');
console.log(`🌐 Testing URL: ${config.baseUrl}`);
console.log('📋 Testing enhanced template with 100% field population');
console.log('');
async function runEnhancedTemplateTestHeadless() {
const browser = await chromium.launch({
headless: true, // Run in headless mode for server compatibility
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-web-security',
'--disable-features=VizDisplayCompositor'
]
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
});
const page = await context.newPage();
// Enhanced console logging
const consoleMessages = [];
page.on('console', msg => {
const message = msg.text();
consoleMessages.push(message);
if (message.includes('HVAC') ||
message.includes('Enhanced') ||
message.includes('Field Population') ||
message.includes('✅') ||
message.includes('❌')) {
console.log(`🔍 Browser: ${message}`);
}
});
// Track errors
const pageErrors = [];
page.on('pageerror', error => {
pageErrors.push(error.message);
console.error(`❌ Page Error: ${error.message}`);
});
// Track network failures
const networkFailures = [];
page.on('response', response => {
if (response.status() >= 400) {
networkFailures.push(`${response.status()} ${response.url()}`);
}
});
try {
console.log('📋 Step 1: Testing login functionality');
// Navigate to login with timeout handling
await page.goto(`${config.baseUrl}/training-login/`, {
waitUntil: 'networkidle',
timeout: config.timeout
});
// Take initial screenshot
await page.screenshot({
path: 'test-results/01-login-page.png',
fullPage: true
});
// Test login
const loginSuccess = await performLoginHeadless(page, config.testCredentials);
if (!loginSuccess) {
throw new Error('Login failed - cannot proceed with template testing');
}
console.log('📋 Step 2: Locating enhanced event creation form');
// Try multiple event creation URLs
const eventFormResult = await findEventCreationForm(page, config.baseUrl);
if (!eventFormResult.success) {
throw new Error(`Enhanced event creation form not found: ${eventFormResult.error}`);
}
console.log(`✅ Enhanced template found at: ${eventFormResult.url}`);
// Take template screenshot
await page.screenshot({
path: 'test-results/02-enhanced-template.png',
fullPage: true
});
console.log('📋 Step 3: Verifying enhanced template features');
const templateVerification = await verifyEnhancedTemplateHeadless(page);
console.log('📋 Step 4: Testing enhanced field population system');
const populationResults = await testEnhancedFieldPopulationHeadless(page, config.testEventData);
console.log('📋 Step 5: Testing individual field functionality');
const fieldTests = await testIndividualFieldsHeadless(page);
console.log('📋 Step 6: Testing form validation and submission readiness');
const submissionTest = await testFormSubmissionReadiness(page);
// Take final screenshot
await page.screenshot({
path: 'test-results/03-populated-form.png',
fullPage: true
});
console.log('📋 Step 7: Generating comprehensive test report');
const testReport = generateComprehensiveTestReport({
template_verification: templateVerification,
field_population: populationResults,
individual_fields: fieldTests,
form_submission: submissionTest,
page_errors: pageErrors,
network_failures: networkFailures,
console_messages: consoleMessages.slice(-20) // Last 20 messages
});
console.log('\n🎉 ENHANCED TEMPLATE TEST COMPLETE');
console.log('='.repeat(70));
console.log(testReport);
return testReport;
} catch (error) {
console.error('❌ Enhanced template test failed:', error.message);
// Take error screenshot
await page.screenshot({
path: 'test-results/error-state.png',
fullPage: true
});
// Log page content for debugging
const pageContent = await page.content();
console.log('📝 Page content length:', pageContent.length);
throw error;
} finally {
await browser.close();
}
}
async function performLoginHeadless(page, credentials) {
try {
console.log('🔐 Attempting login...');
// Wait for login form with multiple selectors
const loginSelectors = [
'input[name="log"]',
'#user_login',
'input[type="text"][name*="user"]',
'.wp-login-form input[type="text"]'
];
let usernameField = null;
for (const selector of loginSelectors) {
try {
await page.waitForSelector(selector, { timeout: 5000 });
usernameField = page.locator(selector).first();
break;
} catch (e) {
continue;
}
}
if (!usernameField || await usernameField.count() === 0) {
throw new Error('Username field not found');
}
const passwordField = page.locator('input[name="pwd"], #user_pass, input[type="password"]').first();
const submitButton = page.locator('input[type="submit"], button[type="submit"], .wp-submit').first();
if (await passwordField.count() === 0) {
throw new Error('Password field not found');
}
// Fill login form
await usernameField.fill(credentials.username);
await passwordField.fill(credentials.password);
// Submit and wait for navigation
await Promise.all([
page.waitForNavigation({ waitUntil: 'networkidle', timeout: 30000 }),
submitButton.click()
]);
// Check for login errors
const errorElement = page.locator('.login_error, .error, #login_error').first();
if (await errorElement.count() > 0) {
const errorText = await errorElement.textContent();
throw new Error(`Login failed: ${errorText}`);
}
// Verify successful login by checking for dashboard or profile elements
const loggedInIndicators = [
'.hvac-trainer-nav',
'.wp-admin-bar',
'body.logged-in',
'.dashboard',
'.trainer-dashboard'
];
let loggedIn = false;
for (const indicator of loggedInIndicators) {
if (await page.locator(indicator).count() > 0) {
loggedIn = true;
break;
}
}
if (!loggedIn) {
throw new Error('Login verification failed - logged in indicators not found');
}
console.log('✅ Login successful');
return true;
} catch (error) {
console.error('❌ Login error:', error.message);
return false;
}
}
async function findEventCreationForm(page, baseUrl) {
const eventCreateUrls = [
'/events/community/add/',
'/community/events/add/',
'/trainer/event/create/',
'/events/add/',
'/event/add/'
];
for (const url of eventCreateUrls) {
try {
console.log(`🔍 Trying: ${baseUrl}${url}`);
await page.goto(`${baseUrl}${url}`, {
waitUntil: 'networkidle',
timeout: 15000
});
// Check for enhanced template indicator
const enhancedIndicator = page.locator('.hvac-success-indicator, .hvac-tec-enhanced-form').first();
await enhancedIndicator.waitFor({ timeout: 5000 });
if (await enhancedIndicator.count() > 0) {
return { success: true, url: url };
}
} catch (e) {
console.log(`❌ URL ${url} failed: ${e.message}`);
continue;
}
}
// Try to find create event link from dashboard
try {
await page.goto(`${baseUrl}/trainer/dashboard/`, {
waitUntil: 'networkidle',
timeout: 15000
});
const createEventLink = page.locator('a').filter({ hasText: /create.*event/i }).first();
if (await createEventLink.count() > 0) {
await createEventLink.click();
await page.waitForLoadState('networkidle');
const enhancedIndicator = page.locator('.hvac-success-indicator, .hvac-tec-enhanced-form').first();
if (await enhancedIndicator.count() > 0) {
return { success: true, url: 'via-dashboard-link' };
}
}
} catch (e) {
console.log(`❌ Dashboard link method failed: ${e.message}`);
}
return { success: false, error: 'Enhanced template not found at any URL' };
}
async function verifyEnhancedTemplateHeadless(page) {
console.log('🔍 Verifying enhanced template features...');
const checks = {
enhanced_indicator: '.hvac-success-indicator',
enhanced_form: '.hvac-tec-enhanced-form',
enhanced_styles: '#hvac-tec-enhanced-styles',
excerpt_field: '#hvac_post_excerpt, textarea[name="post_excerpt"]',
categories_section: '#hvac-categories-section, .hvac-categories-container',
featured_image_section: '#hvac-featured-image-section, .hvac-featured-image-container',
tags_section: '#hvac-tags-section, .hvac-tags-container'
};
const results = {};
let foundCount = 0;
for (const [name, selector] of Object.entries(checks)) {
try {
const element = page.locator(selector).first();
const exists = await element.count() > 0;
results[name] = exists;
if (exists) {
console.log(`${name}: Found`);
foundCount++;
} else {
console.log(`${name}: Not found (${selector})`);
}
} catch (e) {
results[name] = false;
console.log(`${name}: Error checking (${e.message})`);
}
}
const totalChecks = Object.keys(checks).length;
const successRate = Math.round((foundCount / totalChecks) * 100);
console.log(`📊 Template verification: ${foundCount}/${totalChecks} features found (${successRate}%)`);
return {
success: successRate >= 60, // Lower threshold for initial testing
successRate: successRate,
results: results
};
}
async function testEnhancedFieldPopulationHeadless(page, eventData) {
console.log('🎯 Testing enhanced field population system...');
try {
// Check if enhanced system is available
const populationResult = await page.evaluate((testData) => {
// Test multiple population approaches
const results = {
enhanced_system: false,
basic_population: false,
field_access: {},
population_attempts: {}
};
// Check for enhanced system
if (window.HVACEnhancedFieldPopulation) {
results.enhanced_system = true;
try {
const accessTest = window.HVACEnhancedFieldPopulation.testFieldAccess();
const populationTest = window.HVACEnhancedFieldPopulation.populateAllFields(testData);
results.field_access = accessTest;
results.population_test = populationTest;
} catch (e) {
results.enhanced_error = e.message;
}
}
// Basic field population fallback
const basicFields = {
title: '#post_title, input[name="post_title"]',
excerpt: '#hvac_post_excerpt, textarea[name="post_excerpt"]',
content: '#tcepostcontent, textarea[name="content"]'
};
let basicPopulated = 0;
for (const [fieldName, selector] of Object.entries(basicFields)) {
const element = document.querySelector(selector);
if (element) {
results.field_access[fieldName] = true;
if (testData[fieldName]) {
try {
element.value = testData[fieldName];
element.dispatchEvent(new Event('input', { bubbles: true }));
results.population_attempts[fieldName] = true;
basicPopulated++;
} catch (e) {
results.population_attempts[fieldName] = false;
}
}
} else {
results.field_access[fieldName] = false;
}
}
results.basic_population = basicPopulated > 0;
results.basic_populated_count = basicPopulated;
return results;
}, eventData);
console.log('📊 Field Population Results:');
console.log(`🔧 Enhanced System Available: ${populationResult.enhanced_system ? 'Yes' : 'No'}`);
console.log(`🎯 Basic Population: ${populationResult.basic_population ? 'Yes' : 'No'}`);
if (populationResult.enhanced_system && populationResult.population_test) {
const rate = populationResult.population_test.successRate || 0;
console.log(`📈 Enhanced Population Rate: ${rate}%`);
}
if (populationResult.basic_population) {
console.log(`📈 Basic Fields Populated: ${populationResult.basic_populated_count}`);
}
return populationResult;
} catch (error) {
console.error('❌ Field population test failed:', error.message);
return { error: error.message };
}
}
async function testIndividualFieldsHeadless(page) {
console.log('🧪 Testing individual enhanced field functionality...');
const fieldTests = {};
// Test excerpt field
fieldTests.excerpt = await testFieldPresence(page, '#hvac_post_excerpt, textarea[name="post_excerpt"]', 'Excerpt');
// Test categories field
fieldTests.categories = await testFieldPresence(page, '#hvac-categories-section, .hvac-categories-container', 'Categories');
// Test featured image field
fieldTests.featured_image = await testFieldPresence(page, '#hvac-featured-image-section, .hvac-featured-image-container', 'Featured Image');
// Test tags field
fieldTests.tags = await testFieldPresence(page, '#hvac-tags-section, .hvac-tags-container', 'Tags');
// Test form elements
fieldTests.submit_button = await testFieldPresence(page, 'input[type="submit"], button[type="submit"]', 'Submit Button');
const totalTests = Object.keys(fieldTests).length;
const passedTests = Object.values(fieldTests).filter(Boolean).length;
const testSuccessRate = Math.round((passedTests / totalTests) * 100);
console.log(`📊 Individual field tests: ${passedTests}/${totalTests} passed (${testSuccessRate}%)`);
return {
success: testSuccessRate >= 60,
successRate: testSuccessRate,
results: fieldTests
};
}
async function testFieldPresence(page, selector, fieldName) {
try {
const element = page.locator(selector).first();
const exists = await element.count() > 0;
if (exists) {
console.log(`${fieldName} field: Present`);
// Test if field is interactive
const isVisible = await element.isVisible();
const isEnabled = await element.isEnabled();
if (isVisible && isEnabled) {
console.log(`${fieldName} field: Interactive`);
return true;
}
}
console.log(`${fieldName} field: Not found or not interactive`);
return false;
} catch (error) {
console.log(`${fieldName} field test failed: ${error.message}`);
return false;
}
}
async function testFormSubmissionReadiness(page) {
try {
// Check for form elements
const form = page.locator('form').first();
const submitButton = page.locator('input[type="submit"], button[type="submit"]').first();
if (await form.count() === 0) {
console.log('❌ Form submission test: No form found');
return false;
}
if (await submitButton.count() === 0) {
console.log('❌ Form submission test: No submit button found');
return false;
}
// Check if submit button is visible and enabled
const isVisible = await submitButton.isVisible();
const isEnabled = await submitButton.isEnabled();
if (isVisible && isEnabled) {
console.log('✅ Form submission test: Form ready for submission');
return true;
} else {
console.log('⚠️ Form submission test: Submit button not interactive');
return false;
}
} catch (error) {
console.log(`❌ Form submission test failed: ${error.message}`);
return false;
}
}
function generateComprehensiveTestReport(results) {
const {
template_verification,
field_population,
individual_fields,
form_submission,
page_errors,
network_failures,
console_messages
} = results;
let report = '\n📊 ENHANCED TEC TEMPLATE TEST REPORT (HEADLESS)\n';
report += '='.repeat(70) + '\n\n';
// Template verification
if (template_verification) {
report += `🔍 TEMPLATE VERIFICATION: ${template_verification.success ? '✅ PASSED' : '❌ FAILED'} (${template_verification.successRate}%)\n`;
}
// Field population results
if (field_population) {
if (field_population.enhanced_system) {
report += '🎯 ENHANCED FIELD SYSTEM: ✅ AVAILABLE\n';
if (field_population.population_test) {
const rate = field_population.population_test.successRate || 0;
report += ` 📈 Population Success Rate: ${rate}%\n`;
if (rate === 100) {
report += ' 🎉 TARGET ACHIEVED: 100% field population!\n';
}
}
} else {
report += '🎯 ENHANCED FIELD SYSTEM: ❌ NOT AVAILABLE\n';
if (field_population.basic_population) {
report += ` 📈 Basic Population: ${field_population.basic_populated_count} fields\n`;
}
}
}
// Individual field tests
if (individual_fields) {
report += `🧪 FIELD FUNCTIONALITY: ${individual_fields.success ? '✅ PASSED' : '❌ FAILED'} (${individual_fields.successRate}%)\n`;
}
// Form submission
report += `📤 FORM SUBMISSION: ${form_submission ? '✅ READY' : '⚠️ NEEDS CHECK'}\n`;
// Error analysis
if (page_errors.length > 0) {
report += `\n❌ PAGE ERRORS (${page_errors.length}):\n`;
page_errors.slice(0, 5).forEach((error, index) => {
report += ` ${index + 1}. ${error.substring(0, 100)}...\n`;
});
}
if (network_failures.length > 0) {
report += `\n🌐 NETWORK ISSUES (${network_failures.length}):\n`;
network_failures.slice(0, 3).forEach((failure, index) => {
report += ` ${index + 1}. ${failure}\n`;
});
}
// Overall assessment
const scores = [
template_verification?.successRate || 0,
field_population?.population_test?.successRate || (field_population?.basic_population ? 50 : 0),
individual_fields?.successRate || 0,
form_submission ? 100 : 0
];
const averageScore = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
report += '\n🏆 OVERALL ASSESSMENT:\n';
report += ` 📊 Average Score: ${averageScore}%\n`;
if (averageScore >= 90) {
report += ' 🎉 EXCELLENT: Ready for production deployment\n';
} else if (averageScore >= 75) {
report += ' ✅ GOOD: Minor improvements needed\n';
} else if (averageScore >= 60) {
report += ' ⚠️ ACCEPTABLE: Requires fixes before production\n';
} else {
report += ' ❌ POOR: Significant issues need resolution\n';
}
// Recommendations
report += '\n📋 RECOMMENDATIONS:\n';
if (template_verification?.successRate < 80) {
report += ' • Verify template override installation\n';
}
if (!field_population?.enhanced_system) {
report += ' • Check enhanced field population system integration\n';
}
if (individual_fields?.successRate < 80) {
report += ' • Review individual field implementations\n';
}
if (page_errors.length > 0) {
report += ' • Resolve JavaScript errors\n';
}
return report;
}
// Run the enhanced template test in headless mode
if (require.main === module) {
runEnhancedTemplateTestHeadless()
.then(report => {
console.log('\n✅ Enhanced TEC Template Test (Headless) completed');
process.exit(0);
})
.catch(error => {
console.error('\n❌ Enhanced TEC Template Test (Headless) failed:', error.message);
process.exit(1);
});
}
module.exports = { runEnhancedTemplateTestHeadless };