This commit is contained in:
2025-11-30 23:00:48 +01:00
parent 4b8c70978f
commit 645f537895
41 changed files with 738 additions and 1631 deletions

View File

@@ -43,7 +43,7 @@ describe('Workflow hosted session end-to-end (fixture-backed)', () => {
return { repository, engine, useCase };
}
it('runs 118 from use case to STOPPED_AT_STEP_18', async () => {
it('runs 117 from use case and stops automation at manual Track Conditions (STOPPED_AT_STEP_18)', async () => {
const { repository, engine, useCase } = createFixtureEngine();
const config: any = {
@@ -64,13 +64,13 @@ describe('Workflow hosted session end-to-end (fixture-backed)', () => {
// Poll repository until automation loop completes
// MockAutomationEngineAdapter drives the step orchestrator internally.
// Session should end in STOPPED_AT_STEP_18 when step 18 completes.
// Session should end in STOPPED_AT_STEP_18 after completing automated step 17.
// eslint-disable-next-line no-constant-condition
while (true) {
const sessions = await repository.findAll();
finalSession = sessions[0] ?? null;
if (finalSession && (finalSession.state.isStoppedAtStep18() || finalSession.state.isFailed())) {
if (finalSession && finalSession.state.isStoppedAtStep18()) {
break;
}
@@ -83,7 +83,7 @@ describe('Workflow hosted session end-to-end (fixture-backed)', () => {
expect(finalSession).not.toBeNull();
expect(finalSession!.state.isStoppedAtStep18()).toBe(true);
expect(finalSession!.currentStep.value).toBe(18);
expect(finalSession!.currentStep.value).toBe(17);
expect(finalSession!.startedAt).toBeInstanceOf(Date);
expect(finalSession!.completedAt).toBeInstanceOf(Date);
expect(finalSession!.errorMessage).toBeUndefined();
@@ -129,7 +129,7 @@ describe('Workflow hosted session end-to-end (fixture-backed)', () => {
const sessions = await repository.findAll();
finalSession = sessions[0] ?? null;
if (finalSession && (finalSession.state.isFailed() || finalSession.state.isStoppedAtStep18())) {
if (finalSession && finalSession.state.isFailed()) {
break;
}
@@ -143,11 +143,7 @@ describe('Workflow hosted session end-to-end (fixture-backed)', () => {
await failingAdapter.disconnect();
expect(finalSession).not.toBeNull();
expect(
finalSession!.state.isFailed() || finalSession!.state.isStoppedAtStep18(),
).toBe(true);
if (finalSession!.state.isFailed()) {
expect(finalSession!.errorMessage).toBeDefined();
}
expect(finalSession!.state.isFailed()).toBe(true);
expect(finalSession!.errorMessage).toBeDefined();
});
});

View File

@@ -1,6 +1,10 @@
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { PlaywrightAutomationAdapter, FixtureServer } from 'packages/infrastructure/adapters/automation';
import {
PlaywrightAutomationAdapter,
FixtureServer,
} from 'packages/infrastructure/adapters/automation';
import { StepId } from 'packages/domain/value-objects/StepId';
import { IRACING_SELECTORS } from 'packages/infrastructure/adapters/automation/dom/IRacingSelectors';
describe('Workflow steps 79 cars flow (fixture-backed)', () => {
let adapter: PlaywrightAutomationAdapter;
@@ -18,7 +22,7 @@ describe('Workflow steps 79 cars flow (fixture-backed)', () => {
timeout: 5000,
baseUrl,
mode: 'mock',
}
},
);
await adapter.connect();
});
@@ -28,7 +32,7 @@ describe('Workflow steps 79 cars flow (fixture-backed)', () => {
await server.stop();
});
it('executes time limits, cars, and add car in sequence using fixtures', async () => {
it('executes time limits, cars, and add car in sequence using fixtures and leaves JSON-backed state', async () => {
await adapter.navigateToPage(server.getFixtureUrl(7));
const step7Result = await adapter.executeStep(StepId.create(7), {
practice: 10,
@@ -37,14 +41,43 @@ describe('Workflow steps 79 cars flow (fixture-backed)', () => {
});
expect(step7Result.success).toBe(true);
const page = adapter.getPage();
expect(page).not.toBeNull();
const raceSlider = page!
.locator(IRACING_SELECTORS.steps.race)
.first();
const raceSliderValue =
(await raceSlider.getAttribute('data-value')) ??
(await raceSlider.inputValue().catch(() => null));
expect(raceSliderValue).toBe('20');
await adapter.navigateToPage(server.getFixtureUrl(8));
const step8Result = await adapter.executeStep(StepId.create(8), {});
expect(step8Result.success).toBe(true);
const carsContainer = page!
.locator(IRACING_SELECTORS.wizard.stepContainers.cars)
.first();
expect(await carsContainer.count()).toBeGreaterThan(0);
const addCarButton = page!
.locator(IRACING_SELECTORS.steps.addCarButton)
.first();
expect(await addCarButton.count()).toBeGreaterThan(0);
await adapter.navigateToPage(server.getFixtureUrl(9));
const step9Result = await adapter.executeStep(StepId.create(9), {
carSearch: 'Porsche 911 GT3 R',
carSearch: 'Acura ARX-06',
});
expect(step9Result.success).toBe(true);
const carsTable = page!
.locator('#select-car-set-cars table.table.table-striped')
.first();
expect(await carsTable.count()).toBeGreaterThan(0);
const acuraCell = carsTable.locator('tbody tr td >> text=Acura ARX-06 GTP');
expect(await acuraCell.count()).toBeGreaterThan(0);
});
});