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('