import { test, expect } from '@playwright/test'; import { loginAsTrainer } from './utils/login-helpers'; import { createTestEvent } from './utils/event-helpers'; /** * Email Attendees feature tests * @group @email-attendees */ test.describe('Email Attendees Functionality', () => { let eventId: string; let eventTitle: string = 'Test Event for Email Attendees'; test.beforeAll(async ({ browser }) => { // Create a test event with attendees const context = await browser.newContext(); const page = await context.newPage(); await loginAsTrainer(page); // Create a test event eventId = await createTestEvent(page, { title: eventTitle, description: 'This is a test event for the email attendees functionality', ticketType: 'General Admission', price: '50.00' }); // Add test attendees - In a real environment, you'd use the Tribe Tickets API // For testing, we'd either mock this or use a separate helper to purchase tickets await context.close(); }); test('can access Email Attendees page from Event Summary', async ({ page }) => { // Login as trainer await loginAsTrainer(page); // Navigate to event summary await page.goto(`/event-summary/?event_id=${eventId}`); await expect(page).toHaveTitle(new RegExp(eventTitle)); // Check that the Email Attendees button exists const emailAttendeesButton = page.locator('a:text("Email Attendees")'); await expect(emailAttendeesButton).toBeVisible(); // Click Email Attendees button await emailAttendeesButton.click(); // Verify we're on the Email Attendees page await expect(page).toHaveURL(new RegExp(`/email-attendees/\\?event_id=${eventId}`)); await expect(page.locator('h1:text("Email Attendees")')).toBeVisible(); await expect(page.locator(`h2:text("${eventTitle}")`)).toBeVisible(); }); test('email form has all required elements', async ({ page }) => { // Login and go to Email Attendees page await loginAsTrainer(page); await page.goto(`/email-attendees/?event_id=${eventId}`); // Check for required form elements await expect(page.locator('#email_subject')).toBeVisible(); await expect(page.locator('#email_cc')).toBeVisible(); // The rich text editor might be in an iframe, so check for either const hasEditor = await page.locator('.wp-editor-area, #email_message').count() > 0; expect(hasEditor).toBeTruthy(); // Check for recipients section await expect(page.locator('h3:text("Recipients")')).toBeVisible(); // Check for Send Email button await expect(page.locator('button[name="hvac_send_email"]')).toBeVisible(); }); test('can filter attendees by ticket type', async ({ page }) => { // Login and go to Email Attendees page await loginAsTrainer(page); await page.goto(`/email-attendees/?event_id=${eventId}`); // Check if there's a ticket type filter (may not be visible if only one ticket type) const hasTicketTypeFilter = await page.locator('#ticket_type_filter').count() > 0; if (hasTicketTypeFilter) { // Select a ticket type await page.selectOption('#ticket_type_filter', 'General Admission'); // Wait for page to refresh await page.waitForLoadState('networkidle'); // Verify URL contains the ticket type parameter await expect(page).toHaveURL(new RegExp('ticket_type=General\\+Admission')); // Verify attendees are filtered const attendeeItems = page.locator('.hvac-attendee-item'); await expect(attendeeItems).toContainText(['General Admission']); } }); test('can select all attendees', async ({ page }) => { // Login and go to Email Attendees page await loginAsTrainer(page); await page.goto(`/email-attendees/?event_id=${eventId}`); // Get initial count of checked boxes const initialCheckedCount = await page.locator('.hvac-attendee-checkbox:checked').count(); expect(initialCheckedCount).toBe(0); // Click "Select All" checkbox await page.locator('#select_all_attendees').click(); // Verify all checkboxes are now checked const attendeeCheckboxes = page.locator('.hvac-attendee-checkbox'); const attendeeCount = await attendeeCheckboxes.count(); const checkedCount = await page.locator('.hvac-attendee-checkbox:checked').count(); expect(checkedCount).toBe(attendeeCount); }); test('shows validation error when form is incomplete', async ({ page }) => { // Login and go to Email Attendees page await loginAsTrainer(page); await page.goto(`/email-attendees/?event_id=${eventId}`); // Submit form without filling required fields await page.locator('button[name="hvac_send_email"]').click(); // Verify error message is shown await expect(page.locator('.hvac-email-error')).toBeVisible(); await expect(page.locator('.hvac-email-error')).toContainText('fill in all required fields'); }); test('can send email to attendees', async ({ page }) => { // Login and go to Email Attendees page await loginAsTrainer(page); await page.goto(`/email-attendees/?event_id=${eventId}`); // Fill out the form await page.fill('#email_subject', 'Test Email Subject'); // Fill the message (handling both regular textarea and TinyMCE) if (await page.locator('#email_message').count() > 0) { await page.fill('#email_message', 'This is a test email message.'); } else { // For TinyMCE, we need to use the iframe const frame = page.frameLocator('.wp-editor-container iframe'); await frame.locator('body').fill('This is a test email message.'); } // Select recipients (first attendee) await page.locator('.hvac-attendee-checkbox').first().check(); // Submit form await page.locator('button[name="hvac_send_email"]').click(); // Verify success message await expect(page.locator('.hvac-email-sent')).toBeVisible(); await expect(page.locator('.hvac-email-sent')).toContainText('Email successfully sent'); }); });