- 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.
327 lines
No EOL
15 KiB
TypeScript
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`);
|
|
});
|
|
});
|
|
}); |