- Add comprehensive trainer journey test implementation - Cover login, dashboard access, event creation, modification, and deletion - Fix TinyMCE editor interaction issues - Handle venue and organizer form fields - Add proper waits and error handling - Update documentation with test findings - Document event persistence issues in staging Test Status: All trainer journey steps (1-5) are now passing Key Finding: Events persist to My Events page but not main dashboard Co-authored-by: Ben Reed <ben@tealmaker.com>
		
			
				
	
	
		
			95 lines
		
	
	
		
			No EOL
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			No EOL
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Page } from '@playwright/test';
 | |
| import { BasePage } from './BasePage';
 | |
| 
 | |
| export class CreateEventPage extends BasePage {
 | |
|     private readonly eventTitleField = 'input[name="post_title"]';
 | |
|     private readonly eventDescriptionField = '#tcepostcontent';
 | |
|     private readonly startDateField = 'input[name="EventStartDate"]';
 | |
|     private readonly startTimeField = 'input[name="EventStartTime"]';
 | |
|     private readonly endDateField = 'input[name="EventEndDate"]';
 | |
|     private readonly endTimeField = 'input[name="EventEndTime"]';
 | |
|     private readonly venueSelector = 'select#saved_tribe_venue';
 | |
|     private readonly organizerSelector = 'select#saved_tribe_organizer';
 | |
|     private readonly submitButton = 'input[name="community-event"][value="Submit Event"], button:has-text("Submit Event"), input[value="Submit Event"]';
 | |
|     private readonly returnToDashboardLink = 'a:has-text("Return to Dashboard")';
 | |
|     
 | |
|     constructor(page: Page) {
 | |
|         super(page);
 | |
|     }
 | |
|     
 | |
|     async navigateToCreateEvent(): Promise<void> {
 | |
|         await this.navigateTo('/manage-event/');
 | |
|     }
 | |
|     
 | |
|     async fillEventDetails(eventData: {
 | |
|         title: string;
 | |
|         description: string;
 | |
|         startDate: string;
 | |
|         startTime: string;
 | |
|         endDate: string;
 | |
|         endTime: string;
 | |
|         venue?: string;
 | |
|         organizer?: string;
 | |
|     }): Promise<void> {
 | |
|         await this.fill(this.eventTitleField, eventData.title);
 | |
|         
 | |
|         // Always try TinyMCE iframe - the textarea is hidden when TinyMCE is active
 | |
|         try {
 | |
|             const frame = this.page.frameLocator('iframe[id$="_ifr"]');
 | |
|             await frame.locator('body').fill(eventData.description);
 | |
|         } catch (e) {
 | |
|             // Fallback to JavaScript injection
 | |
|             try {
 | |
|                 await this.page.evaluate((desc) => {
 | |
|                     const editor = (window as any).tinyMCE?.activeEditor;
 | |
|                     if (editor) {
 | |
|                         editor.setContent(desc);
 | |
|                     }
 | |
|                 }, eventData.description);
 | |
|             } catch (e2) {
 | |
|                 // Last resort - try the textarea directly
 | |
|                 await this.fill(this.eventDescriptionField, eventData.description);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         await this.fill(this.startDateField, eventData.startDate);
 | |
|         await this.fill(this.startTimeField, eventData.startTime);
 | |
|         await this.fill(this.endDateField, eventData.endDate);
 | |
|         await this.fill(this.endTimeField, eventData.endTime);
 | |
|         
 | |
|         if (eventData.venue) {
 | |
|             await this.page.selectOption(this.venueSelector, eventData.venue);
 | |
|         }
 | |
|         
 | |
|         if (eventData.organizer) {
 | |
|             await this.page.selectOption(this.organizerSelector, eventData.organizer);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     async submitEvent(): Promise<void> {
 | |
|         // Ensure all fields are filled before submitting
 | |
|         await this.page.waitForTimeout(1000);
 | |
|         
 | |
|         // Click the submit button
 | |
|         const submitVisible = await this.page.locator(this.submitButton).isVisible();
 | |
|         console.log('Submit button visible:', submitVisible);
 | |
|         
 | |
|         await this.click(this.submitButton);
 | |
|         
 | |
|         // Wait for navigation or form update
 | |
|         await Promise.race([
 | |
|             this.waitForNavigation(),
 | |
|             this.page.waitForTimeout(5000)
 | |
|         ]);
 | |
|     }
 | |
|     
 | |
|     async returnToDashboard(): Promise<void> {
 | |
|         await this.click(this.returnToDashboardLink);
 | |
|         await this.waitForNavigation();
 | |
|     }
 | |
|     
 | |
|     async isFormVisible(): Promise<boolean> {
 | |
|         return await this.isVisible(this.eventTitleField) && 
 | |
|                await this.isVisible(this.startDateField);
 | |
|     }
 | |
| } |