- Implemented comprehensive trainer navigation system:
* Horizontal and vertical navigation layouts
* Multi-level menu with dropdowns for Events, Venues, Organizers, Profile
* Responsive mobile navigation with hamburger menu
* Keyboard navigation support (Arrow keys, Enter, Escape)
* Active page highlighting
* Master trainer menu items for users with appropriate role
- Created breadcrumb system:
* Automatic breadcrumb generation based on URL structure
* Shortcode support [hvac_breadcrumbs]
* SEO-friendly with structured data (Schema.org)
* Multiple style options (default, pills, arrows)
* Responsive design
- Technical implementation:
* HVAC_Trainer_Navigation class for menu management
* HVAC_Breadcrumbs class for breadcrumb generation
* CSS for both navigation and breadcrumbs
* JavaScript for interactive menu behaviors
* Template part for easy inclusion
Navigation provides easy access to all trainer features and improves UX.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
361 lines
No EOL
13 KiB
TypeScript
361 lines
No EOL
13 KiB
TypeScript
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', 'password123');
|
|
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-breadcrumb')).toContainText('Trainer > Venues > List');
|
|
|
|
// 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 Breadcrumbs', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await loginAsTrainer(page);
|
|
});
|
|
|
|
test('should display proper breadcrumbs on all pages', async ({ page }) => {
|
|
// Test venues breadcrumb
|
|
await page.goto('/trainer/venue/list/');
|
|
await expect(page.locator('.hvac-breadcrumb')).toContainText('Trainer > Venues > List');
|
|
|
|
// Test profile breadcrumb
|
|
await page.goto('/trainer/profile/');
|
|
await expect(page.locator('.hvac-breadcrumb')).toContainText('Trainer > Profile > View');
|
|
|
|
// Test organizers breadcrumb
|
|
await page.goto('/trainer/organizer/list/');
|
|
await expect(page.locator('.hvac-breadcrumb')).toContainText('Trainer > Organizers > List');
|
|
|
|
// Take screenshot of navigation
|
|
await page.screenshot({
|
|
path: 'screenshots/breadcrumb-navigation.png'
|
|
});
|
|
});
|
|
}); |