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`); }); }); });