- Created Page Object Model structure for all trainer-facing pages - Implemented complete test coverage for trainer journey steps 1-8 - Added centralized test data management with test users and events - Updated run-tests.sh with --trainer-journey option for easy execution - Enhanced documentation with test setup, usage, and troubleshooting guides - Created verification scripts to ensure proper test environment setup - Prepared framework for Phase 2/3 features (email, check-in, certificates) This implementation provides a solid foundation for testing the complete trainer user journey and can be easily extended as new features are deployed.
89 lines
No EOL
3.2 KiB
TypeScript
89 lines
No EOL
3.2 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
import { BasePage } from './BasePage';
|
|
|
|
export class DashboardPage extends BasePage {
|
|
private readonly createEventButton = 'a:has-text("Create Event")';
|
|
private readonly viewProfileButton = 'a:has-text("View Trainer Profile")';
|
|
private readonly logoutButton = 'a:has-text("Logout")';
|
|
private readonly eventsTable = '.events-table';
|
|
private readonly statsSection = '.statistics-summary';
|
|
private readonly totalEventsCount = '.total-events-count';
|
|
private readonly upcomingEventsCount = '.upcoming-events-count';
|
|
private readonly pastEventsCount = '.past-events-count';
|
|
private readonly totalTicketsSold = '.total-tickets-sold';
|
|
private readonly totalRevenue = '.total-revenue';
|
|
|
|
constructor(page: Page) {
|
|
super(page);
|
|
}
|
|
|
|
async navigateToDashboard(): Promise<void> {
|
|
await this.navigate('/hvac-dashboard/');
|
|
}
|
|
|
|
async clickCreateEvent(): Promise<void> {
|
|
await this.click(this.createEventButton);
|
|
await this.waitForNavigation();
|
|
}
|
|
|
|
async clickViewProfile(): Promise<void> {
|
|
await this.click(this.viewProfileButton);
|
|
await this.waitForNavigation();
|
|
}
|
|
|
|
async logout(): Promise<void> {
|
|
await this.click(this.logoutButton);
|
|
await this.waitForNavigation();
|
|
}
|
|
|
|
async getStatistics(): Promise<{
|
|
totalEvents: string;
|
|
upcomingEvents: string;
|
|
pastEvents: string;
|
|
ticketsSold: string;
|
|
revenue: string;
|
|
}> {
|
|
return {
|
|
totalEvents: await this.getText(this.totalEventsCount),
|
|
upcomingEvents: await this.getText(this.upcomingEventsCount),
|
|
pastEvents: await this.getText(this.pastEventsCount),
|
|
ticketsSold: await this.getText(this.totalTicketsSold),
|
|
revenue: await this.getText(this.totalRevenue)
|
|
};
|
|
}
|
|
|
|
async isEventsTableVisible(): Promise<boolean> {
|
|
return await this.isVisible(this.eventsTable);
|
|
}
|
|
|
|
async getEventRowData(index: number): Promise<{
|
|
status: string;
|
|
name: string;
|
|
date: string;
|
|
organizer: string;
|
|
capacity: string;
|
|
soldTickets: string;
|
|
revenue: string;
|
|
}> {
|
|
const row = await this.page.locator(`${this.eventsTable} tbody tr`).nth(index);
|
|
|
|
return {
|
|
status: await row.locator('td:nth-child(1)').textContent() || '',
|
|
name: await row.locator('td:nth-child(2)').textContent() || '',
|
|
date: await row.locator('td:nth-child(3)').textContent() || '',
|
|
organizer: await row.locator('td:nth-child(4)').textContent() || '',
|
|
capacity: await row.locator('td:nth-child(5)').textContent() || '',
|
|
soldTickets: await row.locator('td:nth-child(6)').textContent() || '',
|
|
revenue: await row.locator('td:nth-child(7)').textContent() || ''
|
|
};
|
|
}
|
|
|
|
async getEventCount(): Promise<number> {
|
|
return await this.page.locator(`${this.eventsTable} tbody tr`).count();
|
|
}
|
|
|
|
async clickEventName(eventName: string): Promise<void> {
|
|
await this.page.click(`${this.eventsTable} a:has-text("${eventName}")`);
|
|
await this.waitForNavigation();
|
|
}
|
|
} |