/** * Comprehensive Event Management E2E Tests - Agent B * * Tests complete event lifecycle management functionality including: * - Event creation and editing workflows * - The Events Calendar integration * - Event status transitions and approvals * - Event management dashboard operations * - Advanced event features and analytics * * @package HVAC_Community_Events * @version 2.0.0 * @created 2025-08-27 * @author Agent-B-Event-Management */ const BaseTest = require('../framework/core/BaseTest'); const { expect } = require('@playwright/test'); // Page Objects const EventCreation = require('../page-objects/event-management/EventCreation'); const EventEditing = require('../page-objects/event-management/EventEditing'); const EventManagement = require('../page-objects/event-management/EventManagement'); const TrainerDashboard = require('../page-objects/trainer/TrainerDashboard'); // Test data for parallel execution (Agent B specific) const TEST_DATA = { eventPrefix: 'AgentB-E2E-', uniqueId: Date.now(), testEvents: { basic: { title: `AgentB-Basic-Training-${Date.now()}`, description: 'Agent B test event for basic HVAC training lifecycle testing', startDate: getFormattedDate(7), endDate: getFormattedDate(7), startTime: '09:00', endTime: '17:00', capacity: '25', cost: '299.00' }, advanced: { title: `AgentB-Advanced-Workshop-${Date.now()}`, description: 'Agent B test event for advanced heat pump diagnostics', startDate: getFormattedDate(14), endDate: getFormattedDate(15), startTime: '08:30', endTime: '16:30', capacity: '15', cost: '499.00' }, multiDay: { title: `AgentB-Certification-Bootcamp-${Date.now()}`, description: 'Agent B test event for multi-day certification program', startDate: getFormattedDate(21), endDate: getFormattedDate(23), startTime: '09:00', endTime: '17:00', capacity: '20', cost: '799.00' } } }; // Helper function for date formatting function getFormattedDate(daysFromNow = 0) { const date = new Date(); date.setDate(date.getDate() + daysFromNow); return date.toISOString().split('T')[0]; } BaseTest.describe('Event Management Comprehensive E2E Tests - Agent B', () => { // Test Suite 1: Complete Event Lifecycle Testing BaseTest.describe('Complete Event Lifecycle Testing', () => { BaseTest.create( 'should complete full event lifecycle: Create โ†’ Edit โ†’ Publish โ†’ Manage โ†’ Archive', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing complete event lifecycle'); // Authenticate as trainer await baseTest.authenticateAs(page, 'trainer'); // Initialize page objects const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Step 1: Create event console.log('๐Ÿ“ Step 1: Creating event'); await eventCreation.navigate('standard'); // Verify form accessibility const accessibility = await eventCreation.verifyFormAccessibility(); expect(accessibility.isAccessible).toBe(true); // Fill and submit event creation form const createResult = await eventCreation.createTestEvent('basic', { data: TEST_DATA.testEvents.basic }); expect(createResult.success).toBe(true); const createdEventTitle = createResult.eventData.title; // Step 2: Edit the created event console.log('โœ๏ธ Step 2: Editing event'); await eventManagement.navigate(); await eventManagement.editEvent(createdEventTitle); // Verify edit access const editAccess = await eventEditing.verifyEditAccess(); expect(editAccess.hasEditAccess).toBe(true); // Update event details const updatedData = { description: 'Updated description for lifecycle testing', capacity: '30', cost: '349.00' }; await eventEditing.updateEventFields(updatedData); const updateResult = await eventEditing.updateEvent(); expect(updateResult.success).toBe(true); // Step 3: Test status transitions console.log('๐Ÿ”„ Step 3: Testing status transitions'); const transitions = await eventEditing.testStatusTransitions(); expect(transitions.length).toBeGreaterThan(0); // Publish the event await eventEditing.changeStatus('published'); const publishResult = await eventEditing.updateEvent(); expect(publishResult.success).toBe(true); expect(publishResult.newStatus).toBe('published'); // Step 4: Manage event from dashboard console.log('๐Ÿ“Š Step 4: Managing event'); await eventManagement.navigate(); // Verify event appears in management list const eventsList = await eventManagement.getEventsList(); const eventExists = eventsList.some(event => event.title.includes(createdEventTitle.substring(0, 20)) ); expect(eventExists).toBe(true); // Get management metrics const metrics = await eventManagement.getManagementMetrics(); expect(metrics.totalEvents).toBeGreaterThan(0); console.log('โœ… Complete event lifecycle test passed'); }, { category: 'event-lifecycle', priority: 'critical', tags: ['agent-b', 'event-management', 'lifecycle'] } ); BaseTest.create( 'should handle event status transitions correctly', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event status transitions'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Create test event await eventCreation.navigate(); const createResult = await eventCreation.createTestEvent('basic', { data: TEST_DATA.testEvents.advanced }); expect(createResult.success).toBe(true); // Navigate to edit the event await eventManagement.navigate(); await eventManagement.editEvent(createResult.eventData.title); // Test Draft โ†’ Pending transition const currentStatus = await eventEditing.getCurrentStatus(); console.log(`Current status: ${currentStatus}`); if (currentStatus === 'draft') { await eventEditing.changeStatus('pending'); const pendingResult = await eventEditing.updateEvent(); expect(pendingResult.success).toBe(true); // Test Pending โ†’ Published transition await eventEditing.changeStatus('published'); const publishResult = await eventEditing.updateEvent(); expect(publishResult.success).toBe(true); expect(publishResult.newStatus).toBe('published'); } console.log('โœ… Status transition test passed'); }, { category: 'event-lifecycle', priority: 'high', tags: ['agent-b', 'status-transitions', 'workflow'] } ); }); // Test Suite 2: The Events Calendar Integration BaseTest.describe('The Events Calendar Integration', () => { BaseTest.create( 'should create events through TEC interface', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing TEC event creation'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); // Navigate to TEC creation page await eventCreation.navigate('tec'); // Configure TEC-specific options await eventCreation.configureTECOptions({ allDay: false, showMap: true, timezone: 'America/New_York' }); // Create event with TEC integration const tecEventData = { ...TEST_DATA.testEvents.basic, title: `AgentB-TEC-Integration-${Date.now()}` }; const createResult = await eventCreation.createTestEvent('basic', { data: tecEventData }); expect(createResult.success).toBe(true); console.log('โœ… TEC event creation test passed'); }, { category: 'tec-integration', priority: 'high', tags: ['agent-b', 'tec', 'calendar-integration'] } ); BaseTest.create( 'should edit events through TEC interface', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing TEC event editing'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Create event first await eventCreation.navigate('tec'); const tecEventData = { ...TEST_DATA.testEvents.advanced, title: `AgentB-TEC-Edit-${Date.now()}` }; const createResult = await eventCreation.createTestEvent('basic', { data: tecEventData }); expect(createResult.success).toBe(true); // Navigate to TEC edit interface await eventManagement.navigate('tec'); await eventManagement.editEvent(createResult.eventData.title); // Verify TEC editing capabilities const editAccess = await eventEditing.verifyEditAccess(); expect(editAccess.hasEditAccess).toBe(true); // Update TEC-specific fields await eventEditing.updateEventFields({ description: 'Updated through TEC interface', capacity: '18' }); const updateResult = await eventEditing.updateEvent(); expect(updateResult.success).toBe(true); console.log('โœ… TEC event editing test passed'); }, { category: 'tec-integration', priority: 'high', tags: ['agent-b', 'tec', 'editing'] } ); BaseTest.create( 'should access TEC My Events dashboard', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing TEC My Events dashboard'); await baseTest.authenticateAs(page, 'trainer'); const eventManagement = new EventManagement(page); // Navigate to TEC My Events await eventManagement.navigate('tec'); // Verify dashboard functionality const functionality = await eventManagement.verifyDashboardFunctionality(); expect(functionality.canViewEvents).toBe(true); // Get events list from TEC interface const events = await eventManagement.getEventsList(); console.log(`Found ${events.length} events in TEC interface`); // Verify TEC-specific features expect(functionality.score).toBeGreaterThan(0); console.log('โœ… TEC My Events dashboard test passed'); }, { category: 'tec-integration', priority: 'medium', tags: ['agent-b', 'tec', 'dashboard'] } ); }); // Test Suite 3: Event Management Operations BaseTest.describe('Event Management Operations', () => { BaseTest.create( 'should perform bulk operations on events', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing bulk event operations'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventManagement = new EventManagement(page); // Create multiple test events const testEvents = []; for (let i = 0; i < 3; i++) { await eventCreation.navigate(); const eventData = { ...TEST_DATA.testEvents.basic, title: `AgentB-Bulk-Test-${i}-${Date.now()}` }; const createResult = await eventCreation.createTestEvent('basic', { data: eventData }); expect(createResult.success).toBe(true); testEvents.push(createResult.eventData.title); } // Navigate to management dashboard await eventManagement.navigate(); // Select events for bulk operation const selectedCount = await eventManagement.selectEvents(testEvents); expect(selectedCount).toBe(testEvents.length); // Perform bulk status change const bulkResult = await eventManagement.performBulkAction('publish'); expect(bulkResult.success).toBe(true); console.log('โœ… Bulk operations test passed'); }, { category: 'event-operations', priority: 'high', tags: ['agent-b', 'bulk-operations', 'management'] } ); BaseTest.create( 'should filter and search events effectively', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event filtering and search'); await baseTest.authenticateAs(page, 'trainer'); const eventManagement = new EventManagement(page); // Navigate to management dashboard await eventManagement.navigate(); // Test search functionality const searchTerm = 'AgentB'; const searchResults = await eventManagement.searchEvents(searchTerm); // Verify search results contain the search term const relevantResults = searchResults.filter(event => event.title.toLowerCase().includes(searchTerm.toLowerCase()) ); expect(relevantResults.length).toBeGreaterThan(0); // Test status filtering const draftEvents = await eventManagement.filterByStatus('draft'); console.log(`Found ${draftEvents.length} draft events`); // Test sorting await eventManagement.sortEvents('date', 'desc'); const sortedEvents = await eventManagement.getEventsList(); expect(sortedEvents.length).toBeGreaterThan(0); console.log('โœ… Filtering and search test passed'); }, { category: 'event-operations', priority: 'medium', tags: ['agent-b', 'filtering', 'search'] } ); BaseTest.create( 'should export events data', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event export functionality'); await baseTest.authenticateAs(page, 'trainer'); const eventManagement = new EventManagement(page); // Navigate to management dashboard await eventManagement.navigate(); // Test export functionality const exportResult = await eventManagement.exportEvents('csv'); expect(exportResult.initiated).toBe(true); expect(exportResult.format).toBe('csv'); console.log('โœ… Event export test passed'); }, { category: 'event-operations', priority: 'low', tags: ['agent-b', 'export', 'data-management'] } ); }); // Test Suite 4: Advanced Event Features BaseTest.describe('Advanced Event Features', () => { BaseTest.create( 'should handle multi-day event creation and management', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing multi-day event features'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Create multi-day event await eventCreation.navigate(); const createResult = await eventCreation.createTestEvent('multiDay', { data: TEST_DATA.testEvents.multiDay }); expect(createResult.success).toBe(true); // Verify multi-day event in management await eventManagement.navigate(); const events = await eventManagement.getEventsList(); const multiDayEvent = events.find(event => event.title.includes(createResult.eventData.title.substring(0, 20)) ); expect(multiDayEvent).toBeDefined(); console.log('โœ… Multi-day event test passed'); }, { category: 'advanced-features', priority: 'medium', tags: ['agent-b', 'multi-day', 'advanced'] } ); BaseTest.create( 'should validate event capacity and attendance management', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event capacity and attendance'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Create event with specific capacity await eventCreation.navigate(); const capacityEventData = { ...TEST_DATA.testEvents.basic, title: `AgentB-Capacity-Test-${Date.now()}`, capacity: '5' // Small capacity for testing }; const createResult = await eventCreation.createTestEvent('basic', { data: capacityEventData }); expect(createResult.success).toBe(true); // Navigate to edit and check attendee management await eventManagement.navigate(); await eventManagement.editEvent(createResult.eventData.title); // Get attendee information const attendeeInfo = await eventEditing.getAttendeeInfo(); expect(attendeeInfo.count).toBeGreaterThanOrEqual(0); // Verify capacity validation await eventEditing.updateEventFields({ capacity: '10' }); const updateResult = await eventEditing.updateEvent(); expect(updateResult.success).toBe(true); console.log('โœ… Capacity and attendance test passed'); }, { category: 'advanced-features', priority: 'high', tags: ['agent-b', 'capacity', 'attendance'] } ); BaseTest.create( 'should handle event duplication and templating', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event duplication'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventManagement = new EventManagement(page); // Create template event await eventCreation.navigate(); const templateData = { ...TEST_DATA.testEvents.advanced, title: `AgentB-Template-${Date.now()}` }; const createResult = await eventCreation.createTestEvent('basic', { data: templateData }); expect(createResult.success).toBe(true); // Navigate to management and duplicate await eventManagement.navigate(); // Duplicate the event const duplicateResult = await eventManagement.duplicateEvent( createResult.eventData.title ); expect(duplicateResult.success).toBe(true); // Verify duplicate exists in list const updatedEvents = await eventManagement.getEventsList(); const duplicateCount = updatedEvents.filter(event => event.title.toLowerCase().includes('template') ).length; expect(duplicateCount).toBeGreaterThanOrEqual(1); console.log('โœ… Event duplication test passed'); }, { category: 'advanced-features', priority: 'medium', tags: ['agent-b', 'duplication', 'templating'] } ); }); // Test Suite 5: Event Analytics and Reporting BaseTest.describe('Event Analytics and Reporting', () => { BaseTest.create( 'should access event summary and analytics', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing event analytics'); await baseTest.authenticateAs(page, 'trainer'); const eventManagement = new EventManagement(page); const trainerDashboard = new TrainerDashboard(page); // Navigate to dashboard and get stats await trainerDashboard.navigate(); const dashboardStats = await trainerDashboard.getDashboardStats(); // Navigate to event management await eventManagement.navigate(); const managementMetrics = await eventManagement.getManagementMetrics(); // Verify metrics are available expect(managementMetrics.totalEvents).toBeGreaterThanOrEqual(0); expect(typeof managementMetrics.eventsByStatus).toBe('object'); console.log('๐Ÿ“Š Dashboard stats:', dashboardStats); console.log('๐Ÿ“Š Management metrics:', managementMetrics); console.log('โœ… Event analytics test passed'); }, { category: 'analytics', priority: 'medium', tags: ['agent-b', 'analytics', 'reporting'] } ); }); // Test Suite 6: Error Handling and Edge Cases BaseTest.describe('Error Handling and Edge Cases', () => { BaseTest.create( 'should handle form validation errors gracefully', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing form validation handling'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); // Navigate to creation form await eventCreation.navigate(); // Test validation by submitting empty form const validationErrors = await eventCreation.testValidation(); expect(Object.keys(validationErrors).length).toBeGreaterThan(0); // Test with invalid data await eventCreation.fillEventForm({ title: '', // Empty title should trigger validation startDate: 'invalid-date', capacity: '-5' // Negative capacity }); const submitResult = await eventCreation.submitEvent({ expectedOutcome: 'error', waitForRedirect: false }); expect(submitResult.success).toBe(false); console.log('โœ… Form validation test passed'); }, { category: 'error-handling', priority: 'high', tags: ['agent-b', 'validation', 'error-handling'] } ); BaseTest.create( 'should handle concurrent editing scenarios', async (page, testInfo, baseTest) => { console.log('๐Ÿงช Testing concurrent editing scenarios'); await baseTest.authenticateAs(page, 'trainer'); const eventCreation = new EventCreation(page); const eventEditing = new EventEditing(page); const eventManagement = new EventManagement(page); // Create test event await eventCreation.navigate(); const createResult = await eventCreation.createTestEvent('basic', { data: { ...TEST_DATA.testEvents.basic, title: `AgentB-Concurrent-${Date.now()}` } }); expect(createResult.success).toBe(true); // Navigate to edit await eventManagement.navigate(); await eventManagement.editEvent(createResult.eventData.title); // Test version control if available const versionHistory = await eventEditing.getVersionHistory(); console.log('Version history:', versionHistory); // Make concurrent-style update await eventEditing.updateEventFields({ description: 'Updated for concurrent testing' }); const updateResult = await eventEditing.updateEvent(); expect(updateResult.success).toBe(true); console.log('โœ… Concurrent editing test passed'); }, { category: 'error-handling', priority: 'medium', tags: ['agent-b', 'concurrent', 'edge-cases'] } ); }); }); // Test cleanup helper BaseTest.describe('Test Cleanup - Agent B', () => { BaseTest.create( 'should clean up Agent B test events', async (page, testInfo, baseTest) => { console.log('๐Ÿงน Cleaning up Agent B test events'); await baseTest.authenticateAs(page, 'trainer'); const eventManagement = new EventManagement(page); // Navigate to management dashboard await eventManagement.navigate(); // Search for Agent B test events const testEvents = await eventManagement.searchEvents('AgentB'); // Delete test events (with confirmation) let deletedCount = 0; for (const event of testEvents) { if (event.title.includes('AgentB')) { try { await eventManagement.deleteEvent(event.title, true); deletedCount++; } catch (error) { console.warn(`Could not delete event: ${event.title}`, error.message); } } } console.log(`๐Ÿ—‘๏ธ Cleaned up ${deletedCount} test events`); }, { category: 'cleanup', priority: 'low', tags: ['agent-b', 'cleanup', 'maintenance'] } ); });