import { test, expect, Page } from '@playwright/test'; const BASE_URL = 'https://upskill-staging.measurequick.com'; // Helper function to login as trainer async function loginAsTrainer(page: Page) { await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', 'test_trainer'); await page.fill('#user_pass', 'TestTrainer123!'); await page.click('#wp-submit'); await page.waitForURL('**/wp-admin/**'); } // Helper function to login as master trainer async function loginAsMasterTrainer(page: Page) { await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', 'JoeMedosch@gmail.com'); await page.fill('#user_pass', 'JoeTrainer2025@'); await page.click('#wp-submit'); await page.waitForURL('**/wp-admin/**'); } // Helper function to login as admin async function loginAsAdmin(page: Page) { await page.goto(`${BASE_URL}/wp-login.php`); await page.fill('#user_login', 'admin'); await page.fill('#user_pass', 'admin_password'); await page.click('#wp-submit'); await page.waitForURL('**/wp-admin/**'); } test.describe('Trainer Registration Refactor', () => { test.beforeEach(async ({ page }) => { await page.goto(`${BASE_URL}/trainer-registration/`); }); test('should display refactored registration form structure', async ({ page }) => { // Test Personal Information section includes Application Details const personalSection = page.locator('.hvac-form-section').first(); await expect(personalSection.locator('h3')).toContainText('Personal Information'); await expect(personalSection.locator('#application_details')).toBeVisible(); // Test renamed Training Organization Information section await expect(page.locator('h3:has-text("Training Organization Information")')).toBeVisible(); // Test Organization Logo is required const orgLogoLabel = page.locator('label[for="org_logo"]'); await expect(orgLogoLabel).toContainText('Organization Logo'); await expect(orgLogoLabel.locator('.required')).toBeVisible(); // Test headquarters fields await expect(page.locator('#hq_city')).toBeVisible(); await expect(page.locator('#hq_state')).toBeVisible(); await expect(page.locator('#hq_country')).toBeVisible(); // Take screenshot of full form await page.screenshot({ path: 'screenshots/registration-form-refactor.png', fullPage: true }); }); test('should show/hide venue fields conditionally', async ({ page }) => { // Initially venue details should be hidden await expect(page.locator('#venue_details_wrapper')).toBeHidden(); // Click Yes to create venue await page.click('input[name="create_venue"][value="yes"]'); await expect(page.locator('#venue_details_wrapper')).toBeVisible(); // Verify auto-population of venue name await page.fill('#business_name', 'HVAC Pro Training'); await page.fill('#user_city', 'Miami'); // Trigger venue name update await page.locator('#user_city').blur(); await page.waitForTimeout(500); const venueName = await page.locator('#venue_name').inputValue(); expect(venueName).toBe('HVAC Pro Training of Miami'); // Take screenshot with venue fields visible await page.screenshot({ path: 'screenshots/venue-conditional-fields-visible.png' }); // Click No to hide venue fields await page.click('input[name="create_venue"][value="no"]'); await expect(page.locator('#venue_details_wrapper')).toBeHidden(); // Take screenshot with venue fields hidden await page.screenshot({ path: 'screenshots/venue-conditional-fields-hidden.png' }); }); test('should validate required fields', async ({ page }) => { // Try to submit without filling required fields await page.click('button[type="submit"]'); // Check for error messages await expect(page.locator('.hvac-form-errors')).toBeVisible(); // Specifically check org logo required validation await expect(page.locator('#org_logo_error')).toContainText('Organization Logo is required'); // Take screenshot of validation errors await page.screenshot({ path: 'screenshots/registration-validation-errors.png' }); }); }); test.describe('Venues Management', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display venues list page', async ({ page }) => { await page.goto('/trainer/venue/list/'); // Verify page elements await expect(page.locator('h1')).toContainText('Training Venues'); await expect(page.locator('.hvac-venues-table')).toBeVisible(); await expect(page.locator('a:has-text("Add New Venue")')).toBeVisible(); // Verify breadcrumb await expect(page.locator('.hvac-breadcrumbs')).toBeVisible(); // Test filter functionality await page.fill('input[name="search"]', 'Test Venue'); await page.click('button:has-text("Filter")'); // Take screenshot of venues list await page.screenshot({ path: 'screenshots/venues-list.png', fullPage: true }); }); test('should create new venue successfully', async ({ page }) => { await page.goto('/trainer/venue/manage/'); // Verify page title for new venue await expect(page.locator('h1')).toContainText('Create New Venue'); // Fill venue form await page.fill('#venue_name', 'Miami Training Center'); await page.fill('#venue_description', 'State-of-the-art HVAC training facility'); await page.fill('#venue_address', '123 Training Blvd'); await page.fill('#venue_city', 'Miami'); await page.fill('#venue_state', 'FL'); await page.fill('#venue_zip', '33101'); await page.selectOption('#venue_country', 'United States'); await page.fill('#venue_phone', '305-555-0123'); await page.fill('#venue_website', 'https://miamitraining.com'); // Take screenshot of filled form await page.screenshot({ path: 'screenshots/venue-create-form-filled.png' }); // Submit form await page.click('button:has-text("Create Venue")'); // Wait for success message await expect(page.locator('.hvac-message-success')).toBeVisible(); await expect(page.locator('.hvac-message-success')).toContainText('Venue created successfully'); // Verify form switches to edit mode await expect(page.locator('h1')).toContainText('Edit Venue'); await expect(page.locator('button:has-text("Update Venue")')).toBeVisible(); await expect(page.locator('#hvac-delete-venue')).toBeVisible(); // Take screenshot after creation await page.screenshot({ path: 'screenshots/venue-created-success.png' }); }); test('should validate venue form fields', async ({ page }) => { await page.goto('/trainer/venue/manage/'); // Try to submit empty form await page.click('button:has-text("Create Venue")'); // Check for validation errors await expect(page.locator('.hvac-error-message').first()).toBeVisible(); // Test phone validation await page.fill('#venue_phone', 'invalid-phone'); await page.locator('#venue_phone').blur(); await expect(page.locator('#venue_phone + .hvac-error-message')).toContainText('valid phone number'); // Test URL validation await page.fill('#venue_website', 'not-a-url'); await page.locator('#venue_website').blur(); await expect(page.locator('#venue_website + .hvac-error-message')).toContainText('valid website URL'); // Take screenshot of validation await page.screenshot({ path: 'screenshots/venue-validation-errors.png' }); }); }); test.describe('Profile Management', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display profile view with stats', async ({ page }) => { await page.goto('/trainer/profile/'); // Verify page structure await expect(page.locator('h1')).toContainText('Trainer Profile'); await expect(page.locator('a:has-text("Edit Profile")')).toBeVisible(); // Verify profile sections await expect(page.locator('.hvac-profile-sidebar')).toBeVisible(); await expect(page.locator('.hvac-profile-stats')).toBeVisible(); await expect(page.locator('.hvac-profile-main')).toBeVisible(); // Check stats display await expect(page.locator('.hvac-stat-label:has-text("Events Created")')).toBeVisible(); await expect(page.locator('.hvac-stat-label:has-text("Students Trained")')).toBeVisible(); // Take screenshot of profile view await page.screenshot({ path: 'screenshots/profile-view.png', fullPage: true }); }); test('should edit profile successfully', async ({ page }) => { await page.goto('/trainer/profile/edit/'); // Verify edit form await expect(page.locator('h1')).toContainText('Edit Profile'); // Update profile fields await page.fill('#years_experience', '15'); await page.fill('#certifications', 'NATE Certified\nEPA 608 Universal\nOSHA 10'); await page.fill('#phone', '555-123-4567'); await page.fill('#city', 'Orlando'); await page.fill('#state', 'FL'); await page.selectOption('#country', 'United States'); await page.fill('#linkedin', 'https://linkedin.com/in/hvactrainer'); await page.fill('#description', 'Experienced HVAC trainer with 15 years in the industry.'); // Take screenshot of edit form await page.screenshot({ path: 'screenshots/profile-edit-form.png', fullPage: true }); // Save changes await page.click('button:has-text("Save Changes")'); // Verify success message await expect(page.locator('.hvac-message-success')).toBeVisible(); await expect(page.locator('.hvac-message-success')).toContainText('Profile updated successfully'); // Take screenshot after save await page.screenshot({ path: 'screenshots/profile-edit-success.png' }); }); }); test.describe('Organizers Management', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display organizers list', async ({ page }) => { await page.goto('/trainer/organizer/list/'); // Verify page elements await expect(page.locator('h1')).toContainText('Training Organizers'); await expect(page.locator('.hvac-organizers-table')).toBeVisible(); await expect(page.locator('a:has-text("Add New Organizer")')).toBeVisible(); // Test search functionality await page.fill('input[name="search"]', 'HVAC'); await page.click('button:has-text("Search")'); // Take screenshot await page.screenshot({ path: 'screenshots/organizers-list.png', fullPage: true }); }); test('should create new organizer with logo', async ({ page }) => { await page.goto('/trainer/organizer/manage/'); // Verify page title await expect(page.locator('h1')).toContainText('Create New Organizer'); // Fill organizer form await page.fill('#org_name', 'Florida HVAC Institute'); await page.fill('#org_description', 'Leading HVAC training organization in Florida'); await page.fill('#hq_city', 'Tampa'); await page.fill('#hq_state', 'FL'); await page.selectOption('#hq_country', 'United States'); await page.fill('#org_phone', '813-555-0199'); await page.fill('#org_email', 'info@flhvac.edu'); await page.fill('#org_website', 'https://floridahvacinstitute.edu'); // Take screenshot of form await page.screenshot({ path: 'screenshots/organizer-create-form.png' }); // Submit form await page.click('button:has-text("Create Organizer")'); // Verify success await expect(page.locator('.hvac-message-success')).toBeVisible(); await expect(page.locator('.hvac-message-success')).toContainText('Organizer created successfully'); // Verify edit mode await expect(page.locator('h1')).toContainText('Edit Organizer'); await expect(page.locator('#hvac-delete-organizer')).toBeVisible(); // Take screenshot after creation await page.screenshot({ path: 'screenshots/organizer-created-success.png' }); }); test('should validate organizer required fields', async ({ page }) => { await page.goto('/trainer/organizer/manage/'); // Submit empty form await page.click('button:has-text("Create Organizer")'); // Check for validation errors await expect(page.locator('.hvac-error-message').first()).toBeVisible(); await expect(page.locator('#org_name + .hvac-error-message')).toContainText('Organization Name is required'); await expect(page.locator('#hq_city + .hvac-error-message')).toContainText('Headquarters City is required'); // Test email validation await page.fill('#org_email', 'invalid-email'); await page.locator('#org_email').blur(); await expect(page.locator('#org_email + .hvac-error-message')).toContainText('valid email address'); // Take screenshot await page.screenshot({ path: 'screenshots/organizer-validation-errors.png' }); }); }); test.describe('Navigation and Layout Fixes', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display horizontal navigation menu (not column layout)', async ({ page }) => { // Test certificate reports page navigation layout await page.goto(`${BASE_URL}/trainer/certificate-reports/`); // Verify navigation is horizontal (flexbox layout) const menu = page.locator('.hvac-trainer-menu'); await expect(menu).toBeVisible(); // Check that menu uses flexbox (horizontal layout) const menuStyle = await menu.evaluate((el) => getComputedStyle(el).display); expect(menuStyle).toBe('flex'); // Verify menu items are in a row, not column const menuItems = page.locator('.hvac-trainer-menu .menu-item'); await expect(menuItems.first()).toBeVisible(); // Take screenshot to verify horizontal layout await page.screenshot({ path: 'screenshots/navigation-horizontal-layout.png', fullPage: true }); }); test('should display new breadcrumb system on all pages', async ({ page }) => { // Test venues breadcrumb await page.goto(`${BASE_URL}/trainer/venue/list/`); await expect(page.locator('.hvac-breadcrumbs')).toBeVisible(); await expect(page.locator('.hvac-breadcrumb-list')).toBeVisible(); // Test profile breadcrumb await page.goto(`${BASE_URL}/trainer/profile/`); await expect(page.locator('.hvac-breadcrumbs')).toBeVisible(); // Test organizers breadcrumb await page.goto(`${BASE_URL}/trainer/organizer/list/`); await expect(page.locator('.hvac-breadcrumbs')).toBeVisible(); // Test certificate reports breadcrumb await page.goto(`${BASE_URL}/trainer/certificate-reports/`); await expect(page.locator('.hvac-breadcrumbs')).toBeVisible(); // Take screenshot of breadcrumb system await page.screenshot({ path: 'screenshots/breadcrumb-system.png' }); }); test('should verify certificate pages display properly', async ({ page }) => { // Test certificate reports page await page.goto(`${BASE_URL}/trainer/certificate-reports/`); await expect(page.locator('h1')).toContainText('Certificate Reports'); await expect(page.locator('.hvac-certificate-stats')).toBeVisible(); // Verify page structure is correct (not blank) await expect(page.locator('.hvac-page-wrapper')).toBeVisible(); await expect(page.locator('.hvac-container')).toBeVisible(); // Test generate certificates page await page.goto(`${BASE_URL}/trainer/generate-certificates/`); await expect(page.locator('h1')).toContainText('Generate Certificates'); await expect(page.locator('.hvac-certificate-form')).toBeVisible(); // Take screenshots await page.screenshot({ path: 'screenshots/certificate-reports-fixed.png', fullPage: true }); }); }); test.describe('Access Control - Multiple User Roles', () => { test('trainer role should access all trainer pages', async ({ page }) => { await loginAsTrainer(page); // Test all trainer pages are accessible const trainerPages = [ '/trainer/dashboard/', '/trainer/profile/', '/trainer/profile/edit/', '/trainer/venue/list/', '/trainer/venue/manage/', '/trainer/organizer/list/', '/trainer/organizer/manage/', '/trainer/certificate-reports/', '/trainer/generate-certificates/' ]; for (const pageUrl of trainerPages) { await page.goto(`${BASE_URL}${pageUrl}`); // Should not show access denied message await expect(page.locator('p:has-text("You must be a trainer")')).not.toBeVisible(); await expect(page.locator('p:has-text("You must be logged in")')).not.toBeVisible(); } await page.screenshot({ path: 'screenshots/trainer-access-control.png' }); }); test('master trainer role should access all trainer pages', async ({ page }) => { await loginAsMasterTrainer(page); // Test master trainer can access regular trainer pages await page.goto(`${BASE_URL}/trainer/venue/list/`); await expect(page.locator('h1')).toContainText('Training Venues'); await page.goto(`${BASE_URL}/trainer/profile/`); await expect(page.locator('h1')).toContainText('Trainer Profile'); await page.goto(`${BASE_URL}/trainer/organizer/list/`); await expect(page.locator('h1')).toContainText('Training Organizers'); // Should also access master dashboard await page.goto(`${BASE_URL}/master-trainer/master-dashboard/`); await expect(page.locator('h1')).toContainText('Master Dashboard'); await page.screenshot({ path: 'screenshots/master-trainer-access-control.png' }); }); }); test.describe('Enhanced Profile System', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display new profile system (not old Business Information)', async ({ page }) => { await page.goto(`${BASE_URL}/trainer/profile/`); // Should NOT show old "Business Information" section await expect(page.locator('h2:has-text("Business Information")')).not.toBeVisible(); // Should show new profile structure await expect(page.locator('.hvac-profile-sidebar')).toBeVisible(); await expect(page.locator('.hvac-profile-main')).toBeVisible(); await expect(page.locator('.hvac-profile-stats')).toBeVisible(); // Should show new sections await expect(page.locator('h2:has-text("Personal Information")')).toBeVisible(); await expect(page.locator('h2:has-text("Training Organization")')).toBeVisible(); await page.screenshot({ path: 'screenshots/new-profile-system.png', fullPage: true }); }); }); test.describe('Organizers and Venues Content Verification', () => { test.beforeEach(async ({ page }) => { await loginAsTrainer(page); }); test('should display organizers list content (not blank)', async ({ page }) => { await page.goto(`${BASE_URL}/trainer/organizer/list/`); // Should not be blank await expect(page.locator('.hvac-organizers-list')).toBeVisible(); await expect(page.locator('h1')).toContainText('Training Organizers'); await expect(page.locator('a:has-text("Add New Organizer")')).toBeVisible(); // Verify page has actual content, not just whitespace const bodyText = await page.locator('body').textContent(); expect(bodyText?.trim().length).toBeGreaterThan(100); await page.screenshot({ path: 'screenshots/organizers-not-blank.png', fullPage: true }); }); test('should display venues list content (not blank)', async ({ page }) => { await page.goto(`${BASE_URL}/trainer/venue/list/`); // Should not be blank await expect(page.locator('.hvac-venues-list')).toBeVisible(); await expect(page.locator('h1')).toContainText('Training Venues'); await expect(page.locator('a:has-text("Add New Venue")')).toBeVisible(); // Verify page has actual content, not just whitespace const bodyText = await page.locator('body').textContent(); expect(bodyText?.trim().length).toBeGreaterThan(100); await page.screenshot({ path: 'screenshots/venues-not-blank.png', fullPage: true }); }); });