/** * 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: `

TEC Template Enhancement Validation

This event tests the enhanced TEC Community Events template with 100% field population capabilities.

Enhanced Features:

`, 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 };