import { chromium, type Browser, type Page, type BrowserContext } from 'playwright-core'; import { e2eConfig } from '../playwright.config'; import { afterAll, beforeAll, beforeEach, afterEach } from 'vitest'; import { execSync } from 'child_process'; let browser: Browser; let context: BrowserContext; let page: Page; /** * Find the Chromium executable installed by Playwright. */ function findChromium(): string { // Check standard Playwright cache locations const cacheDir = process.env.PLAYWRIGHT_BROWSERS_PATH || `${process.env.HOME}/Library/Caches/ms-playwright`; try { const result = execSync( `find "${cacheDir}" -name "headless_shell" -type f 2>/dev/null | head -1`, { encoding: 'utf-8' } ).trim(); if (result) return result; } catch {} try { const result = execSync( `find "${cacheDir}" -name "chromium" -type f -not -path "*/node_modules/*" 2>/dev/null | head -1`, { encoding: 'utf-8' } ).trim(); if (result) return result; } catch {} // Fall back to system Chrome const systemChrome = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; return systemChrome; } export function setupBrowser() { beforeAll(async () => { const executablePath = findChromium(); browser = await chromium.launch({ executablePath, headless: true, }); }); beforeEach(async () => { context = await browser.newContext({ viewport: e2eConfig.viewport, colorScheme: e2eConfig.colorScheme, baseURL: e2eConfig.baseURL, }); page = await context.newPage(); }); afterEach(async () => { await context?.close(); }); afterAll(async () => { await browser?.close(); }); return { getPage: () => page, getContext: () => context, getBrowser: () => browser, }; }