/** * Cucumber hooks for EuchreCamp E2E tests */ import { Before, After, BeforeAll, AfterAll, IWorldOptions, World } from '@cucumber/cucumber'; import { chromium, Browser, type FullConfig } from '@playwright/test'; import { cleanupAllTestData } from '@/__tests__/test-utils'; import { world } from './world'; import path from 'path'; import fs from 'fs'; // Global browser instance let browser: Browser; // Load environment files const envPath = path.resolve(process.cwd(), '.env'); const envDevPath = path.resolve(process.cwd(), '.env.development'); if (fs.existsSync(envPath)) { require('dotenv').config({ path: envPath }); } if (fs.existsSync(envDevPath)) { require('dotenv').config({ path: envDevPath, override: true }); } /** * Before all scenarios: Launch browser */ BeforeAll(async function () { console.log('🌍 Launching browser for Cucumber tests...'); browser = await chromium.launch(); }); /** * After all scenarios: Close browser and cleanup */ AfterAll(async function () { console.log('🌍 Closing browser...'); await browser.close(); console.log('🌍 Disconnecting from database...'); if (world.prisma) { await world.prisma.$disconnect(); } }); /** * Before each scenario: Create new page context */ Before(async function (this: World) { // Create new context and page world.context = await browser.newContext(); world.page = await world.context.newPage(); // Log console messages for debugging world.page.on('console', msg => { if (msg.type() === 'error') { console.log('❌ PAGE ERROR:', msg.text()); } }); // Log network errors world.page.on('requestfailed', request => { console.log('❌ REQUEST FAILED:', request.url()); }); console.log('🌍 Created new page context'); }); /** * After each scenario: Close page and cleanup test data */ After(async function (this: World) { console.log('🌍 Cleaning up after scenario...'); // Close page and context if (world.page) { await world.page.close(); } if (world.context) { await world.context.close(); } // Clean up test data try { await cleanupAllTestData(); console.log('🌍 Test data cleaned up'); } catch (error) { console.error('🌍 Error cleaning up test data:', error); } }); /** * Custom hook for navigating to a page */ Before({ tags: '@navigation' }, async function (this: World) { console.log('🌍 Navigation hook triggered'); }); /** * Custom hook for authenticated scenarios */ Before({ tags: '@authenticated' }, async function (this: World) { console.log('🌍 Authenticated hook triggered'); // This hook can be extended to load saved auth state }); /** * Tag hooks for specific scenarios */ Before({ tags: '@slow' }, async function (this: World) { console.log('🌍 Slow test - extending timeout'); // Note: Timeout extension happens at step definition level }); Before({ tags: '@flaky' }, async function (this: World) { console.log('🌍 Flaky test - retry enabled'); });