import { test, expect } from './fixtures/auth'; import { CommonActions } from './utils/common-actions'; /** * Certificate edge cases and error handling tests * Tests: validation, error scenarios, boundary conditions * @tag @certificates @edge-cases */ test.describe('Certificate Edge Cases', () => { test('Error handling for invalid certificate generation', async ({ authenticatedPage: page }) => { const actions = new CommonActions(page); // Navigate to Generate Certificates page await actions.navigateAndWait('/generate-certificates/'); // Test submitting without selecting an event const submitButton = page.locator('button[type="submit"], input[type="submit"]'); if (await submitButton.count() > 0) { await submitButton.click(); await actions.waitForAjax(); // Look for error messages const errorSelectors = [ '.error', '.notice-error', 'div:has-text(/error/i)', 'span:has-text(/required/i)', 'p:has-text(/select/i)' ]; let foundError = false; for (const selector of errorSelectors) { if (await page.locator(selector).count() > 0) { foundError = true; console.log('Found appropriate error message for invalid submission'); break; } } // Either error message shown or no action taken (both are valid) await actions.screenshot('invalid-submission-handled'); } }); test('Certificate generation with no attendees', async ({ authenticatedPage: page }) => { const actions = new CommonActions(page); await actions.navigateAndWait('/generate-certificates/'); const eventSelect = page.locator('select[name="event_id"]'); const eventOptions = await eventSelect.locator('option').count(); if (eventOptions > 1) { // Try to find an event with no attendees by testing each option for (let i = 1; i < Math.min(eventOptions, 5); i++) { await eventSelect.selectOption({ index: i }); await actions.waitForAjax(); // Wait a moment for AJAX to complete await page.waitForTimeout(2000); const attendeeCheckboxes = page.locator('input[name="attendee_ids[]"]'); const attendeeCount = await attendeeCheckboxes.count(); if (attendeeCount === 0) { console.log(`Found event with no attendees at index ${i}`); // Try to submit with no attendees const submitButton = page.locator('button[type="submit"], input[type="submit"]'); if (await submitButton.count() > 0) { await submitButton.click(); await actions.waitForAjax(); // Should show appropriate message const noAttendeesMessages = [ page.locator('text=No attendees'), page.locator('text=No participants'), page.locator('div:has-text(/no.*attendees/i)'), page.locator('p:has-text(/select.*attendees/i)') ]; let foundMessage = false; for (const msg of noAttendeesMessages) { if (await msg.count() > 0) { foundMessage = true; console.log('Found appropriate no-attendees message'); break; } } await actions.screenshot('no-attendees-handled'); } break; } } } }); test('Certificate page accessibility and performance', async ({ authenticatedPage: page }) => { const actions = new CommonActions(page); // Test page load performance const startTime = Date.now(); await actions.navigateAndWait('/generate-certificates/'); const loadTime = Date.now() - startTime; console.log(`Certificate generation page loaded in ${loadTime}ms`); expect(loadTime).toBeLessThan(10000); // Should load within 10 seconds // Test basic accessibility const accessibilityChecks = [ { selector: 'h1, h2', name: 'Page has heading' }, { selector: 'label', name: 'Form has labels' }, { selector: 'button, input[type="submit"]', name: 'Page has interactive elements' } ]; for (const check of accessibilityChecks) { const elements = page.locator(check.selector); const count = await elements.count(); expect(count).toBeGreaterThan(0); console.log(`✓ ${check.name}: Found ${count} elements`); } await actions.screenshot('accessibility-verified'); }); test('Certificate system under load simulation', async ({ authenticatedPage: page }) => { const actions = new CommonActions(page); // Simulate rapid navigation between certificate pages const pages = [ '/certificate-reports/', '/generate-certificates/', '/certificate-reports/', '/generate-certificates/' ]; for (let i = 0; i < pages.length; i++) { const startTime = Date.now(); await actions.navigateAndWait(pages[i]); const loadTime = Date.now() - startTime; console.log(`Page ${i + 1} loaded in ${loadTime}ms`); // Verify page loaded correctly const hasContent = await page.locator('h1, h2, .content, main').count() > 0; expect(hasContent).toBeTruthy(); // Short pause to simulate user behavior await page.waitForTimeout(500); } await actions.screenshot('load-simulation-completed'); }); test('Certificate data validation and sanitization', async ({ authenticatedPage: page }) => { const actions = new CommonActions(page); await actions.navigateAndWait('/generate-certificates/'); // Test XSS prevention in any input fields const inputFields = page.locator('input[type="text"], input[type="search"], textarea'); const inputCount = await inputFields.count(); if (inputCount > 0) { const testInput = ''; await inputFields.first().fill(testInput); // Verify the input is sanitized or escaped const value = await inputFields.first().inputValue(); expect(value).not.toContain('