test: Add standalone trainer journey test script
- 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
This commit is contained in:
parent
826555b326
commit
b9fb3b43f4
1 changed files with 456 additions and 0 deletions
456
wordpress-dev/bin/trainer-journey-test.js
Executable file
456
wordpress-dev/bin/trainer-journey-test.js
Executable file
|
|
@ -0,0 +1,456 @@
|
||||||
|
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);
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue