upskill-event-manager/tests/e2e/hvac-final-comprehensive.test.js
Ben 7c9ca65cf2
Some checks are pending
HVAC Plugin CI/CD Pipeline / Security Analysis (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Code Quality & Standards (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Unit Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Integration Tests (push) Waiting to run
HVAC Plugin CI/CD Pipeline / Deploy to Staging (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Deploy to Production (push) Blocked by required conditions
HVAC Plugin CI/CD Pipeline / Notification (push) Blocked by required conditions
Security Monitoring & Compliance / Dependency Vulnerability Scan (push) Waiting to run
Security Monitoring & Compliance / Secrets & Credential Scan (push) Waiting to run
Security Monitoring & Compliance / WordPress Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Static Code Security Analysis (push) Waiting to run
Security Monitoring & Compliance / Security Compliance Validation (push) Waiting to run
Security Monitoring & Compliance / Security Summary Report (push) Blocked by required conditions
Security Monitoring & Compliance / Security Team Notification (push) Blocked by required conditions
feat: add comprehensive test framework and test files
- Add 90+ test files including E2E, unit, and integration tests
- Implement Page Object Model (POM) architecture
- Add Docker testing environment with comprehensive services
- Include modernized test framework with error recovery
- Add specialized test suites for master trainer and trainer workflows
- Update .gitignore to properly track test infrastructure

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 23:23:26 -03:00

442 lines
No EOL
16 KiB
JavaScript

/**
* 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'
}
};