- Fix Certificate Reports page to properly display certificates with statistics and filtering - Fix Generate Certificates page to load attendees correctly and resolve PHP errors - Fix Create Event page to properly detect and use TEC Community Events shortcode - Remove all My Events navigation links and replace with Certificate Reports links - Fix help system by removing duplicate navigation elements - Add comprehensive E2E test suite to verify all fixes and prevent regressions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
390 lines
No EOL
16 KiB
TypeScript
390 lines
No EOL
16 KiB
TypeScript
/**
|
|
* Comprehensive E2E Tests for HVAC Plugin Functionality
|
|
*
|
|
* Tests all recent fixes and enhancements:
|
|
* 1. Certificate Reports page functionality
|
|
* 2. Generate Certificates page functionality
|
|
* 3. Navigation updates (no My Events links)
|
|
* 4. Create Event page behavior
|
|
* 5. PHP error monitoring
|
|
*/
|
|
|
|
import { test, expect } from './fixtures/auth';
|
|
import { CommonActions } from './utils/common-actions';
|
|
|
|
test.describe('HVAC Plugin Comprehensive Functionality Tests', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// Monitor for PHP errors throughout all tests
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error' && msg.text().includes('PHP')) {
|
|
console.error('PHP Error detected:', msg.text());
|
|
}
|
|
});
|
|
});
|
|
|
|
test('Dashboard Navigation - Verify correct links and no My Events', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
await actions.navigateAndWait('/hvac-dashboard/');
|
|
await actions.screenshot('dashboard-navigation');
|
|
|
|
// Check that My Events links are removed
|
|
const myEventsLinks = await page.locator('a[href*="my-events"]').count();
|
|
expect(myEventsLinks).toBe(0);
|
|
console.log('✅ No My Events links found on dashboard');
|
|
|
|
// Verify all navigation buttons are present
|
|
const navButtons = [
|
|
{ text: 'Create Event', exists: true },
|
|
{ text: 'Certificate Reports', exists: true },
|
|
{ text: 'Generate Certificates', exists: true },
|
|
{ text: 'View Profile', exists: true },
|
|
{ text: 'Help', exists: true },
|
|
{ text: 'My Events', exists: false } // Should NOT exist
|
|
];
|
|
|
|
for (const button of navButtons) {
|
|
const count = await page.locator(`.hvac-dashboard-nav a:has-text("${button.text}")`).count();
|
|
if (button.exists) {
|
|
expect(count).toBeGreaterThan(0);
|
|
console.log(`✅ ${button.text} button found`);
|
|
} else {
|
|
expect(count).toBe(0);
|
|
console.log(`✅ ${button.text} button correctly absent`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('Certificate Reports - Full functionality test', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(45000);
|
|
const actions = new CommonActions(page);
|
|
|
|
await actions.navigateAndWait('/certificate-reports/');
|
|
await actions.screenshot('certificate-reports-loaded');
|
|
|
|
// Check page elements
|
|
await expect(page.locator('h1').first()).toContainText('Certificate Reports');
|
|
|
|
// Verify statistics section
|
|
const statsSection = page.locator('.hvac-certificate-stats');
|
|
await expect(statsSection).toBeVisible();
|
|
|
|
const statCards = await page.locator('.hvac-stat-card').count();
|
|
expect(statCards).toBe(4); // Total, Active, Revoked, Emailed
|
|
console.log('✅ All 4 statistics cards present');
|
|
|
|
// Check each stat card has a value
|
|
const statValues = await page.locator('.hvac-stat-value').allTextContents();
|
|
expect(statValues.length).toBe(4);
|
|
statValues.forEach((value, index) => {
|
|
expect(value).toMatch(/^\d+$/); // Should be a number
|
|
});
|
|
console.log(`✅ Statistics values: Total=${statValues[0]}, Active=${statValues[1]}, Revoked=${statValues[2]}, Emailed=${statValues[3]}`);
|
|
|
|
// Verify filters section
|
|
const filtersSection = page.locator('.hvac-filters-section');
|
|
await expect(filtersSection).toBeVisible();
|
|
|
|
// Check event filter
|
|
const eventFilter = page.locator('#filter_event');
|
|
await expect(eventFilter).toBeVisible();
|
|
const eventOptions = await eventFilter.locator('option').count();
|
|
expect(eventOptions).toBeGreaterThan(0);
|
|
console.log(`✅ Event filter has ${eventOptions} options`);
|
|
|
|
// Check status filter
|
|
const statusFilter = page.locator('#filter_status');
|
|
await expect(statusFilter).toBeVisible();
|
|
const statusOptions = await statusFilter.locator('option').count();
|
|
expect(statusOptions).toBe(3); // All, Active, Revoked
|
|
console.log('✅ Status filter has correct options');
|
|
|
|
// Test filter functionality
|
|
if (eventOptions > 1) {
|
|
await eventFilter.selectOption({ index: 1 });
|
|
await page.click('button:has-text("Apply Filters")');
|
|
await page.waitForLoadState('networkidle');
|
|
await actions.screenshot('certificate-reports-filtered');
|
|
console.log('✅ Filter functionality working');
|
|
}
|
|
|
|
// Check certificate display area
|
|
const hasTable = await page.locator('.hvac-certificate-table').isVisible().catch(() => false);
|
|
const hasNoResults = await page.locator('.hvac-no-certificates').isVisible().catch(() => false);
|
|
expect(hasTable || hasNoResults).toBe(true);
|
|
console.log(`✅ Certificate display area present (table: ${hasTable}, no results: ${hasNoResults})`);
|
|
});
|
|
|
|
test('Generate Certificates - Complete workflow test', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(60000);
|
|
const actions = new CommonActions(page);
|
|
|
|
await actions.navigateAndWait('/generate-certificates/');
|
|
await actions.screenshot('generate-certificates-initial');
|
|
|
|
// Verify page structure
|
|
await expect(page.locator('h1').first()).toContainText('Generate Certificates');
|
|
|
|
// Step 1: Event Selection
|
|
const eventSelect = page.locator('#event_id');
|
|
await expect(eventSelect).toBeVisible();
|
|
const eventOptions = await eventSelect.locator('option').count();
|
|
expect(eventOptions).toBeGreaterThan(1);
|
|
console.log(`✅ Event dropdown has ${eventOptions} options`);
|
|
|
|
// Select first real event
|
|
const firstEventValue = await eventSelect.locator('option').nth(1).getAttribute('value');
|
|
await eventSelect.selectOption({ value: firstEventValue! });
|
|
console.log(`✅ Selected event ID: ${firstEventValue}`);
|
|
|
|
// Wait for page reload with event parameter
|
|
await page.waitForURL(/event_id=/);
|
|
await page.waitForLoadState('networkidle');
|
|
await actions.screenshot('generate-certificates-event-selected');
|
|
|
|
// Step 2: Verify attendees section
|
|
const attendeesSection = page.locator('#step-select-attendees');
|
|
await expect(attendeesSection).toBeVisible();
|
|
console.log('✅ Attendees section visible');
|
|
|
|
// Check form elements
|
|
const certificateForm = page.locator('#generate-certificates-form');
|
|
await expect(certificateForm).toBeVisible();
|
|
|
|
// Verify nonce field exists (security)
|
|
const nonceField = await page.locator('input[name="hvac_certificate_nonce"]').count();
|
|
expect(nonceField).toBe(1);
|
|
console.log('✅ Security nonce field present');
|
|
|
|
// Check attendee display
|
|
const hasAttendeesTable = await page.locator('.hvac-attendees-table').isVisible().catch(() => false);
|
|
const hasEmptyMessage = await page.locator('.hvac-empty-state').isVisible().catch(() => false);
|
|
expect(hasAttendeesTable || hasEmptyMessage).toBe(true);
|
|
console.log(`✅ Attendee display present (table: ${hasAttendeesTable}, empty: ${hasEmptyMessage})`);
|
|
|
|
if (hasAttendeesTable) {
|
|
// Verify table structure
|
|
await expect(page.locator('.hvac-attendees-table thead')).toBeVisible();
|
|
await expect(page.locator('.hvac-attendees-table tbody')).toBeVisible();
|
|
|
|
// Check action buttons
|
|
const actionButtons = [
|
|
'#select-all-attendees',
|
|
'#select-checked-in',
|
|
'#deselect-all-attendees'
|
|
];
|
|
|
|
for (const button of actionButtons) {
|
|
await expect(page.locator(button)).toBeVisible();
|
|
}
|
|
console.log('✅ All attendee action buttons present');
|
|
|
|
// Test select all functionality
|
|
await page.click('#select-all-attendees');
|
|
const checkedCount = await page.locator('.attendee-checkbox:checked').count();
|
|
expect(checkedCount).toBeGreaterThan(0);
|
|
console.log(`✅ Select all functionality working (${checkedCount} selected)`);
|
|
|
|
// Check generate button
|
|
const generateButton = page.locator('button[name="generate_certificates"]');
|
|
await expect(generateButton).toBeVisible();
|
|
await expect(generateButton).toHaveText('Generate Certificates');
|
|
console.log('✅ Generate certificates button present');
|
|
}
|
|
|
|
// Verify certificate preview section
|
|
const previewSection = page.locator('.hvac-certificate-preview');
|
|
await expect(previewSection).toBeVisible();
|
|
console.log('✅ Certificate preview section present');
|
|
});
|
|
|
|
test('Create Event page - Verify shortcode handling', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
await actions.navigateAndWait('/manage-event/');
|
|
await actions.screenshot('create-event-page');
|
|
|
|
// Check page title
|
|
await expect(page.locator('h1').first()).toContainText(/Create.*Event|Manage.*Event/i);
|
|
|
|
// Get page content
|
|
const bodyText = await page.locator('body').textContent();
|
|
|
|
// Check for shortcode or form
|
|
if (bodyText?.includes('[tribe_community_events')) {
|
|
console.log('✅ Page shows TEC shortcode (Community Events not active)');
|
|
expect(bodyText).toContain('[tribe_community_events');
|
|
|
|
// Verify it's displayed as content, not an error
|
|
const hasError = await page.locator('.error, .hvac-error').count();
|
|
expect(hasError).toBe(0);
|
|
console.log('✅ No error messages displayed');
|
|
} else {
|
|
// Check for any form that would allow event creation
|
|
const forms = await page.locator('form').count();
|
|
const hasEventFields = await page.locator('input[name*="event"], input[name*="Event"], #event_title, #post_title').count();
|
|
|
|
console.log(`✅ Page has ${forms} forms and ${hasEventFields} event-related fields`);
|
|
|
|
if (forms > 0) {
|
|
expect(hasEventFields).toBeGreaterThan(0);
|
|
console.log('✅ Event creation form detected');
|
|
}
|
|
}
|
|
});
|
|
|
|
test('Trainer Profile - Verify navigation updates', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(30000);
|
|
const actions = new CommonActions(page);
|
|
|
|
await actions.navigateAndWait('/trainer-profile/');
|
|
await actions.screenshot('trainer-profile-navigation');
|
|
|
|
// Check no My Events links
|
|
const myEventsLinks = await page.locator('a[href*="my-events"]').count();
|
|
expect(myEventsLinks).toBe(0);
|
|
console.log('✅ No My Events links on trainer profile');
|
|
|
|
// Verify Certificate Reports link exists
|
|
const certReportsLink = await page.locator('a:has-text("Certificate Reports")').count();
|
|
expect(certReportsLink).toBeGreaterThan(0);
|
|
console.log('✅ Certificate Reports link present on trainer profile');
|
|
|
|
// Check other navigation elements
|
|
const expectedLinks = ['Dashboard', 'Create Event', 'Certificate Reports', 'Help', 'Logout'];
|
|
for (const linkText of expectedLinks) {
|
|
const linkExists = await page.locator(`.hvac-dashboard-nav a:has-text("${linkText}")`).count() > 0;
|
|
if (linkExists) {
|
|
console.log(`✅ ${linkText} link found`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('My Events page removal verification', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(20000);
|
|
const actions = new CommonActions(page);
|
|
|
|
// Attempt to navigate to my-events
|
|
const response = await page.goto('/my-events/', { waitUntil: 'networkidle' });
|
|
const status = response?.status() || 0;
|
|
const finalUrl = page.url();
|
|
|
|
console.log(`My Events page status: ${status}`);
|
|
console.log(`Final URL: ${finalUrl}`);
|
|
|
|
// The page might still exist but should not be linked anywhere
|
|
if (status === 200 && finalUrl.includes('/my-events/')) {
|
|
console.log('⚠️ My Events page still exists but is not linked in navigation');
|
|
|
|
// Verify it's not linked from any main pages
|
|
const pagesToCheck = ['/hvac-dashboard/', '/trainer-profile/'];
|
|
for (const pageUrl of pagesToCheck) {
|
|
await actions.navigateAndWait(pageUrl);
|
|
const myEventsLinksOnPage = await page.locator('a[href*="my-events"]').count();
|
|
expect(myEventsLinksOnPage).toBe(0);
|
|
console.log(`✅ No My Events links on ${pageUrl}`);
|
|
}
|
|
} else {
|
|
console.log('✅ My Events page not accessible or redirects');
|
|
}
|
|
});
|
|
|
|
test('PHP Error Monitoring - No errors across all pages', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(45000);
|
|
const actions = new CommonActions(page);
|
|
const phpErrors: string[] = [];
|
|
|
|
// Enhanced error monitoring
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') {
|
|
const text = msg.text();
|
|
if (text.includes('PHP') || text.includes('Fatal') || text.includes('Warning') || text.includes('Notice')) {
|
|
phpErrors.push(`[${msg.type()}] ${text}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Test all main pages
|
|
const pagesToTest = [
|
|
{ url: '/hvac-dashboard/', name: 'Dashboard' },
|
|
{ url: '/certificate-reports/', name: 'Certificate Reports' },
|
|
{ url: '/generate-certificates/', name: 'Generate Certificates' },
|
|
{ url: '/manage-event/', name: 'Create Event' },
|
|
{ url: '/trainer-profile/', name: 'Trainer Profile' }
|
|
];
|
|
|
|
for (const pageInfo of pagesToTest) {
|
|
console.log(`Testing ${pageInfo.name}...`);
|
|
await actions.navigateAndWait(pageInfo.url);
|
|
await page.waitForTimeout(1000); // Give time for any errors to appear
|
|
|
|
// Additional test for Generate Certificates with event selection
|
|
if (pageInfo.url === '/generate-certificates/') {
|
|
const eventOptions = await page.locator('#event_id option').count();
|
|
if (eventOptions > 1) {
|
|
await page.selectOption('#event_id', { index: 1 });
|
|
await page.waitForTimeout(2000);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Report results
|
|
if (phpErrors.length > 0) {
|
|
console.error('❌ PHP Errors detected:');
|
|
phpErrors.forEach(error => console.error(error));
|
|
expect(phpErrors.length).toBe(0);
|
|
} else {
|
|
console.log('✅ No PHP errors detected across all pages');
|
|
}
|
|
});
|
|
|
|
test('Complete User Journey - Event to Certificate', async ({ authenticatedPage: page }) => {
|
|
test.setTimeout(60000);
|
|
const actions = new CommonActions(page);
|
|
|
|
console.log('Starting complete user journey test...');
|
|
|
|
// 1. Dashboard
|
|
await actions.navigateAndWait('/hvac-dashboard/');
|
|
await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible();
|
|
console.log('✅ Step 1: Dashboard loaded');
|
|
|
|
// 2. Navigate to Certificate Reports
|
|
await page.click('a:has-text("Certificate Reports")');
|
|
await page.waitForLoadState('networkidle');
|
|
await expect(page.locator('h1:has-text("Certificate Reports")')).toBeVisible();
|
|
const initialStats = await page.locator('.hvac-stat-value').first().textContent();
|
|
console.log(`✅ Step 2: Certificate Reports loaded (Total certificates: ${initialStats})`);
|
|
|
|
// 3. Navigate to Generate Certificates
|
|
await page.click('a:has-text("Generate Certificates")');
|
|
await page.waitForLoadState('networkidle');
|
|
await expect(page.locator('h1:has-text("Generate Certificates")')).toBeVisible();
|
|
console.log('✅ Step 3: Generate Certificates loaded');
|
|
|
|
// 4. Select an event
|
|
const eventOptions = await page.locator('#event_id option').count();
|
|
if (eventOptions > 1) {
|
|
await page.selectOption('#event_id', { index: 1 });
|
|
await page.waitForURL(/event_id=/);
|
|
await expect(page.locator('#step-select-attendees')).toBeVisible();
|
|
console.log('✅ Step 4: Event selected and attendees loaded');
|
|
}
|
|
|
|
// 5. Return to dashboard
|
|
await page.click('a[href*="hvac-dashboard"]').first();
|
|
await page.waitForLoadState('networkidle');
|
|
await expect(page.locator('h1:has-text("Dashboard")')).toBeVisible();
|
|
console.log('✅ Step 5: Returned to dashboard');
|
|
|
|
// 6. Check Create Event
|
|
await page.click('a:has-text("Create Event")');
|
|
await page.waitForLoadState('networkidle');
|
|
await expect(page.locator('h1').first()).toContainText(/Event/i);
|
|
console.log('✅ Step 6: Create Event page accessed');
|
|
|
|
console.log('✅ Complete user journey test passed!');
|
|
});
|
|
}); |