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

251 lines
No EOL
10 KiB
TypeScript

import { Page } from '@playwright/test';
import { BasePage } from './BasePage';
export class CertificatePage extends BasePage {
// Generate Certificates page selectors
private readonly generateCertificatesTitle = 'h1:has-text("Generate Certificates")';
private readonly eventSelector = 'select[name="event_id"]';
private readonly eventSearchInput = 'input[name="event_search"]';
private readonly selectAllCheckbox = 'input[name="select_all"]';
private readonly attendeeCheckboxes = 'input[name="attendees[]"]';
private readonly generateButton = 'button:has-text("Generate Certificates")';
private readonly previewButton = 'button:has-text("Preview Certificate")';
private readonly successMessage = '.hvac-success-message';
private readonly errorMessage = '.hvac-error-message';
private readonly attendeeList = '.hvac-attendee-list';
private readonly attendeeItem = '.hvac-attendee-item';
private readonly checkinStatusAttribute = 'data-checkin-status';
private readonly loadingIndicator = '.hvac-loading';
// Certificate Reports page selectors
private readonly certificateReportsTitle = 'h1:has-text("Certificate Reports")';
private readonly certificateFilterInput = 'input[name="certificate_search"]';
private readonly certificateTable = '.hvac-certificate-table';
private readonly certificateTableRows = '.hvac-certificate-table tbody tr';
private readonly viewCertificateButton = 'button:has-text("View")';
private readonly emailCertificateButton = 'button:has-text("Email")';
private readonly revokeCertificateButton = 'button:has-text("Revoke")';
private readonly certificatePagination = '.hvac-pagination';
private readonly certificateModal = '.hvac-certificate-modal';
private readonly certificatePreview = '.hvac-certificate-preview';
private readonly closeModalButton = '.hvac-modal-close';
private readonly confirmRevocationButton = 'button:has-text("Confirm Revocation")';
private readonly confirmEmailButton = 'button:has-text("Send Email")';
constructor(page: Page) {
super(page);
}
// Common methods
async navigateToGenerateCertificates(): Promise<void> {
const STAGING_URL = 'https://wordpress-974670-5399585.cloudwaysapps.com';
await this.page.goto(`${STAGING_URL}/generate-certificates/`);
await this.page.waitForLoadState('networkidle');
await this.screenshot('generate-certificates-page');
}
async navigateToCertificateReports(): Promise<void> {
const STAGING_URL = 'https://wordpress-974670-5399585.cloudwaysapps.com';
await this.page.goto(`${STAGING_URL}/certificate-reports/`);
await this.page.waitForLoadState('networkidle');
await this.screenshot('certificate-reports-page');
}
// Generate Certificates page methods
async isGenerateCertificatesPageVisible(): Promise<boolean> {
return await this.isVisible(this.generateCertificatesTitle);
}
async selectEvent(eventName: string): Promise<void> {
// If there's a search input, try using it
if (await this.isVisible(this.eventSearchInput)) {
await this.fill(this.eventSearchInput, eventName);
await this.page.waitForTimeout(500); // Wait for search results
}
// Select the event from dropdown
await this.page.selectOption(this.eventSelector, { label: eventName });
await this.page.waitForTimeout(1000); // Wait for attendee list to load
// Wait for loading indicator to disappear if it's present
const loadingElement = this.page.locator(this.loadingIndicator);
if (await loadingElement.isVisible()) {
await loadingElement.waitFor({ state: 'hidden', timeout: 5000 });
}
await this.screenshot('event-selected');
}
async getAttendeeCount(): Promise<number> {
return await this.page.locator(this.attendeeItem).count();
}
async getCheckedInAttendeeCount(): Promise<number> {
let checkedInCount = 0;
const attendees = this.page.locator(this.attendeeItem);
const count = await attendees.count();
for (let i = 0; i < count; i++) {
const status = await attendees.nth(i).getAttribute(this.checkinStatusAttribute);
if (status === 'checked-in') {
checkedInCount++;
}
}
return checkedInCount;
}
async selectAllAttendees(): Promise<void> {
await this.click(this.selectAllCheckbox);
await this.screenshot('all-attendees-selected');
}
async selectCheckedInAttendees(): Promise<void> {
// Deselect "Select All" if it's checked
const selectAllChecked = await this.page.isChecked(this.selectAllCheckbox);
if (selectAllChecked) {
await this.click(this.selectAllCheckbox);
}
// Select only checked-in attendees
const attendees = this.page.locator(this.attendeeItem);
const count = await attendees.count();
for (let i = 0; i < count; i++) {
const status = await attendees.nth(i).getAttribute(this.checkinStatusAttribute);
if (status === 'checked-in') {
const checkbox = attendees.nth(i).locator('input[type="checkbox"]');
await checkbox.check();
}
}
await this.screenshot('checked-in-attendees-selected');
}
async selectNonCheckedInAttendees(): Promise<void> {
// Deselect "Select All" if it's checked
const selectAllChecked = await this.page.isChecked(this.selectAllCheckbox);
if (selectAllChecked) {
await this.click(this.selectAllCheckbox);
}
// Select only non-checked-in attendees
const attendees = this.page.locator(this.attendeeItem);
const count = await attendees.count();
for (let i = 0; i < count; i++) {
const status = await attendees.nth(i).getAttribute(this.checkinStatusAttribute);
if (status !== 'checked-in') {
const checkbox = attendees.nth(i).locator('input[type="checkbox"]');
await checkbox.check();
}
}
await this.screenshot('non-checked-in-attendees-selected');
}
async generateCertificates(): Promise<void> {
await this.click(this.generateButton);
// Wait for loading indicator to disappear if it's present
const loadingElement = this.page.locator(this.loadingIndicator);
if (await loadingElement.isVisible()) {
await loadingElement.waitFor({ state: 'hidden', timeout: 10000 });
}
await this.page.waitForTimeout(2000); // Additional wait for any post-processing
await this.screenshot('certificates-generated');
}
async previewCertificate(): Promise<void> {
await this.click(this.previewButton);
// Wait for the preview modal to appear
await this.waitForElement(this.certificateModal);
await this.screenshot('certificate-preview');
}
async closePreview(): Promise<void> {
if (await this.isVisible(this.closeModalButton)) {
await this.click(this.closeModalButton);
await this.page.waitForTimeout(500); // Wait for modal to close
}
}
async isSuccessMessageVisible(): Promise<boolean> {
return await this.isVisible(this.successMessage);
}
async isErrorMessageVisible(): Promise<boolean> {
return await this.isVisible(this.errorMessage);
}
async getSuccessMessage(): Promise<string> {
return await this.getText(this.successMessage);
}
async getErrorMessage(): Promise<string> {
return await this.getText(this.errorMessage);
}
// Certificate Reports page methods
async isCertificateReportsPageVisible(): Promise<boolean> {
return await this.isVisible(this.certificateReportsTitle);
}
async searchCertificates(query: string): Promise<void> {
await this.fill(this.certificateFilterInput, query);
await this.page.waitForTimeout(1000); // Wait for search results
// Wait for loading indicator to disappear if it's present
const loadingElement = this.page.locator(this.loadingIndicator);
if (await loadingElement.isVisible()) {
await loadingElement.waitFor({ state: 'hidden', timeout: 5000 });
}
await this.screenshot('certificate-search');
}
async getCertificateCount(): Promise<number> {
return await this.page.locator(this.certificateTableRows).count();
}
async viewCertificate(index: number = 0): Promise<void> {
const viewButtons = this.page.locator(this.viewCertificateButton);
await viewButtons.nth(index).click();
// Wait for the preview modal to appear
await this.waitForElement(this.certificateModal);
await this.screenshot('view-certificate');
}
async emailCertificate(index: number = 0): Promise<void> {
const emailButtons = this.page.locator(this.emailCertificateButton);
await emailButtons.nth(index).click();
// Wait for the email confirmation dialog
if (await this.isVisible(this.confirmEmailButton)) {
await this.click(this.confirmEmailButton);
await this.page.waitForTimeout(2000); // Wait for email to be sent
}
await this.screenshot('email-certificate');
}
async revokeCertificate(index: number = 0): Promise<void> {
const revokeButtons = this.page.locator(this.revokeCertificateButton);
await revokeButtons.nth(index).click();
// Wait for the revocation confirmation dialog
if (await this.isVisible(this.confirmRevocationButton)) {
await this.click(this.confirmRevocationButton);
await this.page.waitForTimeout(2000); // Wait for revocation to complete
}
await this.screenshot('revoke-certificate');
}
async isPaginationVisible(): Promise<boolean> {
return await this.isVisible(this.certificatePagination);
}
}