import { STAGING_URL, PATHS, TIMEOUTS } from './config/staging-config'; import { test, expect, Page } from '@playwright/test'; import * as dotenv from 'dotenv'; import { resolve } from 'path'; dotenv.config({ path: resolve(__dirname, '../../../../.env') }); test.use({ screenshot: 'only-on-failure', video: 'retain-on-failure', trace: 'retain-on-failure', actionTimeout: 30000, timeout: 120000, // 2 minutes per test }); test.describe('Event Creation with Cache Disabled', () => { const stagingUrl = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com'; test('creates event with cache disabled', async ({ page }) => { const username = 'test_trainer'; const password = 'Test123!'; // Step 1: Login with cache disabled (using no_cache_test query param) await page.goto(stagingUrl + '/community-login/?no_cache_test=1', { waitUntil: 'domcontentloaded' }); await page.fill('input#user_login', username); await page.fill('input#user_pass', password); await page.getByRole('button', { name: /log in/i }).click(); // Wait for login to complete await page.waitForURL(/hvac-dashboard|manage-event/, { timeout: 30000 }); // Step 2: Navigate directly to event creation (cache disabled for /manage-event/) await page.goto(stagingUrl + '/manage-event/?no_cache_test=1', { waitUntil: 'domcontentloaded' }); await page.waitForSelector('input[name="post_title"]', { state: 'visible' }); // Step 3: Fill form fields const now = new Date(); const uniqueTitle = `HVAC Training ${now.toISOString().split('.')[0].replace(/[-T:]/g, '')}`; await page.fill('input[name="post_title"]', uniqueTitle); // Set dates const eventDate = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); const dateStr = eventDate.toISOString().split('T')[0]; await page.fill('input[name="EventStartDate"]', dateStr); await page.fill('input[name="EventEndDate"]', dateStr); await page.fill('input[name="EventStartTime"]', '09:00'); await page.fill('input[name="EventEndTime"]', '17:00'); // Set venue if fields exist const venueFieldExists = await page.locator('input[name="venue[Venue]"]').isVisible().catch(() => false); if (venueFieldExists) { await page.fill('input[name="venue[Venue]"]', 'New Test Venue'); await page.fill('input[name="venue[Address]"]', '789 Test St'); await page.fill('input[name="venue[City]"]', 'Test City'); await page.fill('input[name="venue[Province]"]', 'BC'); await page.fill('input[name="venue[Country]"]', 'Canada'); await page.fill('input[name="venue[Zip]"]', 'V1X 1X1'); } // Step 4: Handle description field with proper naming const descriptionText = `This is a test event created on ${now.toISOString()}. This event covers HVAC training basics.`; // Try multiple approaches to ensure the description is set // 1. Fill the textarea directly try { await page.fill('textarea[name="tcepostcontent"]', descriptionText); } catch (e) { console.log('Direct textarea fill failed:', e.message); } // 2. Handle TinyMCE editor if present try { const iframe = page.frameLocator('iframe#tcepostcontent_ifr'); const iframeBody = iframe.locator('body'); await iframeBody.click(); await iframeBody.fill(descriptionText); } catch (e) { console.log('TinyMCE iframe approach failed:', e.message); } // 3. Use JavaScript to set both tcepostcontent and post_content await page.evaluate((content) => { // Set the visible textarea const textarea = document.querySelector('textarea[name="tcepostcontent"]') as HTMLTextAreaElement; if (textarea) { textarea.value = content; textarea.dispatchEvent(new Event('change', { bubbles: true })); } // Create a hidden field for post_content if it doesn't exist let postContentField = document.querySelector('input[name="post_content"], textarea[name="post_content"]') as HTMLInputElement; if (!postContentField) { postContentField = document.createElement('input'); postContentField.type = 'hidden'; postContentField.name = 'post_content'; const form = document.querySelector('form'); if (form) { form.appendChild(postContentField); } } postContentField.value = content; // Also try TinyMCE API if available if ((window as any).tinymce) { const editor = (window as any).tinymce.get('tcepostcontent'); if (editor) { editor.setContent(content); } } }, descriptionText); // Set additional fields if they exist const organizerFieldExists = await page.locator('select[name="EventOrganizerID"]').isVisible().catch(() => false); if (organizerFieldExists) { await page.selectOption('select[name="EventOrganizerID"]', { index: 1 }); } const ticketFieldExists = await page.locator('input[name="ticket_price"]').isVisible().catch(() => false); if (ticketFieldExists) { await page.fill('input[name="ticket_price"]', '100'); await page.fill('input[name="ticket_quantity"]', '20'); } // Take screenshot before submission await page.screenshot({ path: 'before-submission-no-cache.png', fullPage: true }); // Step 5: Submit form with both field names await page.evaluate(() => { // Ensure both field names have the content const tceContent = (document.querySelector('textarea[name="tcepostcontent"]') as HTMLTextAreaElement)?.value; const postContentField = document.querySelector('input[name="post_content"], textarea[name="post_content"]') as HTMLInputElement; if (tceContent && postContentField) { postContentField.value = tceContent; } }); // Submit the form await page.click('input[type="submit"][value="Submit Event"]'); await page.waitForLoadState('networkidle'); // Check for success or error const pageContent = await page.content(); const errorExists = await page.locator('.tribe-notice-error, .error-message').isVisible().catch(() => false); if (errorExists) { await page.screenshot({ path: 'submission-error-no-cache.png', fullPage: true }); const errorText = await page.locator('.tribe-notice-error, .error-message').textContent(); console.error('Submission error:', errorText); // Additional debugging const formData = await page.evaluate(() => { const form = document.querySelector('form'); if (!form) return {}; const data: Record = {}; const formData = new FormData(form); formData.forEach((value, key) => { data[key] = value.toString(); }); return data; }); console.log('Form data:', formData); } // Verify success if (pageContent.includes(uniqueTitle) || pageContent.includes('Event submitted') || pageContent.includes('successfully created')) { console.log('Event created successfully!'); } else { console.log('Event creation may have failed - checking for any indication of success...'); // Check if we were redirected to the event page const currentUrl = page.url(); if (currentUrl.includes('/events/') || currentUrl.includes('event=')) { console.log('Redirected to event page - likely successful'); } else { throw new Error('Event creation failed'); } } }); });