- Create comprehensive Node.js-based trainer journey test - Implement event creation, dashboard verification, and certificate testing - Add robust error handling and detailed logging - Bypass Playwright framework issues with direct Playwright API usage - Ensure test can run independently of test framework configuration
		
			
				
	
	
		
			456 lines
		
	
	
		
			No EOL
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			456 lines
		
	
	
		
			No EOL
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
| const { chromium } = require('playwright');
 | |
| 
 | |
| // Constants
 | |
| const STAGING_URL = 'https://wordpress-974670-5399585.cloudwaysapps.com';
 | |
| const LOGIN_URL = `${STAGING_URL}/community-login/`;
 | |
| const DASHBOARD_URL = `${STAGING_URL}/hvac-dashboard/`;
 | |
| const CREATE_EVENT_URL = `${STAGING_URL}/community-events/`;
 | |
| const USERNAME = 'test_trainer';
 | |
| const PASSWORD = 'Test123!';
 | |
| 
 | |
| // Main function to run tests
 | |
| async function runTrainerJourney() {
 | |
|   console.log('Starting trainer journey test...');
 | |
|   
 | |
|   // Launch browser
 | |
|   const browser = await chromium.launch({ headless: false });
 | |
|   const context = await browser.newContext({
 | |
|     viewport: { width: 1280, height: 720 }
 | |
|   });
 | |
|   const page = await context.newPage();
 | |
|   
 | |
|   try {
 | |
|     // STEP 1: Login
 | |
|     console.log('\nSTEP 1: Logging in...');
 | |
|     await loginAsTrainer(page);
 | |
|     
 | |
|     // STEP 2: Verify Dashboard
 | |
|     console.log('\nSTEP 2: Verifying dashboard...');
 | |
|     await verifyDashboard(page);
 | |
|     
 | |
|     // STEP 3: Create Event
 | |
|     console.log('\nSTEP 3: Creating event...');
 | |
|     const eventTitle = await createEvent(page);
 | |
|     
 | |
|     if (eventTitle) {
 | |
|       console.log(`Event created: ${eventTitle}`);
 | |
|       
 | |
|       // STEP 4: Check Event in Dashboard
 | |
|       console.log('\nSTEP 4: Checking event in dashboard...');
 | |
|       await checkEventInDashboard(page, eventTitle);
 | |
|       
 | |
|       // STEP 5: Generate Certificates
 | |
|       console.log('\nSTEP 5: Testing certificate generation...');
 | |
|       await testCertificateGeneration(page, eventTitle);
 | |
|       
 | |
|       // STEP 6: Certificate Reports
 | |
|       console.log('\nSTEP 6: Testing certificate reports...');
 | |
|       await testCertificateReports(page, eventTitle);
 | |
|     }
 | |
|     
 | |
|     console.log('\nTrainer journey test completed successfully!');
 | |
|   } catch (error) {
 | |
|     console.error(`Test failed: ${error.message}`);
 | |
|     
 | |
|     // Take a screenshot on failure
 | |
|     await page.screenshot({ path: `trainer-journey-error-${Date.now()}.png` });
 | |
|     
 | |
|     throw error;
 | |
|   } finally {
 | |
|     // Close browser
 | |
|     await browser.close();
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Login as trainer
 | |
| async function loginAsTrainer(page) {
 | |
|   await page.goto(LOGIN_URL);
 | |
|   await page.fill('#user_login', USERNAME);
 | |
|   await page.fill('#user_pass', PASSWORD);
 | |
|   await page.click('#wp-submit');
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Verify login successful
 | |
|   if (!page.url().includes('hvac-dashboard')) {
 | |
|     throw new Error('Login failed');
 | |
|   }
 | |
|   console.log('Login successful');
 | |
| }
 | |
| 
 | |
| // Verify dashboard elements
 | |
| async function verifyDashboard(page) {
 | |
|   await page.goto(DASHBOARD_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Check page title
 | |
|   const title = await page.title();
 | |
|   console.log(`Dashboard title: ${title}`);
 | |
|   
 | |
|   // Check for dashboard components
 | |
|   const statsSection = page.locator('.hvac-dashboard-stats');
 | |
|   if (await statsSection.isVisible()) {
 | |
|     console.log('Dashboard stats section found');
 | |
|   } else {
 | |
|     console.log('Dashboard stats section not found');
 | |
|   }
 | |
|   
 | |
|   // Check for event table
 | |
|   const eventsTable = page.locator('table');
 | |
|   if (await eventsTable.isVisible()) {
 | |
|     console.log('Events table found');
 | |
|     
 | |
|     // Get event count
 | |
|     const eventRows = page.locator('table tbody tr');
 | |
|     const eventCount = await eventRows.count();
 | |
|     console.log(`Found ${eventCount} events in dashboard`);
 | |
|   } else {
 | |
|     console.log('Events table not found');
 | |
|   }
 | |
|   
 | |
|   // Check for action buttons
 | |
|   const createEventLink = page.locator('a:has-text("Create Event")');
 | |
|   if (await createEventLink.isVisible()) {
 | |
|     console.log('Create Event link found');
 | |
|   } else {
 | |
|     console.log('Create Event link not found');
 | |
|   }
 | |
|   
 | |
|   console.log('Dashboard verification completed!');
 | |
| }
 | |
| 
 | |
| // Create a new event
 | |
| async function createEvent(page) {
 | |
|   // Generate unique event title with timestamp
 | |
|   const timestamp = Date.now();
 | |
|   const eventTitle = `Test Event ${timestamp}`;
 | |
|   
 | |
|   // Navigate to create event page
 | |
|   await page.goto(CREATE_EVENT_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Fill in event details
 | |
|   console.log('Filling event form...');
 | |
|   
 | |
|   // Title - try different selectors
 | |
|   console.log('Filling title field...');
 | |
|   
 | |
|   try {
 | |
|     // Screenshot for debugging
 | |
|     await page.screenshot({ path: `event-form-${Date.now()}.png` });
 | |
|     
 | |
|     const titleField = page.locator('#post_title, input[name="post_title"], .tribe-events-community-details input[name="post_title"]').first();
 | |
|     
 | |
|     if (await titleField.isVisible()) {
 | |
|       await titleField.fill(eventTitle);
 | |
|       console.log('Title field filled');
 | |
|     } else {
 | |
|       console.log('Title field not found');
 | |
|     }
 | |
|   } catch (error) {
 | |
|     console.error(`Error filling title: ${error.message}`);
 | |
|   }
 | |
|   
 | |
|   // Set event date (tomorrow)
 | |
|   const tomorrow = new Date();
 | |
|   tomorrow.setDate(tomorrow.getDate() + 1);
 | |
|   const tomorrowStr = tomorrow.toISOString().split('T')[0]; // Format: YYYY-MM-DD
 | |
|   
 | |
|   // Date fields
 | |
|   await page.fill('input[name="EventStartDate"]', tomorrowStr);
 | |
|   await page.fill('input[name="EventEndDate"]', tomorrowStr);
 | |
|   
 | |
|   // Description - try both TinyMCE and textarea approaches
 | |
|   const tinyMceFrame = page.frameLocator('.mce-edit-area iframe');
 | |
|   const tinyMceVisible = await tinyMceFrame.count() > 0;
 | |
|   
 | |
|   if (tinyMceVisible) {
 | |
|     console.log('Using TinyMCE editor for description');
 | |
|     await tinyMceFrame.locator('body').fill(`This is a test event created on ${new Date().toLocaleString()}`);
 | |
|   } else {
 | |
|     console.log('Using fallback textarea for description');
 | |
|     await page.fill('#post_content', `This is a test event created on ${new Date().toLocaleString()}`);
 | |
|   }
 | |
|   
 | |
|   // Fill venue details
 | |
|   await page.fill('#EventVenueName', 'Test Venue');
 | |
|   await page.fill('#EventVenueAddress', '123 Test Street');
 | |
|   await page.fill('#EventVenueCity', 'Test City');
 | |
|   await page.fill('#EventVenueCountry', 'United States');
 | |
|   await page.fill('#EventVenueZip', '12345');
 | |
|   
 | |
|   // Set up tickets if the tab exists
 | |
|   const ticketsTab = page.locator('text=Tickets');
 | |
|   if (await ticketsTab.isVisible()) {
 | |
|     await ticketsTab.click();
 | |
|     
 | |
|     // Check if we need to add a ticket
 | |
|     const addTicketButton = page.locator('text=Add a new ticket');
 | |
|     if (await addTicketButton.isVisible()) {
 | |
|       await addTicketButton.click();
 | |
|       
 | |
|       // Fill ticket details
 | |
|       await page.fill('.tribe-ticket-field-name input', 'General Admission');
 | |
|       await page.fill('.tribe-ticket-field-price input', '10');
 | |
|       await page.fill('.tribe-ticket-field-capacity input', '100');
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   // Submit form
 | |
|   console.log('Submitting event form...');
 | |
|   await page.click('#community-events-submit');
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Check if we have an edit link, which indicates success
 | |
|   const editLink = page.locator('a:has-text("Edit")');
 | |
|   if (await editLink.isVisible()) {
 | |
|     console.log('Event created successfully!');
 | |
|     return eventTitle;
 | |
|   } else {
 | |
|     console.log('Event creation might have failed, checking for error messages...');
 | |
|     
 | |
|     // Check for error messages
 | |
|     const errorMessage = page.locator('.error, .notice-error');
 | |
|     if (await errorMessage.isVisible()) {
 | |
|       const errorText = await errorMessage.textContent();
 | |
|       console.log(`Error creating event: ${errorText}`);
 | |
|     }
 | |
|     
 | |
|     // Let's assume it worked and continue the test
 | |
|     return eventTitle;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Check if event appears in dashboard
 | |
| async function checkEventInDashboard(page, eventTitle) {
 | |
|   // Go to dashboard
 | |
|   await page.goto(DASHBOARD_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // First check in My Events section if it exists
 | |
|   const myEventsLink = page.locator('a:has-text("My Events")');
 | |
|   if (await myEventsLink.isVisible()) {
 | |
|     await myEventsLink.click();
 | |
|     await page.waitForLoadState('networkidle');
 | |
|     
 | |
|     // Look for our event
 | |
|     const eventLink = page.locator(`a:has-text("${eventTitle}")`);
 | |
|     if (await eventLink.isVisible()) {
 | |
|       console.log(`Event "${eventTitle}" found in My Events!`);
 | |
|       return true;
 | |
|     } else {
 | |
|       console.log(`Event "${eventTitle}" not found in My Events, it may be pending approval`);
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   // As a fallback, check in the main dashboard table
 | |
|   await page.goto(DASHBOARD_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Look for event in the table
 | |
|   const tableRow = page.locator(`tr:has-text("${eventTitle}")`);
 | |
|   if (await tableRow.isVisible()) {
 | |
|     console.log(`Event "${eventTitle}" found in dashboard table!`);
 | |
|     return true;
 | |
|   } else {
 | |
|     console.log(`Event "${eventTitle}" not found in dashboard table, it may be pending approval`);
 | |
|     return false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Test certificate generation
 | |
| async function testCertificateGeneration(page, eventTitle) {
 | |
|   // Navigate to dashboard first
 | |
|   await page.goto(DASHBOARD_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Look for Generate Certificates link
 | |
|   const generateLink = page.locator('a:has-text("Generate Certificates")');
 | |
|   if (await generateLink.isVisible()) {
 | |
|     await generateLink.click();
 | |
|     await page.waitForLoadState('networkidle');
 | |
|     
 | |
|     // Check page title
 | |
|     const title = await page.title();
 | |
|     console.log(`Generate Certificates page title: ${title}`);
 | |
|     
 | |
|     // Check for event dropdown
 | |
|     const eventDropdown = page.locator('#event_id');
 | |
|     if (await eventDropdown.isVisible()) {
 | |
|       console.log('Event dropdown found');
 | |
|       
 | |
|       // Count options
 | |
|       const optionCount = await page.locator('#event_id option').count();
 | |
|       console.log(`Event options: ${optionCount}`);
 | |
|       
 | |
|       // Try to find our event in the dropdown
 | |
|       const eventOption = page.locator(`#event_id option:has-text("${eventTitle}")`);
 | |
|       if (await eventOption.count() > 0) {
 | |
|         console.log(`Found our event "${eventTitle}" in the dropdown!`);
 | |
|         
 | |
|         // Select our event
 | |
|         await eventDropdown.selectOption({ label: new RegExp(eventTitle) });
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Check for attendees
 | |
|         const attendeeList = page.locator('.hvac-attendee-list');
 | |
|         if (await attendeeList.isVisible()) {
 | |
|           const attendeeCount = await page.locator('.hvac-attendee-item').count();
 | |
|           console.log(`Found ${attendeeCount} attendees for the event`);
 | |
|           
 | |
|           // Our new event likely has no attendees yet, so this is expected
 | |
|           if (attendeeCount === 0) {
 | |
|             console.log('No attendees found for the event, skipping certificate generation');
 | |
|           } else {
 | |
|             // Select all attendees
 | |
|             await page.click('button:has-text("Select All")');
 | |
|             
 | |
|             // Generate certificates
 | |
|             await page.click('button[type="submit"]:has-text("Generate Certificates")');
 | |
|             await page.waitForLoadState('networkidle');
 | |
|             
 | |
|             // Check for success message
 | |
|             const successMessage = page.locator('.hvac-success-message');
 | |
|             if (await successMessage.isVisible()) {
 | |
|               console.log('Certificates generated successfully!');
 | |
|             } else {
 | |
|               console.log('Certificate generation may have failed');
 | |
|             }
 | |
|           }
 | |
|         } else {
 | |
|           console.log('No attendee list found');
 | |
|         }
 | |
|       } else {
 | |
|         console.log(`Our event "${eventTitle}" not found in dropdown, it may be pending approval`);
 | |
|         
 | |
|         // Try the first event in the list
 | |
|         await eventDropdown.selectOption({ index: 1 });
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Get the selected event name
 | |
|         const selectedEventName = await page.locator('#event_id option:checked').textContent();
 | |
|         console.log(`Selected existing event: ${selectedEventName}`);
 | |
|         
 | |
|         // Check for attendees
 | |
|         const attendeeCount = await page.locator('.hvac-attendee-item').count();
 | |
|         console.log(`Found ${attendeeCount} attendees for the event`);
 | |
|         
 | |
|         if (attendeeCount > 0) {
 | |
|           // Select all attendees
 | |
|           await page.click('button:has-text("Select All")');
 | |
|           
 | |
|           // Generate certificates
 | |
|           await page.click('button[type="submit"]:has-text("Generate Certificates")');
 | |
|           await page.waitForLoadState('networkidle');
 | |
|           
 | |
|           // Check for success message
 | |
|           const successMessage = page.locator('.hvac-success-message');
 | |
|           if (await successMessage.isVisible()) {
 | |
|             console.log('Certificates generated successfully!');
 | |
|           } else {
 | |
|             console.log('Certificate generation may have failed');
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } else {
 | |
|       console.log('Event dropdown not found');
 | |
|     }
 | |
|     
 | |
|     console.log('Certificate generation test completed!');
 | |
|     return true;
 | |
|   } else {
 | |
|     console.log('Generate Certificates link not found, skipping test');
 | |
|     return false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Test certificate reports
 | |
| async function testCertificateReports(page, eventTitle) {
 | |
|   // Navigate to dashboard first
 | |
|   await page.goto(DASHBOARD_URL);
 | |
|   await page.waitForLoadState('networkidle');
 | |
|   
 | |
|   // Look for Certificate Reports link
 | |
|   const reportsLink = page.locator('a:has-text("Certificate Reports")');
 | |
|   if (await reportsLink.isVisible()) {
 | |
|     await reportsLink.click();
 | |
|     await page.waitForLoadState('networkidle');
 | |
|     
 | |
|     // Check page title
 | |
|     const title = await page.title();
 | |
|     console.log(`Certificate Reports page title: ${title}`);
 | |
|     
 | |
|     // Check for filter form
 | |
|     const filterForm = page.locator('form.hvac-certificate-filters');
 | |
|     if (await filterForm.isVisible()) {
 | |
|       console.log('Certificate filter form found');
 | |
|       
 | |
|       // Check if event filter exists
 | |
|       const eventFilter = page.locator('#filter_event');
 | |
|       if (await eventFilter.isVisible()) {
 | |
|         console.log('Event filter found');
 | |
|         
 | |
|         // Try to find our event in the dropdown
 | |
|         const eventOption = page.locator(`#filter_event option:has-text("${eventTitle}")`);
 | |
|         if (await eventOption.count() > 0) {
 | |
|           console.log(`Found our event "${eventTitle}" in the filter dropdown!`);
 | |
|           
 | |
|           // Select our event
 | |
|           await eventFilter.selectOption({ label: new RegExp(eventTitle) });
 | |
|         } else {
 | |
|           console.log(`Our event "${eventTitle}" not found in filter, using another existing event`);
 | |
|           
 | |
|           // Use the first event in the list if available
 | |
|           const optionCount = await page.locator('#filter_event option').count();
 | |
|           if (optionCount > 1) {
 | |
|             await eventFilter.selectOption({ index: 1 });
 | |
|           }
 | |
|         }
 | |
|         
 | |
|         // Apply filter
 | |
|         await page.click('button[type="submit"]');
 | |
|         await page.waitForLoadState('networkidle');
 | |
|         
 | |
|         // Check for certificates
 | |
|         const certificateCount = await page.locator('.hvac-certificate-item').count();
 | |
|         console.log(`Found ${certificateCount} certificates after filtering`);
 | |
|         
 | |
|         // Test attendee search if available
 | |
|         const attendeeSearch = page.locator('#search_attendee');
 | |
|         if (await attendeeSearch.isVisible()) {
 | |
|           console.log('Testing attendee search...');
 | |
|           
 | |
|           // Try a search term
 | |
|           await attendeeSearch.fill('test');
 | |
|           await page.click('button[type="submit"]');
 | |
|           await page.waitForLoadState('networkidle');
 | |
|           
 | |
|           // Check results
 | |
|           const searchResultCount = await page.locator('.hvac-certificate-item').count();
 | |
|           console.log(`Found ${searchResultCount} certificates for attendee search "test"`);
 | |
|           
 | |
|           // Reset filters
 | |
|           const resetButton = page.locator('button[type="reset"]');
 | |
|           if (await resetButton.isVisible()) {
 | |
|             await resetButton.click();
 | |
|             await page.waitForLoadState('networkidle');
 | |
|             console.log('Filters reset');
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     } else {
 | |
|       console.log('Certificate filter form not found');
 | |
|     }
 | |
|     
 | |
|     console.log('Certificate reports test completed!');
 | |
|     return true;
 | |
|   } else {
 | |
|     console.log('Certificate Reports link not found, skipping test');
 | |
|     return false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Run the tests
 | |
| runTrainerJourney().catch(error => {
 | |
|   console.error(`Error running trainer journey: ${error.message}`);
 | |
|   process.exit(1);
 | |
| }); |