upskill-event-manager/wordpress-dev/tests/e2e/utils/CertificateTestData.ts
bengizmo fbc2d818c0 feat: Add comprehensive certificate E2E tests
- Created CertificatePage class for testing certificate functionality
- Updated DashboardPage to support certificate links in navigation
- Implemented test data generator for certificate testing
- Added tests for certificate generation with checked-in users
- Added tests for certificate generation with non-checked-in users
- Added certificate management (view/email/revoke) tests
- Created comprehensive trainer journey test including certificates
- Added utility script to run certificate-specific tests

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-20 20:44:42 -03:00

181 lines
No EOL
7.3 KiB
TypeScript

import { Page } from '@playwright/test';
import { VerbosityController } from './VerbosityController';
/**
* Utility class to set up test data for certificate testing
* This helps ensure we have events with both checked-in and non-checked-in attendees
*/
export class CertificateTestData {
private page: Page;
private verbosity: VerbosityController;
private readonly STAGING_URL = 'https://wordpress-974670-5399585.cloudwaysapps.com';
constructor(page: Page) {
this.page = page;
this.verbosity = VerbosityController.getInstance();
}
/**
* Login as the test trainer
*/
async loginAsTrainer(): Promise<void> {
this.verbosity.log('Logging in as test_trainer');
await this.page.goto(`${this.STAGING_URL}/community-login/`);
await this.page.fill('#user_login', 'test_trainer');
await this.page.fill('#user_pass', 'Test123!');
await this.page.click('#wp-submit');
await this.page.waitForLoadState('networkidle');
}
/**
* Creates a test event with a specified name and future date
*/
async createTestEvent(eventName: string): Promise<string | null> {
this.verbosity.log(`Creating test event: ${eventName}`);
await this.page.goto(`${this.STAGING_URL}/manage-event/`);
await this.page.waitForLoadState('networkidle');
// Fill in event details
await this.page.fill('#post_title, input[name="post_title"]', eventName);
// Add description
const newEventFrame = this.page.frameLocator('iframe[id*="_ifr"]');
const newEventBody = newEventFrame.locator('body');
await newEventBody.fill(`This is a test event created for certificate testing: ${eventName}`);
// Set dates (30 days from now)
const futureDate = new Date();
futureDate.setDate(futureDate.getDate() + 30);
const dateString = `${(futureDate.getMonth() + 1).toString().padStart(2, '0')}/${futureDate.getDate().toString().padStart(2, '0')}/${futureDate.getFullYear()}`;
await this.page.fill('input[name="EventStartDate"]', dateString);
await this.page.fill('input[name="EventStartTime"]', '10:00 AM');
await this.page.fill('input[name="EventEndDate"]', dateString);
await this.page.fill('input[name="EventEndTime"]', '04:00 PM');
// Add a ticket for $100
await this.addTicket('Certificate Test Ticket', '100');
// Submit the event
const submitButton = this.page.locator('input[value="Submit Event"], button:has-text("Submit Event")');
await submitButton.click();
await this.page.waitForLoadState('networkidle');
// Get the event ID from the URL if possible
const url = this.page.url();
const match = url.match(/post=(\d+)/);
if (match && match[1]) {
return match[1];
}
return null;
}
/**
* Adds a ticket to an event
*/
private async addTicket(ticketName: string, price: string): Promise<void> {
// Look for ticket creation UI elements
const ticketNameField = this.page.locator('#tribe-tickets-editor-tickets-name');
const ticketPriceField = this.page.locator('#tribe-tickets-editor-tickets-price');
const addTicketButton = this.page.locator('button:has-text("Add Ticket")');
// If the ticket UI isn't visible, try to open it
if (!await ticketNameField.isVisible()) {
const addTicketsSection = this.page.locator('a:has-text("Add Tickets")');
if (await addTicketsSection.isVisible()) {
await addTicketsSection.click();
await this.page.waitForTimeout(1000);
}
}
// Fill in ticket details
if (await ticketNameField.isVisible()) {
await ticketNameField.fill(ticketName);
await ticketPriceField.fill(price);
await addTicketButton.click();
await this.page.waitForTimeout(2000);
} else {
this.verbosity.log('Warning: Ticket creation UI not found');
}
}
/**
* Simulates attendee registrations for an event
* Creates a mix of checked-in and non-checked-in attendees
*/
async createTestAttendees(eventId: string, count: number = 5): Promise<void> {
this.verbosity.log(`Creating ${count} test attendees for event ${eventId}`);
// First, navigate to the admin area to access the event
await this.page.goto(`${this.STAGING_URL}/wp-admin/post.php?post=${eventId}&action=edit`);
// Check if we're on the login page and log in if needed
if (this.page.url().includes('wp-login.php')) {
await this.page.fill('#user_login', 'test_trainer');
await this.page.fill('#user_pass', 'Test123!');
await this.page.click('#wp-submit');
await this.page.waitForLoadState('networkidle');
}
// Navigate to the attendees tab - this is implementation-specific and may need adjustment
const attendeesTab = this.page.locator('a:has-text("Attendees")');
if (await attendeesTab.isVisible()) {
await attendeesTab.click();
await this.page.waitForTimeout(1000);
}
// Look for "Add New" button
const addNewButton = this.page.locator('a:has-text("Add attendee"), button:has-text("Add attendee")');
for (let i = 1; i <= count; i++) {
// Click "Add New" for each attendee
if (await addNewButton.isVisible()) {
await addNewButton.click();
await this.page.waitForTimeout(500);
// Fill in attendee info
await this.page.fill('input[name="attendee[email]"]', `test.attendee${i}@example.com`);
await this.page.fill('input[name="attendee[full_name]"]', `Test Attendee ${i}`);
// Mark every other attendee as checked in
if (i % 2 === 0) {
const checkinCheckbox = this.page.locator('input[name="attendee[check_in]"]');
if (await checkinCheckbox.isVisible()) {
await checkinCheckbox.check();
}
}
// Save the attendee
const saveButton = this.page.locator('button:has-text("Add")');
await saveButton.click();
await this.page.waitForTimeout(1000);
} else {
this.verbosity.log('Warning: Add attendee button not found');
break;
}
}
}
/**
* Creates a complete test event with attendees for certificate testing
*/
async setupCertificateTestEvent(): Promise<string | null> {
// Create a uniquely named event
const timestamp = new Date().getTime();
const eventName = `Certificate Test Event ${timestamp}`;
// Create the event
const eventId = await this.createTestEvent(eventName);
if (!eventId) {
this.verbosity.log('Failed to create test event');
return null;
}
// Add test attendees (mix of checked-in and non-checked-in)
await this.createTestAttendees(eventId, 6);
return eventName;
}
}