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 Field Mapping Fix', () => { const stagingUrl = process.env.UPSKILL_STAGING_URL || 'https://upskill-staging.measurequick.com'; test('creates event with our description field fix', async ({ page }) => { const username = 'test_trainer'; const password = 'Test123!'; // Step 1: Login await page.goto(stagingUrl + '/community-login/', { 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 to event creation await page.goto(stagingUrl + '/manage-event/', { waitUntil: 'domcontentloaded' }); await page.waitForSelector('input[name="post_title"]', { state: 'visible' }); // Step 3: Fill form fields const now = new Date(); const uniqueTitle = `HVAC Training Fixed ${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'); // Step 4: Handle description field - our form handler should map it correctly const descriptionText = `This is a test event created on ${now.toISOString()}. This event covers HVAC training basics.`; // Fill the textarea directly - our handler should map tcepostcontent to post_content try { await page.fill('textarea[name="tcepostcontent"]', descriptionText); } catch (e) { console.log('Direct textarea fill failed:', e.message); } // 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); } // Take screenshot before submission await page.screenshot({ path: 'before-submission-with-fix.png', fullPage: true }); // Step 5: 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-with-fix.png', fullPage: true }); const errorText = await page.locator('.tribe-notice-error, .error-message').textContent(); console.error('Submission error:', errorText); // If we still get description error, our fix needs adjustment if (errorText?.includes('Event Description is required')) { throw new Error('Our field mapping fix did not work - description still required'); } } // Verify success const currentUrl = page.url(); console.log('Current URL after submission:', currentUrl); if (pageContent.includes(uniqueTitle) || pageContent.includes('Event submitted') || pageContent.includes('successfully created') || currentUrl.includes('/events/') || currentUrl.includes('event=')) { console.log('Event created successfully with our fix!'); } else { throw new Error('Event creation may have failed'); } }); });