/** * Integration tests for FixtureServer and PlaywrightAutomationAdapter wiring. */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { FixtureServer, getAllStepFixtureMappings, PlaywrightAutomationAdapter } from 'packages/automation/infrastructure/adapters/automation'; declare const getComputedStyle: any; declare const document: any; describe('FixtureServer integration', () => { let server: FixtureServer; let adapter: PlaywrightAutomationAdapter; let baseUrl: string; beforeAll(async () => { server = new FixtureServer(); const serverInfo = await server.start(); baseUrl = serverInfo.url; adapter = new PlaywrightAutomationAdapter({ headless: true, timeout: 5000, baseUrl, }); const connectResult = await adapter.connect(); expect(connectResult.success).toBe(true); }); afterAll(async () => { await adapter.disconnect(); await server.stop(); }); describe('FixtureServer', () => { it('reports running state after start', () => { expect(server.isRunning()).toBe(true); }); it('exposes mappings for steps 1 through 18', () => { const mappings = getAllStepFixtureMappings(); const stepNumbers = Object.keys(mappings).map(Number).sort((a, b) => a - b); expect(stepNumbers[0]).toBe(1); expect(stepNumbers[stepNumbers.length - 1]).toBe(18); expect(stepNumbers).toHaveLength(18); }); it('serves all mapped fixtures over HTTP', async () => { const mappings = getAllStepFixtureMappings(); const stepNumbers = Object.keys(mappings).map(Number); for (const stepNumber of stepNumbers) { const url = server.getFixtureUrl(stepNumber); const result = await adapter.navigateToPage(url); expect(result.success).toBe(true); } }); it('serves CSS assets for a step fixture', async () => { const page = adapter.getPage(); expect(page).not.toBeNull(); await adapter.navigateToPage(server.getFixtureUrl(2)); const cssLoaded = await page!.evaluate(() => { const styles = getComputedStyle(document.body); return styles.backgroundColor !== ''; }); expect(cssLoaded).toBe(true); }); it('returns 404 for non-existent files', async () => { const page = adapter.getPage(); expect(page).not.toBeNull(); const response = await page!.goto(`${baseUrl}/non-existent-file.html`); expect(response?.status()).toBe(404); }); }); describe('Error handling', () => { it('returns error when browser is not connected', async () => { const disconnectedAdapter = new PlaywrightAutomationAdapter({ headless: true, timeout: 1000, }); const navResult = await disconnectedAdapter.navigateToPage('http://localhost:9999'); expect(navResult.success).toBe(false); expect(navResult.error).toBe('Browser not connected'); const fillResult = await disconnectedAdapter.fillFormField('test', 'value'); expect(fillResult.success).toBe(false); expect(fillResult.error).toBe('Browser not connected'); const clickResult = await disconnectedAdapter.clickElement('test'); expect(clickResult.success).toBe(false); expect(clickResult.error).toBe('Browser not connected'); }); it('reports connected state correctly', async () => { expect(adapter.isConnected()).toBe(true); const newAdapter = new PlaywrightAutomationAdapter({ headless: true }); expect(newAdapter.isConnected()).toBe(false); await newAdapter.connect(); expect(newAdapter.isConnected()).toBe(true); await newAdapter.disconnect(); expect(newAdapter.isConnected()).toBe(false); }); }); });