upskill-event-manager/wordpress-dev/tests/e2e/pages/DashboardPage.ts
bengizmo d6211ee364 feat(testing): Implement HVAC_Test_User_Factory and update .gitignore
- Add HVAC_Test_User_Factory class with:
  * User creation with specific roles
  * Multiple role support
  * Persona management system
  * Account cleanup integration
- Create comprehensive test suite in HVAC_Test_User_Factory_Test.php
- Update testing improvement plan documentation
- Add implementation decisions to project memory bank
- Restructure .gitignore with:
  * Whitelist approach for better file management
  * Explicit backup exclusions
  * Specific bin directory inclusions

Part of the Account Management component from the testing framework improvement plan.
2025-04-14 17:41:36 -03:00

217 lines
No EOL
7.9 KiB
TypeScript

import { Page, expect } from '@playwright/test';
import { LogParser } from '../utils/logParser';
export class DashboardPage {
readonly page: Page;
private readonly selectors = {
// Navigation buttons
createEventButton: '#create-event-btn',
viewTrainerProfileButton: '#view-trainer-profile-btn',
logoutButton: '#logout-btn',
// Statistics summary
totalEvents: '#total-events',
upcomingEvents: '#upcoming-events',
pastEvents: '#past-events',
totalTickets: '#total-tickets',
totalRevenue: '#total-revenue',
revenueTargetComparison: '#revenue-comparison',
// Events table
eventsTable: '#events-table',
eventStatusIcon: '.event-status-icon',
eventNameLink: '.event-name-link',
eventDateCell: '.event-date',
eventOrganizer: '.event-organizer',
eventCapacity: '.event-capacity',
eventTicketsSold: '.event-tickets-sold',
eventRevenue: '.event-revenue',
sortButton: '.sort-button',
filterDropdown: '#event-filter'
};
constructor(page: Page) {
this.page = page;
}
async navigate() {
await this.page.goto('/hvac-dashboard/');
await this.page.waitForLoadState('networkidle');
}
// Navigation button methods
async clickCreateEvent() {
await this.page.click(this.selectors.createEventButton);
}
async clickViewTrainerProfile() {
await this.page.click(this.selectors.viewTrainerProfileButton);
}
async clickLogout() {
await this.page.click(this.selectors.logoutButton);
}
// Statistics verification methods
async verifyTotalEvents(expectedCount: number) {
const count = await this.page.textContent(this.selectors.totalEvents);
expect(Number(count)).toBe(expectedCount);
}
async verifyUpcomingEvents(expectedCount: number) {
const count = await this.page.textContent(this.selectors.upcomingEvents);
expect(Number(count)).toBe(expectedCount);
}
async verifyPastEvents(expectedCount: number) {
const count = await this.page.textContent(this.selectors.pastEvents);
expect(Number(count)).toBe(expectedCount);
}
async verifyTotalTickets(expectedCount: number) {
const count = await this.page.textContent(this.selectors.totalTickets);
expect(Number(count)).toBe(expectedCount);
}
async verifyTotalRevenue(expectedAmount: number) {
const amount = await this.page.textContent(this.selectors.totalRevenue);
expect(amount).not.toBeNull();
const parsedAmount = amount ? parseFloat(amount.replace(/[^0-9.]/g, '')) : 0;
expect(parsedAmount).toBe(expectedAmount);
// Verify proper currency formatting
expect(amount).toMatch(/^\$\d{1,3}(,\d{3})*(\.\d{2})?$/);
}
async verifyRevenueComparison(expectedText: string) {
const comparison = await this.page.textContent(this.selectors.revenueTargetComparison);
expect(comparison).toContain(expectedText);
}
// Navigation button selectors
get createEventButton() {
return this.page.locator('button:has-text("Create Event")');
}
get viewTrainerProfileButton() {
return this.page.locator('button:has-text("View Trainer Profile")');
}
// Statistics selectors
get totalEventsCount() {
return this.page.locator('[data-testid="total-events-count"]');
}
get upcomingEventsCount() {
return this.page.locator('[data-testid="upcoming-events-count"]');
}
get pastEventsCount() {
return this.page.locator('[data-testid="past-events-count"]');
}
get totalRevenue() {
return this.page.locator('[data-testid="total-revenue"]');
}
get revenueProgress() {
return this.page.locator('[data-testid="revenue-progress"]');
}
// Events table methods
getStatusIcon(status: string) {
return this.page.locator(`[data-testid="status-icon-${status}"]`);
}
getEventLink(eventName: string) {
return this.page.locator(`[data-testid="event-link"]:has-text("${eventName}")`);
}
getEventRow(eventName: string) {
return this.page.locator(`[data-testid="event-row"]:has-text("${eventName}")`);
}
async verifyEventStatusIcon(eventRow: number, expectedStatus: string) {
const statusIcon = await this.page.locator(this.selectors.eventStatusIcon).nth(eventRow);
const classList = await statusIcon.getAttribute('class');
expect(classList).toContain(`status-${expectedStatus.toLowerCase()}`);
// Verify tooltip content
const tooltip = await statusIcon.getAttribute('title');
expect(tooltip).toContain(expectedStatus);
}
async verifyEventNameLink(eventRow: number, expectedUrl: string) {
const link = await this.page.locator(this.selectors.eventNameLink).nth(eventRow);
const href = await link.getAttribute('href');
expect(href).toBe(expectedUrl);
}
async verifyEventDateHighlight(eventRow: number, shouldBeHighlighted: boolean) {
const dateCell = await this.page.locator(this.selectors.eventDateCell).nth(eventRow);
const classList = await dateCell.getAttribute('class');
if (shouldBeHighlighted) {
expect(classList).toContain('highlighted');
} else {
expect(classList).not.toContain('highlighted');
}
}
async sortBy(columnName: string) {
await this.page.locator(this.selectors.sortButton, { hasText: columnName }).click();
}
async filterBy(filterOption: string) {
await this.page.selectOption(this.selectors.filterDropdown, filterOption);
}
async verifyEventOrganizer(eventRow: number, expectedOrganizer: string) {
const organizer = await this.page.locator(this.selectors.eventOrganizer).nth(eventRow).textContent();
expect(organizer).toBe(expectedOrganizer);
}
async verifyEventCapacity(eventRow: number, expectedCapacity: number) {
const capacity = await this.page.locator(this.selectors.eventCapacity).nth(eventRow).textContent();
expect(Number(capacity)).toBe(expectedCapacity);
}
async verifyEventTicketsSold(eventRow: number, expectedSold: number) {
const sold = await this.page.locator(this.selectors.eventTicketsSold).nth(eventRow).textContent();
expect(Number(sold)).toBe(expectedSold);
}
async verifyEventRevenue(eventRow: number, expectedRevenue: number) {
const revenue = await this.page.locator(this.selectors.eventRevenue).nth(eventRow).textContent();
expect(revenue).not.toBeNull();
const parsedRevenue = revenue ? parseFloat(revenue.replace(/[^0-9.]/g, '')) : 0;
expect(parsedRevenue).toBe(expectedRevenue);
}
async verifyTableSortOrder(columnName: string, expectedOrder: string[]) {
const column = columnName.toLowerCase();
const selector = column === 'date' ? this.selectors.eventDateCell :
column === 'revenue' ? this.selectors.eventRevenue :
this.selectors.eventNameLink;
const elements = await this.page.locator(selector).all();
const actualValues = await Promise.all(elements.map(async el => await el.textContent()));
expect(actualValues).toEqual(expectedOrder);
}
async verifyFilterResults(filterType: string, expectedCount?: number) {
const statuses = await this.page.locator(this.selectors.eventStatusIcon).all();
for (const status of statuses) {
const classList = await status.getAttribute('class');
expect(classList).toContain(`status-${filterType}`);
}
if (expectedCount !== undefined) {
const actualCount = await this.getTableRowCount();
expect(actualCount).toBe(expectedCount);
}
}
async getTableRowCount(): Promise<number> {
return this.page.locator('.events-table tbody tr').count();
}
}