upskill-event-manager/wordpress-dev/tests/e2e/trainer-journey-updated.test.ts

353 lines
No EOL
15 KiB
TypeScript

import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config';
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { DashboardPage } from './pages/DashboardPage';
import { CreateEventPage } from './pages/CreateEventPage';
import { EventSummaryPage } from './pages/EventSummaryPage';
import { ModifyEventPage } from './pages/ModifyEventPage';
import { TEST_USERS } from './data/test-users';
import { TEST_EVENTS } from './data/test-events';
// STAGING_URL is now imported from config
test.describe('Trainer User Journey - Updated', () => {
let loginPage: LoginPage;
let dashboardPage: DashboardPage;
let createEventPage: CreateEventPage;
let eventSummaryPage: EventSummaryPage;
let modifyEventPage: ModifyEventPage;
const trainer = TEST_USERS.trainer;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
dashboardPage = new DashboardPage(page);
createEventPage = new CreateEventPage(page);
eventSummaryPage = new EventSummaryPage(page);
modifyEventPage = new ModifyEventPage(page);
// Set base URL
page.context().setDefaultNavigationTimeout(TIMEOUTS.navigation);
await page.goto(STAGING_URL);
});
test('Step 1 & 2: Trainer Login', async ({ page }) => {
// Navigate to login page
await loginPage.navigateToLogin();
await expect(page).toHaveURL(/.*community-login/);
// Verify login form is visible
expect(await loginPage.isLoginFormVisible()).toBe(true);
// Login with test trainer credentials
await loginPage.login(trainer.username, trainer.password);
// Verify successful login and redirect to dashboard
await expect(page).toHaveURL(/.*hvac-dashboard/);
await page.screenshot({ path: 'test-results/screenshots/login-success.png' });
});
test('Step 3: Access Dashboard', async ({ page }) => {
// Login first
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
// Wait for dashboard to load
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(/hvac-dashboard/);
// Verify dashboard elements are visible
expect(await dashboardPage.isEventsTableVisible()).toBe(true);
// Get and verify statistics
const stats = await dashboardPage.getStatistics();
expect(stats.totalEvents).toBeDefined();
expect(stats.upcomingEvents).toBeDefined();
expect(stats.pastEvents).toBeDefined();
expect(stats.revenue).toBeDefined();
await page.screenshot({ path: 'test-results/screenshots/dashboard-view.png' });
});
test('Step 4a: Create Event', async ({ page }) => {
// Login and navigate to dashboard
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
// Click create event button
await dashboardPage.clickCreateEvent();
await expect(page).toHaveURL(/.*manage-event/);
// Fill event details
const eventData = TEST_EVENTS.basicEvent;
await createEventPage.fillEventDetails(eventData);
// Submit event
await createEventPage.submitEvent();
// Wait for the page to update after submission
await page.waitForTimeout(3000);
// Verify submission - we remain on the manage-event page but with different content
await expect(page).toHaveURL(/manage-event/);
// Check for success indicator - the button is all caps
const viewYourEventsButtonVisible = await page.locator('text="VIEW YOUR SUBMITTED EVENTS"').isVisible().catch(() => false);
console.log('View Your Events Button Visible:', viewYourEventsButtonVisible);
// Alternative check - the form updated, showing the event title is filled
const titleFilled = await page.locator('input[name="post_title"]').inputValue();
console.log('Title field value:', titleFilled);
expect(viewYourEventsButtonVisible).toBeTruthy();
await page.screenshot({ path: 'test-results/screenshots/event-created.png' });
});
test('Step 4b: Manage Events - View Event List', async ({ page }) => {
// Login
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
// Navigate to My Events instead of dashboard
await page.goto(`${STAGING_URL}/my-events/`);
await page.waitForLoadState('networkidle');
// Check upcoming events
const upcomingMessage = await page.locator('text="You have no upcoming events"').isVisible();
// Check past events
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
// Look for events in the past events tab
const eventRows = page.locator('tr.community-events-event-row');
const rowCount = await eventRows.count();
if (rowCount > 0) {
const firstRow = eventRows.first();
const title = await firstRow.locator('a.url').innerText();
console.log('Found past event:', title);
await page.screenshot({ path: 'test-results/screenshots/past-events-list.png' });
}
// Verify filter tabs are present
const filterTabs = ['UPCOMING EVENTS', 'PAST EVENTS'];
for (const filter of filterTabs) {
const filterVisible = await page.locator(`a:has-text("${filter}")`).isVisible();
expect(filterVisible).toBe(true);
}
});
test('Step 4c: Manage Events - Modify Event from Past Events', async ({ page }) => {
// Login and navigate to My Events
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
await page.goto(`${STAGING_URL}/my-events/`);
// Go to past events tab
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
// Get the first past event
const eventRows = page.locator('tr.community-events-event-row');
const rowCount = await eventRows.count();
if (rowCount > 0) {
// Click the Edit link in the first row
const firstRow = eventRows.first();
const editLink = firstRow.locator('a:has-text("Edit")');
if (await editLink.count() > 0) {
await editLink.click();
await page.waitForLoadState('networkidle');
const modifyUrl = page.url();
console.log('Modify page URL:', modifyUrl);
await page.screenshot({ path: 'test-results/screenshots/modify-event-page.png' });
// Modify event details
const updatedEvent = {
...TEST_EVENTS.basicEvent,
title: 'Updated Event Title',
description: 'This event has been modified for testing.'
};
// Clear existing fields and fill new values
await page.fill('input[name="post_title"]', updatedEvent.title);
// Update description in TinyMCE
try {
const frame = page.frameLocator('iframe[id$="_ifr"]');
await frame.locator('body').fill(updatedEvent.description);
} catch (e) {
// Fallback to textarea
await page.fill('textarea[name="post_content"]', updatedEvent.description);
}
// Look for update button
const updateButtonVisible = await page.locator('input[name="community-event"][value="Update"]').isVisible();
if (updateButtonVisible) {
await page.click('input[name="community-event"][value="Update"]');
} else {
await page.click('input[name="community-event"][value="Submit Event"]');
}
await page.waitForLoadState('networkidle');
await page.screenshot({ path: 'test-results/screenshots/event-updated.png' });
// Verify update by going back to My Events
await page.goto(`${STAGING_URL}/my-events/`);
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
const updatedTitle = await eventRows.first().locator('a.url').innerText();
console.log('Updated event title:', updatedTitle);
}
}
});
test('Step 4d: Manage Events - Delete Event', async ({ page }) => {
// Login and navigate to My Events
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
await page.goto(`${STAGING_URL}/my-events/`);
// Go to past events tab
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
// Get initial event count
const eventRows = page.locator('tr.community-events-event-row');
const initialCount = await eventRows.count();
console.log('Initial event count:', initialCount);
if (initialCount > 0) {
// Click Edit on the first event
const firstRow = eventRows.first();
const editLink = firstRow.locator('a:has-text("Edit")');
if (await editLink.count() > 0) {
await editLink.click();
await page.waitForLoadState('networkidle');
// Look for delete link/button
const deleteLink = page.locator('a:has-text("Delete Event")');
const deleteButton = page.locator('button:has-text("Delete")');
if (await deleteLink.count() > 0) {
await deleteLink.click();
// Handle confirmation if present
const confirmButton = page.locator('button:has-text("Yes, Delete")');
if (await confirmButton.isVisible()) {
await confirmButton.click();
}
} else if (await deleteButton.count() > 0) {
await deleteButton.click();
// Handle confirmation if present
const confirmButton = page.locator('button:has-text("Yes, Delete")');
if (await confirmButton.isVisible()) {
await confirmButton.click();
}
}
await page.waitForLoadState('networkidle');
await page.screenshot({ path: 'test-results/screenshots/event-deleted.png' });
// Go back to My Events to verify deletion
await page.goto(`${STAGING_URL}/my-events/`);
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
const finalCount = await eventRows.count();
console.log('Final event count:', finalCount);
expect(finalCount).toBeLessThanOrEqual(initialCount);
}
}
});
test('Step 5: View Event Details from Past Events', async ({ page }) => {
// Login and navigate to My Events
await loginPage.navigateToLogin();
await loginPage.login(trainer.username, trainer.password);
await page.goto(`${STAGING_URL}/my-events/`);
// Go to past events tab
await page.click('a:has-text("PAST EVENTS")');
await page.waitForLoadState('networkidle');
// Get the first past event
const eventRows = page.locator('tr.community-events-event-row');
const rowCount = await eventRows.count();
if (rowCount > 0) {
// Click on the event title
const firstRow = eventRows.first();
const eventLink = firstRow.locator('a.url');
const eventTitle = await eventLink.innerText();
console.log('Viewing event:', eventTitle);
await eventLink.click();
await page.waitForLoadState('networkidle');
const eventUrl = page.url();
console.log('Event detail URL:', eventUrl);
await page.screenshot({ path: 'test-results/screenshots/event-detail-page.png' });
// Check for event details on the page
const titleElement = page.locator('h1, h2').first();
const titleText = await titleElement.innerText();
expect(titleText).toBeTruthy();
// Look for event metadata
const dateInfo = page.locator('.tribe-events-event-meta');
const hasDateInfo = await dateInfo.count() > 0;
expect(hasDateInfo).toBe(true);
}
});
// Phase 2 and Phase 3 tests remain skipped
test.skip('Step 9: Email Communication (Phase 2)', async ({ page }) => {
// This will be implemented when Phase 2 is deployed
});
test.skip('Step 10: Attendee Check-in', async ({ page }) => {
// This will be implemented when the feature is available
});
test.skip('Step 11: Certificate Generation (Phase 3)', async ({ page }) => {
// This will be implemented when Phase 3 is deployed
});
});
// Error Scenario Tests
test.describe('Trainer Journey - Error Scenarios', () => {
let loginPage: LoginPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await page.goto(STAGING_URL);
});
test('Invalid Login Credentials', async ({ page }) => {
await loginPage.navigateToLogin();
await loginPage.login('invalid_user', 'wrong_password');
// Should remain on login page
await expect(page).toHaveURL(/.*community-login/);
// Error message should be visible
const errorMessage = await loginPage.getErrorMessage();
expect(errorMessage).toContain('Invalid username or password');
});
test('Access Dashboard Without Login', async ({ page }) => {
// Try to access dashboard directly
await page.goto(PATHS.dashboard);
// Should be redirected to login
await expect(page).toHaveURL(/.*community-login/);
});
});