import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { PlaywrightAutomationAdapter } from '../../packages/infrastructure/adapters/automation/PlaywrightAutomationAdapter'; import { StepId } from '../../packages/domain/value-objects/StepId'; import path from 'path'; /** * E2E tests for Steps 7-9 alignment fix. * * Tests verify that: * - Step 7 correctly handles Time Limits wizard step (#set-time-limit) * - Step 8 correctly handles Set Cars wizard step (#set-cars) * - Step 9 correctly handles Add Car modal (not a wizard step) * * These tests MUST FAIL initially to demonstrate the off-by-one error. */ describe('Steps 7-9 Alignment Fix (E2E)', () => { let adapter: PlaywrightAutomationAdapter; const fixtureBaseUrl = `file://${path.resolve(process.cwd(), 'html-dumps')}`; beforeAll(async () => { adapter = new PlaywrightAutomationAdapter({ headless: true, timeout: 5000, baseUrl: fixtureBaseUrl, mode: 'mock', }); await adapter.connect(); }); afterAll(async () => { await adapter.disconnect(); }); describe('RED Phase - These tests MUST fail initially', () => { it('Step 7 should wait for #set-time-limit wizard step', async () => { // Navigate to Step 7 fixture await adapter.navigateToPage(`${fixtureBaseUrl}/step-07-time-limits.html`); const page = adapter.getPage(); expect(page).not.toBeNull(); // Verify we're on the correct page BEFORE execution const stepIndicatorBefore = await page!.textContent('[data-indicator]'); expect(stepIndicatorBefore).toContain('Time Limits'); // Execute Step 7 with time limit config const result = await adapter.executeStep( StepId.create(7), { practice: 10, qualify: 10, race: 20, } ); // Should succeed expect(result.success).toBe(true); expect(result.error).toBeUndefined(); // After execution, we should have navigated to Step 8 (Set Cars) // This is the expected behavior - executeStep() clicks "Next" at the end const stepIndicatorAfter = await page!.textContent('[data-indicator]'); expect(stepIndicatorAfter).toContain('Set Cars'); }); it('Step 8 should wait for #set-cars wizard step', async () => { // Navigate to Step 8 fixture (Set Cars) await adapter.navigateToPage(`${fixtureBaseUrl}/step-08-set-cars.html`); const page = adapter.getPage(); expect(page).not.toBeNull(); // Verify we're on the correct page BEFORE execution const stepIndicatorBefore = await page!.textContent('[data-indicator]'); expect(stepIndicatorBefore).toContain('Set Cars'); // Execute Step 8 - should just wait for #set-cars and click next const result = await adapter.executeStep( StepId.create(8), {} ); // Should succeed expect(result.success).toBe(true); expect(result.error).toBeUndefined(); // Note: After Step 8, we'd normally navigate to Track, but that fixture doesn't exist yet // So we just verify Step 8 executed successfully }); it('Step 9 should handle Add Car modal correctly', async () => { // Navigate to Step 9 fixture (Add Car modal) await adapter.navigateToPage(`${fixtureBaseUrl}/step-09-add-car.html`); const page = adapter.getPage(); expect(page).not.toBeNull(); // Verify we're on the Add Car modal page const modalTitleBefore = await page!.textContent('[data-indicator="add-car"]'); expect(modalTitleBefore).toContain('Add a Car'); // Execute Step 9 with car search const result = await adapter.executeStep( StepId.create(9), { carSearch: 'Porsche 911 GT3 R', } ); // Should succeed expect(result.success).toBe(true); expect(result.error).toBeUndefined(); // Step 9 is a modal-only step - it doesn't navigate to another page // It just handles the car addition modal, so we verify it completed successfully }); }); describe('Integration - Full Steps 7-9 flow', () => { it('should execute Steps 7-9 in correct sequence', async () => { // Step 7: Time Limits await adapter.navigateToPage(`${fixtureBaseUrl}/step-07-time-limits.html`); const step7Result = await adapter.executeStep(StepId.create(7), { practice: 10, qualify: 10, race: 20, }); expect(step7Result.success).toBe(true); // Step 8: Set Cars await adapter.navigateToPage(`${fixtureBaseUrl}/step-08-set-cars.html`); const step8Result = await adapter.executeStep(StepId.create(8), {}); expect(step8Result.success).toBe(true); // Step 9: Add Car modal await adapter.navigateToPage(`${fixtureBaseUrl}/step-09-add-car.html`); const step9Result = await adapter.executeStep(StepId.create(9), { carSearch: 'Porsche 911 GT3 R', }); expect(step9Result.success).toBe(true); }); }); });