const { test, expect } = require('@playwright/test'); /** * E2E Tests for Trainer Approval Journey * * Tests the complete workflow from registration to approval */ // Test configuration const baseURL = process.env.SITE_URL || 'http://localhost:8888'; const adminEmail = process.env.ADMIN_EMAIL || 'admin@example.com'; const adminPassword = process.env.ADMIN_PASSWORD || 'password'; // Test data const testTrainer = { email: `test_${Date.now()}@example.com`, password: 'TestPass123!', firstName: 'Test', lastName: 'Trainer', displayName: 'Test Trainer', businessName: 'Test HVAC Training Co', businessPhone: '555-123-4567', businessEmail: 'business@testtraining.com', businessDescription: 'Test training company for HVAC professionals', country: 'United States', state: 'California', city: 'Los Angeles', zip: '90001', applicationDetails: 'Testing the trainer approval workflow' }; test.describe('Trainer Approval Journey', () => { test('Complete trainer registration and approval workflow', async ({ page }) => { // Step 1: Register as a new trainer await test.step('Register new trainer account', async () => { await page.goto(`${baseURL}/trainer/registration/`); // Fill in account information await page.fill('#user_email', testTrainer.email); await page.fill('#user_pass', testTrainer.password); await page.fill('#confirm_password', testTrainer.password); // Fill in personal information await page.fill('#first_name', testTrainer.firstName); await page.fill('#last_name', testTrainer.lastName); await page.fill('#display_name', testTrainer.displayName); await page.fill('#description', 'Experienced HVAC trainer with 10+ years in the field'); // Fill in business information await page.fill('#business_name', testTrainer.businessName); await page.fill('#business_phone', testTrainer.businessPhone); await page.fill('#business_email', testTrainer.businessEmail); await page.fill('#business_description', testTrainer.businessDescription); // Fill in address information await page.selectOption('#user_country', testTrainer.country); await page.selectOption('#user_state', testTrainer.state); await page.fill('#user_city', testTrainer.city); await page.fill('#user_zip', testTrainer.zip); // Training venue await page.check('input[name="create_venue"][value="Yes"]'); // Training information await page.check('input[name="business_type"][value="Educator"]'); await page.check('input[name="training_audience[]"][value="Industry professionals"]'); await page.check('input[name="training_formats[]"][value="In-person"]'); await page.check('input[name="training_locations[]"][value="Local"]'); await page.check('input[name="training_resources[]"][value="Classroom"]'); // Application details await page.fill('#application_details', testTrainer.applicationDetails); // Submit registration await page.click('input[type="submit"][value="Register"]'); // Verify redirect to pending page await page.waitForURL(`${baseURL}/registration-pending/`); await expect(page.locator('h1')).toContainText('Account is Pending Approval'); }); // Step 2: Try to access trainer dashboard (should redirect to pending page) await test.step('Verify pending trainer cannot access dashboard', async () => { // Log in as the new trainer await page.goto(`${baseURL}/community-login/`); await page.fill('input[name="log"]', testTrainer.email); await page.fill('input[name="pwd"]', testTrainer.password); await page.click('input[type="submit"]'); // Try to access dashboard await page.goto(`${baseURL}/trainer/dashboard/`); // Should be redirected to pending page await page.waitForURL(`${baseURL}/trainer-account-pending/`); await expect(page.locator('h1')).toContainText('Your Account is Pending Approval'); }); // Step 3: Log in as admin/master trainer and view pending trainers await test.step('View pending trainers in master dashboard', async () => { // Log out current user await page.goto(`${baseURL}/wp-login.php?action=logout`); await page.click('a:has-text("log out")'); // Log in as admin await page.goto(`${baseURL}/wp-login.php`); await page.fill('#user_login', adminEmail); await page.fill('#user_pass', adminPassword); await page.click('#wp-submit'); // Navigate to master dashboard await page.goto(`${baseURL}/master-trainer/dashboard/`); // Filter by pending status await page.selectOption('#trainer-status-filter', 'pending'); await page.click('#apply-trainer-filters'); // Wait for table to load await page.waitForSelector('.trainers-table'); // Verify our test trainer appears in the list await expect(page.locator('td:has-text("' + testTrainer.displayName + '")')).toBeVisible(); await expect(page.locator('td:has-text("' + testTrainer.email + '")')).toBeVisible(); await expect(page.locator('.status-badge.status-pending')).toBeVisible(); }); // Step 4: Approve the trainer using bulk update await test.step('Approve trainer using bulk update', async () => { // Select the trainer const checkbox = page.locator(`input.trainer-checkbox[value]:has(~ td:has-text("${testTrainer.email}"))`); await checkbox.check(); // Select approved status await page.selectOption('#bulk-status-update', 'approved'); // Click update button await page.click('#bulk-update-btn'); // Confirm in dialog page.on('dialog', dialog => dialog.accept()); // Wait for success message await expect(page.locator('#bulk-update-message')).toBeVisible(); await expect(page.locator('#bulk-update-message')).toContainText('Successfully updated'); // Verify status changed in table await page.selectOption('#trainer-status-filter', 'approved'); await page.click('#apply-trainer-filters'); await page.waitForSelector('.trainers-table'); await expect(page.locator('.status-badge.status-approved')).toBeVisible(); }); // Step 5: Log back in as trainer and verify access await test.step('Verify approved trainer can access dashboard', async () => { // Log out admin await page.goto(`${baseURL}/wp-login.php?action=logout`); await page.click('a:has-text("log out")'); // Log in as trainer await page.goto(`${baseURL}/community-login/`); await page.fill('input[name="log"]', testTrainer.email); await page.fill('input[name="pwd"]', testTrainer.password); await page.click('input[type="submit"]'); // Access dashboard await page.goto(`${baseURL}/trainer/dashboard/`); // Should not be redirected await expect(page).toHaveURL(`${baseURL}/trainer/dashboard/`); await expect(page.locator('h1')).toContainText('Trainer Dashboard'); // Verify can access other trainer pages await page.goto(`${baseURL}/trainer/event/manage/`); await expect(page.locator('h1')).toContainText('Create New Event'); }); // Step 6: Test disable functionality await test.step('Test disabling trainer account', async () => { // Log back in as admin await page.goto(`${baseURL}/wp-login.php?action=logout`); await page.click('a:has-text("log out")'); await page.goto(`${baseURL}/wp-login.php`); await page.fill('#user_login', adminEmail); await page.fill('#user_pass', adminPassword); await page.click('#wp-submit'); // Navigate to master dashboard await page.goto(`${baseURL}/master-trainer/dashboard/`); // Find and disable the trainer await page.selectOption('#trainer-status-filter', 'approved'); await page.click('#apply-trainer-filters'); await page.waitForSelector('.trainers-table'); const checkbox = page.locator(`input.trainer-checkbox[value]:has(~ td:has-text("${testTrainer.email}"))`); await checkbox.check(); await page.selectOption('#bulk-status-update', 'disabled'); await page.click('#bulk-update-btn'); page.on('dialog', dialog => dialog.accept()); await expect(page.locator('#bulk-update-message')).toBeVisible(); }); // Step 7: Verify disabled trainer cannot access dashboard await test.step('Verify disabled trainer is redirected', async () => { // Log out admin await page.goto(`${baseURL}/wp-login.php?action=logout`); await page.click('a:has-text("log out")'); // Log in as trainer await page.goto(`${baseURL}/community-login/`); await page.fill('input[name="log"]', testTrainer.email); await page.fill('input[name="pwd"]', testTrainer.password); await page.click('input[type="submit"]'); // Try to access dashboard await page.goto(`${baseURL}/trainer/dashboard/`); // Should be redirected to disabled page await page.waitForURL(`${baseURL}/trainer-account-disabled/`); await expect(page.locator('h1')).toContainText('Account Access Restricted'); }); }); test('Test email approval link workflow', async ({ page }) => { // This test would require email interception or a test email service // For now, we'll test the approval URL directly // Create a test trainer first const approvalTestTrainer = { email: `approval_test_${Date.now()}@example.com`, // ... other fields }; // Register trainer (abbreviated for this test) // In real scenario, this would go through full registration // Simulate clicking approval link // The actual implementation would extract this from the email // await page.goto(`${baseURL}/master-trainer/dashboard/?hvac_approve_trainer=123&hvac_approval_token=abc123`); // This is a placeholder for the email approval test expect(true).toBe(true); }); test('Test trainer table filtering and search', async ({ page }) => { // Log in as admin await page.goto(`${baseURL}/wp-login.php`); await page.fill('#user_login', adminEmail); await page.fill('#user_pass', adminPassword); await page.click('#wp-submit'); // Navigate to master dashboard await page.goto(`${baseURL}/master-trainer/dashboard/`); await test.step('Test status filtering', async () => { // Test each status filter const statuses = ['all', 'pending', 'approved', 'active', 'inactive', 'disabled']; for (const status of statuses) { await page.selectOption('#trainer-status-filter', status); await page.click('#apply-trainer-filters'); await page.waitForSelector('#trainers-table-container'); // Verify table loaded const hasTable = await page.locator('.trainers-table').count() > 0 || await page.locator('.no-data-message').count() > 0; expect(hasTable).toBe(true); } }); await test.step('Test search functionality', async () => { // Reset filters await page.click('#reset-trainer-filters'); // Search for a trainer await page.fill('#trainer-search', 'test'); await page.click('#apply-trainer-filters'); await page.waitForSelector('#trainers-table-container'); // Verify results const hasResults = await page.locator('.trainers-table').count() > 0 || await page.locator('.no-data-message').count() > 0; expect(hasResults).toBe(true); }); await test.step('Test pagination', async () => { // Reset filters to show all await page.click('#reset-trainer-filters'); await page.waitForSelector('#trainers-table-container'); // Check if pagination exists const hasPagination = await page.locator('.pagination-container').count() > 0; if (hasPagination) { // Click next page if available const nextButton = page.locator('.pagination-btn:has-text("Next")'); if (await nextButton.count() > 0) { await nextButton.click(); await page.waitForSelector('#trainers-table-container'); } } expect(true).toBe(true); // Test completed without errors }); }); });