- Add missing render_certificate_fix() method to main plugin class - Remove duplicate shortcode registration causing PHP errors - Enhance legacy redirect system with dual-hook approach for better compatibility - Update certificate reports template URLs to hierarchical structure - Add comprehensive E2E test suite with Playwright for all plugin pages - Create deployment and verification scripts for automated testing - Add detailed documentation for deployment, troubleshooting, and maintenance - Update package.json with Playwright test dependencies - Achieve 89% success rate for plugin functionality and 100% for redirects 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
234 lines
No EOL
9.2 KiB
TypeScript
234 lines
No EOL
9.2 KiB
TypeScript
import { test, expect, Page } from '@playwright/test';
|
|
|
|
/**
|
|
* E2E Test Suite to Verify Bug Fixes
|
|
*
|
|
* This test suite specifically verifies the fixes implemented for:
|
|
* - Certificate reports 404 error
|
|
* - Legacy URL redirects
|
|
* - Missing shortcode render methods
|
|
*/
|
|
|
|
// Helper function to take screenshots for verification
|
|
async function takeFixVerificationScreenshot(page: Page, testName: string) {
|
|
await page.screenshot({
|
|
path: `test-results/screenshots/fix-verification-${testName}.png`,
|
|
fullPage: true
|
|
});
|
|
}
|
|
|
|
test.describe('HVAC Plugin Bug Fixes Verification', () => {
|
|
|
|
test('Certificate Reports page fix verification', async ({ page }) => {
|
|
// Navigate to certificate reports page
|
|
await page.goto('/trainer/certificate-reports/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Take screenshot for verification
|
|
await takeFixVerificationScreenshot(page, 'certificate-reports-fixed');
|
|
|
|
// Should not show "This page doesn't seem to exist" anymore
|
|
const bodyText = await page.locator('body').textContent();
|
|
expect(bodyText).not.toContain("This page doesn't seem to exist");
|
|
expect(bodyText).not.toContain("404");
|
|
|
|
// Should either redirect to login or show certificate reports content
|
|
const isLoginPage = page.url().includes('/training-login/') ||
|
|
bodyText?.includes('Trainer Login') ||
|
|
bodyText?.includes('Sign in to access');
|
|
|
|
const isCertificatePage = bodyText?.includes('Certificate Reports') ||
|
|
bodyText?.includes('certificate') ||
|
|
bodyText?.includes('Certificate');
|
|
|
|
// Should show either login (for auth) or certificate content
|
|
expect(isLoginPage || isCertificatePage).toBe(true);
|
|
|
|
console.log(`✓ Certificate reports page fix verified - ${isLoginPage ? 'redirected to login' : 'showing certificate content'}`);
|
|
});
|
|
|
|
test('Legacy URL redirects verification', async ({ page }) => {
|
|
const legacyRedirectTests = [
|
|
{ from: '/hvac-dashboard/', to: '/trainer/dashboard/', description: 'Dashboard redirect' },
|
|
{ from: '/trainer-profile/', to: '/trainer/my-profile/', description: 'Profile redirect' },
|
|
{ from: '/certificate-reports/', to: '/trainer/certificate-reports/', description: 'Certificate reports redirect' },
|
|
{ from: '/generate-certificates/', to: '/trainer/generate-certificates/', description: 'Generate certificates redirect' },
|
|
{ from: '/manage-event/', to: '/trainer/event/manage/', description: 'Manage event redirect' }
|
|
];
|
|
|
|
for (const redirectTest of legacyRedirectTests) {
|
|
console.log(`Testing redirect: ${redirectTest.from} → ${redirectTest.to}`);
|
|
|
|
// Navigate to legacy URL
|
|
await page.goto(redirectTest.from);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Take screenshot
|
|
const screenshotName = `legacy-redirect-${redirectTest.from.replace(/[^a-z0-9]/g, '-')}`;
|
|
await takeFixVerificationScreenshot(page, screenshotName);
|
|
|
|
// Check if redirect occurred
|
|
const currentUrl = page.url();
|
|
const redirectOccurred = currentUrl.includes(redirectTest.to);
|
|
|
|
// Should redirect to the correct new URL
|
|
expect(redirectOccurred).toBe(true);
|
|
|
|
// Should not show 404 error
|
|
const bodyText = await page.locator('body').textContent();
|
|
expect(bodyText).not.toContain("This page doesn't seem to exist");
|
|
expect(bodyText).not.toContain("404");
|
|
|
|
console.log(`✓ ${redirectTest.description} working: ${redirectTest.from} → ${currentUrl}`);
|
|
}
|
|
});
|
|
|
|
test('All trainer pages accessibility verification', async ({ page }) => {
|
|
const trainerPages = [
|
|
'/trainer/dashboard/',
|
|
'/trainer/my-profile/',
|
|
'/trainer/certificate-reports/',
|
|
'/trainer/generate-certificates/',
|
|
'/trainer/event/manage/',
|
|
'/trainer/event/summary/',
|
|
'/trainer/email-attendees/',
|
|
'/trainer/communication-templates/',
|
|
'/trainer/communication-schedules/',
|
|
'/trainer/attendee-profile/',
|
|
'/trainer/documentation/'
|
|
];
|
|
|
|
let accessiblePages = 0;
|
|
let totalPages = trainerPages.length;
|
|
|
|
for (const pageUrl of trainerPages) {
|
|
try {
|
|
await page.goto(pageUrl, { timeout: 10000 });
|
|
await page.waitForLoadState('networkidle', { timeout: 5000 });
|
|
|
|
// Take screenshot
|
|
const pageName = pageUrl.split('/').filter(s => s).pop() || 'unknown';
|
|
await takeFixVerificationScreenshot(page, `trainer-page-${pageName}`);
|
|
|
|
// Check page is accessible (not 404)
|
|
const bodyText = await page.locator('body').textContent();
|
|
const is404 = bodyText?.includes("This page doesn't seem to exist") ||
|
|
bodyText?.includes("404") ||
|
|
bodyText?.includes("Page not found");
|
|
|
|
if (!is404) {
|
|
accessiblePages++;
|
|
console.log(`✓ ${pageUrl} is accessible`);
|
|
} else {
|
|
console.log(`✗ ${pageUrl} shows 404 error`);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.log(`✗ ${pageUrl} failed to load: ${error}`);
|
|
}
|
|
}
|
|
|
|
// Calculate success rate
|
|
const successRate = accessiblePages / totalPages;
|
|
console.log(`\n=== TRAINER PAGES ACCESSIBILITY ===`);
|
|
console.log(`Accessible pages: ${accessiblePages}/${totalPages}`);
|
|
console.log(`Success rate: ${Math.round(successRate * 100)}%`);
|
|
|
|
// Should have at least 90% success rate after fixes
|
|
expect(successRate).toBeGreaterThan(0.9);
|
|
});
|
|
|
|
test('Master trainer pages accessibility verification', async ({ page }) => {
|
|
const masterTrainerPages = [
|
|
'/master-trainer/dashboard/',
|
|
'/master-trainer/google-sheets/',
|
|
'/master-trainer/certificate-fix/'
|
|
];
|
|
|
|
let accessiblePages = 0;
|
|
let totalPages = masterTrainerPages.length;
|
|
|
|
for (const pageUrl of masterTrainerPages) {
|
|
try {
|
|
await page.goto(pageUrl, { timeout: 10000 });
|
|
await page.waitForLoadState('networkidle', { timeout: 5000 });
|
|
|
|
// Take screenshot
|
|
const pageName = pageUrl.split('/').filter(s => s).pop() || 'unknown';
|
|
await takeFixVerificationScreenshot(page, `master-trainer-page-${pageName}`);
|
|
|
|
// Check page is accessible (not 404)
|
|
const bodyText = await page.locator('body').textContent();
|
|
const is404 = bodyText?.includes("This page doesn't seem to exist") ||
|
|
bodyText?.includes("404") ||
|
|
bodyText?.includes("Page not found");
|
|
|
|
if (!is404) {
|
|
accessiblePages++;
|
|
console.log(`✓ ${pageUrl} is accessible`);
|
|
} else {
|
|
console.log(`✗ ${pageUrl} shows 404 error`);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.log(`✗ ${pageUrl} failed to load: ${error}`);
|
|
}
|
|
}
|
|
|
|
// Calculate success rate
|
|
const successRate = accessiblePages / totalPages;
|
|
console.log(`\n=== MASTER TRAINER PAGES ACCESSIBILITY ===`);
|
|
console.log(`Accessible pages: ${accessiblePages}/${totalPages}`);
|
|
console.log(`Success rate: ${Math.round(successRate * 100)}%`);
|
|
|
|
// Should have 100% success rate after fixes
|
|
expect(successRate).toBe(1.0);
|
|
});
|
|
|
|
test('Login page continues to work correctly', async ({ page }) => {
|
|
await page.goto('/training-login/');
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Take screenshot
|
|
await takeFixVerificationScreenshot(page, 'login-page-still-working');
|
|
|
|
// Verify login form elements are present
|
|
const hasUsernameField = await page.locator('input[name="log"], input[type="text"]').isVisible().catch(() => false);
|
|
const hasPasswordField = await page.locator('input[name="pwd"], input[type="password"]').isVisible().catch(() => false);
|
|
const hasSubmitButton = await page.locator('input[type="submit"], button[type="submit"], .login-submit').isVisible().catch(() => false);
|
|
|
|
// Login page should still work perfectly
|
|
expect(hasUsernameField || hasPasswordField || hasSubmitButton).toBe(true);
|
|
|
|
// Should show login title
|
|
const bodyText = await page.locator('body').textContent();
|
|
expect(bodyText).toContain('Trainer Login');
|
|
|
|
console.log('✓ Login page continues to work correctly after fixes');
|
|
});
|
|
|
|
test('WordPress admin bar and structure verification', async ({ page }) => {
|
|
// Test a few key pages to ensure WordPress structure is intact
|
|
const testPages = [
|
|
'/training-login/',
|
|
'/trainer/dashboard/',
|
|
'/master-trainer/dashboard/'
|
|
];
|
|
|
|
for (const pageUrl of testPages) {
|
|
await page.goto(pageUrl);
|
|
await page.waitForLoadState('networkidle');
|
|
|
|
// Check for WordPress structure
|
|
const hasWpClasses = await page.locator('body[class*="wp-"]').isVisible().catch(() => false);
|
|
const hasHeader = await page.locator('header, .site-header, .header').isVisible().catch(() => false);
|
|
const hasFooter = await page.locator('footer, .site-footer, .footer').isVisible().catch(() => false);
|
|
|
|
// Should maintain WordPress structure
|
|
const hasWordPressStructure = hasWpClasses || hasHeader || hasFooter;
|
|
expect(hasWordPressStructure).toBe(true);
|
|
|
|
console.log(`✓ ${pageUrl} maintains WordPress structure`);
|
|
}
|
|
});
|
|
}); |