/** * HVAC Final Comprehensive E2E Test Suite * Complete end-to-end testing for event creation and editing functionality * * @package HVAC_Community_Events * @version 2.0.0 * @created 2025-08-13 */ const { test, expect, devices } = require('@playwright/test'); const path = require('path'); const fs = require('fs').promises; // Test configuration const BASE_URL = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com'; const TEST_TIMEOUT = 60000; // Test credentials const TEST_USER = { email: 'test_trainer@example.com', password: 'TestTrainer123!', name: 'Test Trainer' }; // Test data const TEST_EVENT = { title: `Test Event ${Date.now()}`, description: 'This is a comprehensive test event created by Playwright E2E testing suite.', startDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now endDate: new Date(Date.now() + 8 * 24 * 60 * 60 * 1000), // 8 days from now venue: 'Test Training Center', organizer: 'Test Training Organization', category: 'HVAC Training', tags: ['test', 'automation', 'e2e'] }; // Helper functions async function login(page) { await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', TEST_USER.email); await page.fill('#user_pass', TEST_USER.password); await page.click('#wp-submit'); await page.waitForURL(/trainer\/dashboard/); } async function navigateToEventCreation(page) { await page.goto(`${BASE_URL}/trainer/events/create/`); await page.waitForSelector('.hvac-event-form-wrapper, iframe#tec-create-frame', { timeout: 10000 }); } async function fillEventForm(page, eventData) { // Check if using iframe const iframe = await page.$('iframe#tec-create-frame'); const context = iframe ? await iframe.contentFrame() : page; // Fill basic fields await context.fill('input[name="post_title"], #tribe-events-title', eventData.title); // Fill description with TinyMCE or textarea const descriptionField = await context.$('#tinyMCE, #content, textarea[name="post_content"]'); if (descriptionField) { await descriptionField.fill(eventData.description); } // Set dates const startDateInput = await context.$('input[name="EventStartDate"], #EventStartDate'); if (startDateInput) { await startDateInput.fill(eventData.startDate.toISOString().split('T')[0]); } const endDateInput = await context.$('input[name="EventEndDate"], #EventEndDate'); if (endDateInput) { await endDateInput.fill(eventData.endDate.toISOString().split('T')[0]); } // Add venue if field exists const venueInput = await context.$('input[name="venue[Venue]"], #venue-name'); if (venueInput) { await venueInput.fill(eventData.venue); } // Add organizer if field exists const organizerInput = await context.$('input[name="organizer[Organizer]"], #organizer-name'); if (organizerInput) { await organizerInput.fill(eventData.organizer); } } async function submitEventForm(page) { const iframe = await page.$('iframe#tec-create-frame'); const context = iframe ? await iframe.contentFrame() : page; // Find and click submit button const submitButton = await context.$('button[type="submit"], input[type="submit"], .tribe-submit-event-button'); if (submitButton) { await submitButton.click(); } } async function takeScreenshot(page, name) { const screenshotDir = path.join(__dirname, '../../screenshots'); await fs.mkdir(screenshotDir, { recursive: true }); await page.screenshot({ path: path.join(screenshotDir, `${name}-${Date.now()}.png`), fullPage: true }); } // Test suite test.describe('HVAC Final Comprehensive Test Suite', () => { test.setTimeout(TEST_TIMEOUT); test.beforeEach(async ({ page }) => { // Set viewport await page.setViewportSize({ width: 1280, height: 720 }); }); test.describe('Authentication Tests', () => { test('should login successfully as trainer', async ({ page }) => { await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', TEST_USER.email); await page.fill('#user_pass', TEST_USER.password); await page.click('#wp-submit'); // Verify redirect to dashboard await expect(page).toHaveURL(/trainer\/dashboard/, { timeout: 10000 }); // Verify dashboard elements await expect(page.locator('.hvac-dashboard-header')).toBeVisible(); await takeScreenshot(page, 'dashboard-after-login'); }); test('should maintain session across pages', async ({ page }) => { await login(page); // Navigate to different pages await page.goto(`${BASE_URL}/trainer/certificate-reports/`); await expect(page.locator('.hvac-page-header, h1')).toBeVisible(); await page.goto(`${BASE_URL}/trainer/profile/`); await expect(page.locator('.hvac-profile-content, .hvac-page-header')).toBeVisible(); // Verify still logged in const logoutLink = await page.$('a[href*="logout"]'); expect(logoutLink).toBeTruthy(); }); }); test.describe('Event Creation Tests', () => { test('should display event creation form with all fields', async ({ page }) => { await login(page); await navigateToEventCreation(page); // Check for form presence const formExists = await page.locator('.hvac-event-form-wrapper, iframe#tec-create-frame').isVisible(); expect(formExists).toBeTruthy(); // If iframe, check inside iframe const iframe = await page.$('iframe#tec-create-frame'); if (iframe) { const frame = await iframe.contentFrame(); // Check for required fields await expect(frame.locator('input[name="post_title"], #tribe-events-title')).toBeVisible(); await expect(frame.locator('#tinyMCE, #content, textarea[name="post_content"]')).toBeVisible(); } await takeScreenshot(page, 'event-creation-form'); }); test('should create event with minimal required fields', async ({ page }) => { await login(page); await navigateToEventCreation(page); // Fill minimal required fields await fillEventForm(page, { title: `Minimal Test Event ${Date.now()}`, description: 'Minimal test event description' }); await takeScreenshot(page, 'event-form-filled-minimal'); // Submit form await submitEventForm(page); // Wait for success indication await page.waitForTimeout(3000); // Check for success message or redirect const currentUrl = page.url(); const hasSuccess = currentUrl.includes('success') || currentUrl.includes('event') || currentUrl.includes('dashboard'); expect(hasSuccess).toBeTruthy(); await takeScreenshot(page, 'event-created-minimal'); }); test('should create event with all fields', async ({ page }) => { await login(page); await navigateToEventCreation(page); // Fill all fields await fillEventForm(page, TEST_EVENT); await takeScreenshot(page, 'event-form-filled-complete'); // Submit form await submitEventForm(page); // Wait for processing await page.waitForTimeout(3000); await takeScreenshot(page, 'event-created-complete'); }); test('should validate required fields', async ({ page }) => { await login(page); await navigateToEventCreation(page); // Try to submit without filling required fields await submitEventForm(page); // Check for validation messages await page.waitForTimeout(2000); const iframe = await page.$('iframe#tec-create-frame'); const context = iframe ? await iframe.contentFrame() : page; // Look for error messages const errorVisible = await context.locator('.error, .tribe-error, .validation-error').count() > 0; await takeScreenshot(page, 'validation-errors'); }); }); test.describe('Event Editing Tests', () => { test('should navigate to event list', async ({ page }) => { await login(page); await page.goto(`${BASE_URL}/trainer/events/`); // Check for event list await expect(page.locator('.hvac-events-list, .tribe-events-list, table')).toBeVisible(); await takeScreenshot(page, 'event-list'); }); test('should open event for editing', async ({ page }) => { await login(page); await page.goto(`${BASE_URL}/trainer/events/`); // Find edit link for first event const editLink = await page.$('a[href*="edit"], .edit-link, .tribe-edit-link'); if (editLink) { await editLink.click(); await page.waitForTimeout(3000); // Check if edit form loaded const formVisible = await page.locator('.hvac-event-form-wrapper, iframe, form').isVisible(); expect(formVisible).toBeTruthy(); await takeScreenshot(page, 'event-edit-form'); } }); test('should update event title', async ({ page }) => { await login(page); await page.goto(`${BASE_URL}/trainer/events/`); // Find and click edit link const editLink = await page.$('a[href*="edit"], .edit-link'); if (editLink) { await editLink.click(); await page.waitForTimeout(3000); // Update title const iframe = await page.$('iframe'); const context = iframe ? await iframe.contentFrame() : page; const titleInput = await context.$('input[name="post_title"], #tribe-events-title'); if (titleInput) { await titleInput.fill(`Updated Event ${Date.now()}`); await submitEventForm(page); await page.waitForTimeout(3000); await takeScreenshot(page, 'event-updated'); } } }); }); test.describe('Navigation Tests', () => { test('should have working navigation menu', async ({ page }) => { await login(page); // Check for navigation menu await expect(page.locator('.hvac-trainer-nav, .hvac-nav-menu')).toBeVisible(); // Test navigation links const navLinks = [ { selector: 'a[href*="dashboard"]', url: /dashboard/ }, { selector: 'a[href*="certificate"]', url: /certificate/ }, { selector: 'a[href*="profile"]', url: /profile/ } ]; for (const link of navLinks) { const element = await page.$(link.selector); if (element) { const href = await element.getAttribute('href'); expect(href).toBeTruthy(); } } await takeScreenshot(page, 'navigation-menu'); }); test('should have mobile-responsive navigation', async ({ page }) => { // Set mobile viewport await page.setViewportSize({ width: 375, height: 667 }); await login(page); // Check for hamburger menu const hamburger = await page.$('.hvac-menu-toggle, .menu-toggle, .hamburger'); if (hamburger) { await hamburger.click(); await page.waitForTimeout(500); // Check if menu opened const menuVisible = await page.locator('.hvac-nav-menu.mobile-active, .menu-open').isVisible(); await takeScreenshot(page, 'mobile-navigation-open'); } }); }); test.describe('Cross-Browser Tests', () => { ['chromium', 'firefox', 'webkit'].forEach(browserName => { test(`should work in ${browserName}`, async ({ browser }) => { const context = await browser.newContext(); const page = await context.newPage(); await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', TEST_USER.email); await page.fill('#user_pass', TEST_USER.password); await page.click('#wp-submit'); // Wait for dashboard await page.waitForURL(/trainer\/dashboard/, { timeout: 15000 }); // Verify page loaded const dashboardVisible = await page.locator('.hvac-dashboard-header, h1').isVisible(); expect(dashboardVisible).toBeTruthy(); await page.screenshot({ path: path.join(__dirname, `../../screenshots/cross-browser-${browserName}-${Date.now()}.png`) }); await context.close(); }); }); }); test.describe('Performance Tests', () => { test('should load dashboard within acceptable time', async ({ page }) => { const startTime = Date.now(); await login(page); const loadTime = Date.now() - startTime; console.log(`Dashboard load time: ${loadTime}ms`); // Should load within 10 seconds expect(loadTime).toBeLessThan(10000); }); test('should handle rapid navigation', async ({ page }) => { await login(page); // Rapidly navigate between pages const pages = [ '/trainer/dashboard/', '/trainer/events/', '/trainer/certificate-reports/', '/trainer/profile/' ]; for (const pagePath of pages) { await page.goto(`${BASE_URL}${pagePath}`); await page.waitForLoadState('domcontentloaded'); } // Should not crash or hang const finalPageLoaded = await page.locator('body').isVisible(); expect(finalPageLoaded).toBeTruthy(); }); }); test.describe('Accessibility Tests', () => { test('should have proper ARIA labels', async ({ page }) => { await login(page); // Check for ARIA labels on interactive elements const buttons = await page.$$('button, a[role="button"]'); for (const button of buttons.slice(0, 5)) { // Check first 5 buttons const ariaLabel = await button.getAttribute('aria-label'); const text = await button.textContent(); // Should have either aria-label or text content expect(ariaLabel || text).toBeTruthy(); } }); test('should support keyboard navigation', async ({ page }) => { await login(page); // Test tab navigation await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); await page.keyboard.press('Tab'); // Check if an element has focus const focusedElement = await page.evaluate(() => document.activeElement.tagName); expect(focusedElement).not.toBe('BODY'); }); }); }); // Export test configuration module.exports = { testDir: __dirname, timeout: TEST_TIMEOUT, retries: 1, workers: 1, use: { baseURL: BASE_URL, screenshot: 'only-on-failure', video: 'retain-on-failure', trace: 'on-first-retry' } };