upskill-event-manager/wordpress-dev/tests/e2e/dashboard.spec.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

327 lines
No EOL
15 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { DashboardPage } from './pages/DashboardPage';
import { LoginPage } from './pages/LoginPage';
interface EventItem {
date: string;
revenue: number;
// Add other properties as needed
}
test.describe('Dashboard Tests', () => {
let dashboardPage: DashboardPage;
let loginPage: LoginPage;
test('should successfully login and verify dashboard elements', async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
// Login with staging credentials
await loginPage.navigate();
console.log('Attempting login with credentials: test_trainer/Test123!');
await loginPage.login('test_trainer', 'Test123!');
console.log('Login completed, checking for dashboard elements...');
// Verify dashboard elements
await dashboardPage.navigate();
await expect(page).toHaveURL(/dashboard/);
await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible();
});
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
// Login before each test using staging credentials
await loginPage.navigate();
console.log('Attempting login with credentials: test_trainer/Test123!');
await loginPage.login('test_trainer', 'Test123!');
console.log('Login completed, checking for dashboard elements...');
await dashboardPage.navigate();
});
test.describe('Statistics Summary Tests', () => {
test('Total events count matches mocked API data', async ({ page }) => {
// Mock API response for testing
await page.route('**/api/events/count', route => route.fulfill({
status: 200,
body: JSON.stringify({ total: 42 })
}));
await page.reload();
await expect(dashboardPage.totalEventsCount).toHaveText('42');
});
test('Upcoming events count is accurate', async ({ page }) => {
await page.route('**/api/events/upcoming', route => route.fulfill({
status: 200,
body: JSON.stringify({ upcoming: 15 })
}));
await page.reload();
await expect(dashboardPage.upcomingEventsCount).toHaveText('15');
});
test('Past events count is accurate', async ({ page }) => {
await page.route('**/api/events/past', route => route.fulfill({
status: 200,
body: JSON.stringify({ past: 27 })
}));
await page.reload();
await expect(dashboardPage.pastEventsCount).toHaveText('27');
});
test('Revenue calculations match expected values', async ({ page }) => {
await page.route('**/api/revenue', route => route.fulfill({
status: 200,
body: JSON.stringify({
total: 12500,
target: 100000,
percentage: 12.5
})
}));
await page.reload();
await expect(dashboardPage.totalRevenue).toHaveText('$12,500');
await expect(dashboardPage.revenueProgress).toHaveAttribute('aria-valuenow', '12.5');
});
});
test.describe('Events Table Tests', () => {
test('Displays correct status icons', async ({ page }) => {
// Mock API response with test events
await page.route('**/api/events', route => route.fulfill({
status: 200,
body: JSON.stringify([{
id: 1,
name: 'Test Event',
status: 'draft',
date: '2025-12-31',
organizer: 'Test Organizer',
capacity: 100,
ticketsSold: 50,
revenue: 2500
}])
}));
await page.reload();
await expect(dashboardPage.getStatusIcon('draft')).toBeVisible();
});
test('Event links open in new tab', async ({ page }) => {
await page.route('**/api/events', route => route.fulfill({
status: 200,
body: JSON.stringify([{
id: 1,
name: 'Test Event',
status: 'published',
date: '2025-12-31',
organizer: 'Test Organizer',
capacity: 100,
ticketsSold: 50,
revenue: 2500
}])
}));
await page.reload();
const eventLink = dashboardPage.getEventLink('Test Event');
await expect(eventLink).toHaveAttribute('target', '_blank');
});
test('Highlights events within 7 days', async ({ page }) => {
const nextWeek = new Date();
nextWeek.setDate(nextWeek.getDate() + 3);
const dateString = nextWeek.toISOString().split('T')[0];
await page.route('**/api/events', route => route.fulfill({
status: 200,
body: JSON.stringify([{
id: 1,
name: 'Upcoming Event',
status: 'published',
date: dateString,
organizer: 'Test Organizer',
capacity: 100,
ticketsSold: 50,
revenue: 2500
}])
}));
await page.reload();
await expect(dashboardPage.getEventRow('Upcoming Event')).toHaveClass(/highlighted/);
});
});
test.describe('Navigation Tests', () => {
test('Create Event button opens event creation page with correct permissions', async ({ page }) => {
await dashboardPage.clickCreateEvent();
await expect(page).toHaveURL(/.*create-event/);
await expect(page.locator('h1:has-text("Create New Event")')).toBeVisible();
await expect(page.locator('text=You have permission to create events')).toBeVisible();
});
test('View Trainer Profile button opens profile page with correct content', async ({ page }) => {
await dashboardPage.clickViewTrainerProfile();
await expect(page).toHaveURL(/.*trainer-profile/);
await expect(page.locator('h1:has-text("Trainer Profile")')).toBeVisible();
await expect(page.locator('text=Certifications')).toBeVisible();
});
test('Logout button returns to login page and clears session', async ({ page }) => {
await dashboardPage.clickLogout();
await expect(page).toHaveURL(/.*wp-login.php/);
await expect(page.locator('text=You have been logged out')).toBeVisible();
});
test('Navigation buttons are disabled for unauthorized users', async ({ page }) => {
// Test setup for unauthorized user
await page.evaluate(() => {
localStorage.setItem('userRole', 'attendee');
});
await page.reload();
await expect(dashboardPage.createEventButton).toBeDisabled();
await expect(dashboardPage.viewTrainerProfileButton).toBeDisabled();
});
});
test.describe('Statistics Summary Tests', () => {
test('Total events count matches live API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
await dashboardPage.verifyTotalEvents(events.total);
});
test('Upcoming events count matches API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events?status=upcoming');
const events = await response.json();
await dashboardPage.verifyUpcomingEvents(events.count);
});
test('Past events count matches API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events?status=past');
const events = await response.json();
await dashboardPage.verifyPastEvents(events.count);
});
test('Total tickets sold matches API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/tickets');
const tickets = await response.json();
await dashboardPage.verifyTotalTickets(tickets.total_sold);
});
test('Total revenue matches API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/revenue');
const revenue = await response.json();
await dashboardPage.verifyTotalRevenue(revenue.total);
});
test('Revenue comparison to annual target is calculated correctly', async ({ request }) => {
const revenueResponse = await request.get('/wp-json/hvac/v1/revenue');
const targetResponse = await request.get('/wp-json/hvac/v1/target');
const revenue = await revenueResponse.json();
const target = await targetResponse.json();
const expectedPercentage = Math.round((revenue.total / target.annual) * 100);
await dashboardPage.verifyRevenueComparison(`${expectedPercentage}% of annual target`);
});
});
test.describe('Events Table Tests', () => {
test('Event status icons display correctly for different statuses', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
for (const [index, event] of events.items.entries()) {
await dashboardPage.verifyEventStatusIcon(index, event.status);
console.log(`Verified status icon for event ${event.id}: ${event.status}`);
}
});
test('Event name links open in new tab with correct URL', async ({ context, request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
const testEvent = events.items[0];
const pagePromise = context.waitForEvent('page');
await dashboardPage.verifyEventNameLink(0, `/event/${testEvent.slug}`);
const newPage = await pagePromise;
await expect(newPage).toHaveURL(new RegExp(testEvent.slug));
console.log(`Verified link opens correctly for event: ${testEvent.name}`);
});
test('Event dates within 7 days are highlighted', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
for (const [index, event] of events.items.entries()) {
const shouldHighlight = new Date(event.date).getTime() - new Date().getTime() < 7 * 24 * 60 * 60 * 1000;
await dashboardPage.verifyEventDateHighlight(index, shouldHighlight);
console.log(`Verified date highlight for event ${event.name}: ${shouldHighlight}`);
}
});
test('Event organizer information matches API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
for (const [index, event] of events.items.entries()) {
await dashboardPage.verifyEventOrganizer(index, event.organizer.name);
console.log(`Verified organizer for event ${event.name}: ${event.organizer.name}`);
}
});
test('Event capacity and ticket statistics match API data', async ({ request }) => {
const response = await request.get('/wp-json/hvac/v1/events');
const events = await response.json();
for (const [index, event] of events.items.entries()) {
await dashboardPage.verifyEventCapacity(index, event.capacity);
await dashboardPage.verifyEventTicketsSold(index, event.tickets_sold);
await dashboardPage.verifyEventRevenue(index, event.revenue);
console.log(`Verified stats for event ${event.name}: ${event.tickets_sold}/${event.capacity} tickets, $${event.revenue}`);
}
});
test('Table sorting functionality works correctly', async ({ request }) => {
// Test date sorting
await dashboardPage.sortBy('Date');
const dateResponse = await request.get('/wp-json/hvac/v1/events?sort=date');
const dateSortedEvents = await dateResponse.json();
await dashboardPage.verifyTableSortOrder('date', dateSortedEvents.items.map((e: EventItem) => e.date));
console.log('Verified date sorting matches API');
// Test revenue sorting
await dashboardPage.sortBy('Revenue');
const revenueResponse = await request.get('/wp-json/hvac/v1/events?sort=revenue');
const revenueSortedEvents = await revenueResponse.json();
await dashboardPage.verifyTableSortOrder('revenue', revenueSortedEvents.items.map((e: EventItem) => e.revenue.toString()));
console.log('Verified revenue sorting matches API');
});
test('Table filtering capabilities work correctly', async ({ request }) => {
// Test upcoming events filter
await dashboardPage.filterBy('upcoming');
const upcomingResponse = await request.get('/wp-json/hvac/v1/events?status=upcoming');
const upcomingEvents = await upcomingResponse.json();
await dashboardPage.verifyFilterResults('upcoming', upcomingEvents.items.length);
console.log(`Verified upcoming filter shows ${upcomingEvents.items.length} events`);
// Test past events filter
await dashboardPage.filterBy('past');
const pastResponse = await request.get('/wp-json/hvac/v1/events?status=past');
const pastEvents = await pastResponse.json();
await dashboardPage.verifyFilterResults('past', pastEvents.items.length);
console.log(`Verified past filter shows ${pastEvents.items.length} events`);
// Test draft status filter
await dashboardPage.filterBy('draft');
const draftResponse = await request.get('/wp-json/hvac/v1/events?status=draft');
const draftEvents = await draftResponse.json();
await dashboardPage.verifyFilterResults('draft', draftEvents.items.length);
console.log(`Verified draft filter shows ${draftEvents.items.length} events`);
});
});
});