rename to core
This commit is contained in:
+134
-134
@@ -38,10 +38,10 @@ Everything else from the concept docs (league/season management, result aggregat
|
||||
- React renderer: [`App`](apps/companion/renderer/App.tsx), UI components under [`components`](apps/companion/renderer/components).
|
||||
|
||||
- Automation & browser integration:
|
||||
- Domain models around hosted sessions and steps, e.g. [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Application layer ports and use-cases, e.g. [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1), [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1), [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Playwright-based automation adapter and helpers, e.g. [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1), [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1).
|
||||
- Logging, config and in-memory repository implementations, e.g. [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1), [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1), [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1), [`PinoLogAdapter`](packages/infrastructure/adapters/logging/PinoLogAdapter.ts:1).
|
||||
- Domain models around hosted sessions and steps, e.g. [`AutomationSession`](core/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Application layer ports and use-cases, e.g. [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1), [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1), [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Playwright-based automation adapter and helpers, e.g. [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1), [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1).
|
||||
- Logging, config and in-memory repository implementations, e.g. [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1), [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1), [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1), [`PinoLogAdapter`](core/infrastructure/adapters/logging/PinoLogAdapter.ts:1).
|
||||
|
||||
- Testing:
|
||||
- Unit tests for domain, application and infrastructure.
|
||||
@@ -162,14 +162,14 @@ The website under [`apps/website`](apps/website:1) is the primary presentation s
|
||||
- Read standings, stats snapshots and rating values.
|
||||
- Submit registrations, complaints and admin actions.
|
||||
- Trigger or schedule result imports and (where allowed) automation runs.
|
||||
- These APIs are implemented by the platform application layer and are conceptually separate from the automation-specific ports in `packages/application`.
|
||||
- These APIs are implemented by the platform application layer and are conceptually separate from the automation-specific ports in `core/application`.
|
||||
|
||||
### 2.4 Platform Integration with Automation
|
||||
|
||||
The web platform uses the automation & companion subsystem as a hosted-session engine, without coupling to Playwright or Electron details:
|
||||
|
||||
- **From league/season data to automation intent**
|
||||
- The platform aggregates league configuration (series settings, car/track choices, schedule, server settings) and derives a hosted-session configuration structure conceptually equivalent to [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- The platform aggregates league configuration (series settings, car/track choices, schedule, server settings) and derives a hosted-session configuration structure conceptually equivalent to [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- This configuration captures the intent of a single hosted session (or a batch of sessions across a season) in a platform-neutral format.
|
||||
|
||||
- **Hand-off to automation**
|
||||
@@ -207,9 +207,9 @@ This section describes how the automation engine and companion in this repo sit
|
||||
|
||||
- **Automation Engine & Domain (this repo)**
|
||||
- Clean Architecture core for iRacing hosted-session automation:
|
||||
- Domain and value objects under [`packages/domain`](packages/domain/entities/AutomationSession.ts:1).
|
||||
- Application use-cases and ports under [`packages/application`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Infrastructure adapters under [`packages/infrastructure`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Domain and value objects under [`core/domain`](core/domain/entities/AutomationSession.ts:1).
|
||||
- Application use-cases and ports under [`core/application`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Infrastructure adapters under [`core/infrastructure`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Exposes automation capabilities via application ports that can be used both by the companion and by external orchestrators.
|
||||
|
||||
- **iRacing Web (members.iracing.com)**
|
||||
@@ -228,7 +228,7 @@ This section describes how the automation engine and companion in this repo sit
|
||||
|
||||
- Shared concept space:
|
||||
- Both surfaces operate on the competition concepts described in [`CONCEPT.md`](docs/concept/CONCEPT.md), [`ADMINS.md`](docs/concept/ADMINS.md), [`DRIVERS.md`](docs/concept/DRIVERS.md), [`COMPETITION.md`](docs/concept/COMPETITION.md), [`RACING.md`](docs/concept/RACING.md), [`SOCIAL.md`](docs/concept/SOCIAL.md), [`TEAMS.md`](docs/concept/TEAMS.md).
|
||||
- The automation engine uses [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) as the canonical representation of a hosted-session setup derived from those higher-level concepts.
|
||||
- The automation engine uses [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) as the canonical representation of a hosted-session setup derived from those higher-level concepts.
|
||||
|
||||
- Division of responsibilities:
|
||||
- The **website** is the primary UI for league management, discovery, stats and rating (core platform concerns).
|
||||
@@ -245,7 +245,7 @@ At a high level, communication flows are designed around the automation engine a
|
||||
- Companion App → Application Use-cases → Automation Engine → Playwright Adapter → iRacing Web.
|
||||
|
||||
- Hand-off of automation intent:
|
||||
- Core platform services or the web app can derive a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) from league data and store it server-side.
|
||||
- Core platform services or the web app can derive a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) from league data and store it server-side.
|
||||
- The companion app or a headless orchestrator retrieves these configs via platform APIs and invokes the automation engine using the same application ports used in this repo.
|
||||
|
||||
### 2.4 System context diagram
|
||||
@@ -300,7 +300,7 @@ The automation strategy is shaped by iRacing’s platform boundaries and Terms o
|
||||
- Hooking the sim process or game memory.
|
||||
- Running any automation that is not clearly aligned with “browser automation of a public web UI”.
|
||||
|
||||
The [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) contains additional safeguards, such as:
|
||||
The [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) contains additional safeguards, such as:
|
||||
|
||||
- Guardrails around checkout/payment-like buttons using iRacing-specific selector maps.
|
||||
- Explicit “blocked selector” detection before clicks.
|
||||
@@ -336,7 +336,7 @@ Inner layers:
|
||||
**Layer responsibilities**
|
||||
|
||||
- **Domain**
|
||||
- Competition-neutral automation concepts such as [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1), session and step invariants and validators.
|
||||
- Competition-neutral automation concepts such as [`AutomationSession`](core/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1), session and step invariants and validators.
|
||||
- Independent of Electron, Playwright, HTTP or persistence.
|
||||
|
||||
- **Application**
|
||||
@@ -354,9 +354,9 @@ Inner layers:
|
||||
|
||||
**Key rules in this repo**
|
||||
|
||||
- `packages/domain/*` has no dependencies on application, infrastructure, or Electron.
|
||||
- `packages/application/*` depends only on `packages/domain/*` (plus shared types).
|
||||
- `packages/infrastructure/*` depends on domain and application ports, and on external libraries (Playwright, Pino, etc.).
|
||||
- `core/domain/*` has no dependencies on application, infrastructure, or Electron.
|
||||
- `core/application/*` depends only on `core/domain/*` (plus shared types).
|
||||
- `core/infrastructure/*` depends on domain and application ports, and on external libraries (Playwright, Pino, etc.).
|
||||
- `apps/companion/*` depends on inner layers and glues application use-cases to Electron UI and IPC.
|
||||
|
||||
This keeps the **automation engine** stable and reusable across presentation surfaces (companion today, web or backend orchestrators later), while allowing infrastructure and UI details to evolve without rewriting business logic.
|
||||
@@ -365,19 +365,19 @@ This keeps the **automation engine** stable and reusable across presentation sur
|
||||
|
||||
## 4. Layer-by-Layer Mapping
|
||||
|
||||
### 4.1 Domain Layer (`packages/domain/*`)
|
||||
### 4.1 Domain Layer (`core/domain/*`)
|
||||
|
||||
The domain models what an “automation session” is, how it progresses, and which invariants must hold regardless of UI or tooling.
|
||||
|
||||
**Core entities**
|
||||
|
||||
- [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1)
|
||||
- [`AutomationSession`](core/domain/entities/AutomationSession.ts:1)
|
||||
- Represents a single hosted-session automation run.
|
||||
- Tracks:
|
||||
- `id`
|
||||
- `currentStep` (wizard step, via [`StepId`](packages/domain/value-objects/StepId.ts:1))
|
||||
- `state` (via [`SessionState`](packages/domain/value-objects/SessionState.ts:1))
|
||||
- immutable [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)
|
||||
- `currentStep` (wizard step, via [`StepId`](core/domain/value-objects/StepId.ts:1))
|
||||
- `state` (via [`SessionState`](core/domain/value-objects/SessionState.ts:1))
|
||||
- immutable [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)
|
||||
- timestamps (`startedAt`, `completedAt`)
|
||||
- failure information (`errorMessage`).
|
||||
- Enforces invariants:
|
||||
@@ -385,44 +385,44 @@ The domain models what an “automation session” is, how it progresses, and wh
|
||||
- Steps can only move forward and must progress sequentially (`n → n+1`, no skipping or going backwards).
|
||||
- Terminal states (e.g. `STOPPED_AT_STEP_18`, `FAILED`) cannot be mutated further.
|
||||
|
||||
- [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)
|
||||
- [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)
|
||||
- Describes the admin’s intended hosted session:
|
||||
- Required: `sessionName`, `trackId`, `carIds`.
|
||||
- Optional QoL fields: `serverName`, `password`, `adminPassword`, `maxDrivers`, weather/time-of-day, lengths, damage model, track state, etc.
|
||||
- Acts as the **canonical session description** that higher layers use to map into iRacing’s wizard fields.
|
||||
|
||||
- [`StepExecution`](packages/domain/entities/StepExecution.ts:1)
|
||||
- [`StepExecution`](core/domain/entities/StepExecution.ts:1)
|
||||
- Encapsulates the result of executing a single wizard step, including timing and error data.
|
||||
|
||||
**Value objects**
|
||||
|
||||
- Session lifecycle and step identity:
|
||||
- [`SessionState`](packages/domain/value-objects/SessionState.ts:1)
|
||||
- [`SessionLifetime`](packages/domain/value-objects/SessionLifetime.ts:1)
|
||||
- [`StepId`](packages/domain/value-objects/StepId.ts:1)
|
||||
- [`SessionState`](core/domain/value-objects/SessionState.ts:1)
|
||||
- [`SessionLifetime`](core/domain/value-objects/SessionLifetime.ts:1)
|
||||
- [`StepId`](core/domain/value-objects/StepId.ts:1)
|
||||
|
||||
- Authentication and browser state:
|
||||
- [`AuthenticationState`](packages/domain/value-objects/AuthenticationState.ts:1)
|
||||
- [`BrowserAuthenticationState`](packages/domain/value-objects/BrowserAuthenticationState.ts:1)
|
||||
- [`CookieConfiguration`](packages/domain/value-objects/CookieConfiguration.ts:1)
|
||||
- [`AuthenticationState`](core/domain/value-objects/AuthenticationState.ts:1)
|
||||
- [`BrowserAuthenticationState`](core/domain/value-objects/BrowserAuthenticationState.ts:1)
|
||||
- [`CookieConfiguration`](core/domain/value-objects/CookieConfiguration.ts:1)
|
||||
|
||||
- Checkout and pricing safety:
|
||||
- [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1)
|
||||
- [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1)
|
||||
- [`CheckoutConfirmation`](packages/domain/value-objects/CheckoutConfirmation.ts:1)
|
||||
- [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1)
|
||||
- [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1)
|
||||
- [`CheckoutConfirmation`](core/domain/value-objects/CheckoutConfirmation.ts:1)
|
||||
|
||||
- Overlay/visual integration:
|
||||
- [`ScreenRegion`](packages/domain/value-objects/ScreenRegion.ts:1)
|
||||
- [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1)
|
||||
- [`ScreenRegion`](core/domain/value-objects/ScreenRegion.ts:1)
|
||||
- [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1)
|
||||
|
||||
**Domain services**
|
||||
|
||||
- [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1)
|
||||
- [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1)
|
||||
- Declaratively describes what it means for the automation to be “on the right wizard page”.
|
||||
- Evaluates combinations of required/forbidden selectors into a structured result.
|
||||
- Used by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) to avoid driving the wrong UI state.
|
||||
- Used by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) to avoid driving the wrong UI state.
|
||||
|
||||
- [`StepTransitionValidator`](packages/domain/services/StepTransitionValidator.ts:1)
|
||||
- [`StepTransitionValidator`](core/domain/services/StepTransitionValidator.ts:1)
|
||||
- Enforces legal transitions between wizard steps and session states.
|
||||
- Centralizes the rules for when it is safe to move to the next step or finalize.
|
||||
|
||||
@@ -433,133 +433,133 @@ The domain models what an “automation session” is, how it progresses, and wh
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Application Layer (`packages/application/*`)
|
||||
### 4.2 Application Layer (`core/application/*`)
|
||||
|
||||
The application layer orchestrates use-cases by coordinating domain entities and calling ports that are implemented in infrastructure.
|
||||
|
||||
**Key ports**
|
||||
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1)
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1)
|
||||
- `validateConfiguration(config)` → checks whether the intended hosted session is structurally valid and automatable.
|
||||
- `executeStep(stepId, config)` → drives a single wizard step using the underlying browser automation.
|
||||
- `stopAutomation()` → halts the current run.
|
||||
|
||||
- [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1)
|
||||
- Persists [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) instances for tracking and later inspection.
|
||||
- [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1)
|
||||
- Persists [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) instances for tracking and later inspection.
|
||||
|
||||
- Screen & browser integration:
|
||||
- [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1) (implemented by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)).
|
||||
- [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1) for login/session management.
|
||||
- [`ICheckoutService`](packages/application/ports/ICheckoutService.ts:1) and [`ICheckoutConfirmationPort`](packages/application/ports/ICheckoutConfirmationPort.ts:1) for safe credits/checkout flows.
|
||||
- [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1) (implemented by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)).
|
||||
- [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1) for login/session management.
|
||||
- [`ICheckoutService`](core/application/ports/ICheckoutService.ts:1) and [`ICheckoutConfirmationPort`](core/application/ports/ICheckoutConfirmationPort.ts:1) for safe credits/checkout flows.
|
||||
|
||||
- Cross-cutting:
|
||||
- [`ILogger`](packages/application/ports/ILogger.ts:1)
|
||||
- [`IOverlaySyncPort`](packages/application/ports/IOverlaySyncPort.ts:1)
|
||||
- [`IAutomationEventPublisher`](packages/application/ports/IAutomationEventPublisher.ts:1)
|
||||
- [`IUserConfirmationPort`](packages/application/ports/IUserConfirmationPort.ts:1)
|
||||
- [`ILogger`](core/application/ports/ILogger.ts:1)
|
||||
- [`IOverlaySyncPort`](core/application/ports/IOverlaySyncPort.ts:1)
|
||||
- [`IAutomationEventPublisher`](core/application/ports/IAutomationEventPublisher.ts:1)
|
||||
- [`IUserConfirmationPort`](core/application/ports/IUserConfirmationPort.ts:1)
|
||||
|
||||
**Key services**
|
||||
|
||||
- [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1)
|
||||
- [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1)
|
||||
- Bridges the automation lifecycle (from infrastructure) to overlay/presentation consumers (companion renderer).
|
||||
- Consumes an [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) (implemented by the Playwright adapter) and publishes state to an overlay sync port.
|
||||
- Consumes an [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) (implemented by the Playwright adapter) and publishes state to an overlay sync port.
|
||||
|
||||
**Key use-cases**
|
||||
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- Creates a new [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) from a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Calls [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) to perform validation before any browser work starts.
|
||||
- Persists the session via [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- Creates a new [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) from a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Calls [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) to perform validation before any browser work starts.
|
||||
- Persists the session via [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1).
|
||||
- Returns a DTO that the companion app tracks as progress state.
|
||||
|
||||
- Authentication:
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](packages/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](core/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- These map the ToS-compliant login flow described in [`CONCEPT.md`](docs/concept/CONCEPT.md) and [`ADMINS.md`](docs/concept/ADMINS.md) into explicit use-cases (no password handling by GridPilot).
|
||||
|
||||
- Automation completion & checkout:
|
||||
- [`CompleteRaceCreationUseCase`](packages/application/use-cases/CompleteRaceCreationUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Uses [`ICheckoutService`](packages/application/ports/ICheckoutService.ts:1) from the Playwright layer to inspect price/state and defers to a UI-side confirmation port to comply with “never surprise-charge the admin”.
|
||||
- [`CompleteRaceCreationUseCase`](core/application/use-cases/CompleteRaceCreationUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Uses [`ICheckoutService`](core/application/ports/ICheckoutService.ts:1) from the Playwright layer to inspect price/state and defers to a UI-side confirmation port to comply with “never surprise-charge the admin”.
|
||||
|
||||
- Guarding against stale auth:
|
||||
- [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) ensures the current page is still authenticated before continuing automation.
|
||||
- [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) ensures the current page is still authenticated before continuing automation.
|
||||
|
||||
The application layer is where “admin intent” (start automation, confirm checkout, verify login) is encoded and exposed to the companion, without exposing Playwright or DOM specifics.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Infrastructure Layer (`packages/infrastructure/*`)
|
||||
### 4.3 Infrastructure Layer (`core/infrastructure/*`)
|
||||
|
||||
The infrastructure layer implements the ports using concrete tools and services.
|
||||
|
||||
**Automation adapters**
|
||||
|
||||
- [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)
|
||||
- [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)
|
||||
- Implements:
|
||||
- [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1)
|
||||
- [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1)
|
||||
- [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) used by [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1).
|
||||
- [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1)
|
||||
- [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1)
|
||||
- [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) used by [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1).
|
||||
- Responsibilities:
|
||||
- Managing Playwright browser, context, and page lifecycle (headed/headless, fixture vs real mode).
|
||||
- Navigating to the iRacing hosted-session wizard, login pages and fixtures.
|
||||
- Driving wizard steps through an internal [`WizardStepOrchestrator`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Driving wizard steps through an internal [`WizardStepOrchestrator`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Injecting and updating the on-page automation overlay.
|
||||
- Enforcing click safety (blocked selectors, checkout detection).
|
||||
- Handling authentication flows, cookies and persistent sessions via [`SessionCookieStore`](packages/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1) and [`PlaywrightAuthSessionService`](packages/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1).
|
||||
- Validating page state using [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1).
|
||||
- Handling authentication flows, cookies and persistent sessions via [`SessionCookieStore`](core/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1) and [`PlaywrightAuthSessionService`](core/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1).
|
||||
- Validating page state using [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1).
|
||||
|
||||
- [`MockBrowserAutomationAdapter`](packages/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1)
|
||||
- [`MockBrowserAutomationAdapter`](core/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1)
|
||||
- Lightweight adapter used in tests to simulate automation without real browser interactions.
|
||||
|
||||
- [`FixtureServer`](packages/infrastructure/adapters/automation/engine/FixtureServer.ts:1)
|
||||
- [`FixtureServer`](core/infrastructure/adapters/automation/engine/FixtureServer.ts:1)
|
||||
- Serves static HTML fixtures from `html-dumps-optimized/` to exercise the automation logic deterministically in tests and local development.
|
||||
|
||||
**DOM helpers**
|
||||
|
||||
- [`IRacingDomNavigator`](packages/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts:1)
|
||||
- [`IRacingDomNavigator`](core/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts:1)
|
||||
- High-level navigation and waiting logic for wizard steps and key UI elements.
|
||||
|
||||
- [`IRacingDomInteractor`](packages/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1)
|
||||
- [`IRacingDomInteractor`](core/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1)
|
||||
- Encapsulates filling fields, clicking elements, handling modals.
|
||||
|
||||
- [`SafeClickService`](packages/infrastructure/adapters/automation/dom/SafeClickService.ts:1)
|
||||
- [`SafeClickService`](core/infrastructure/adapters/automation/dom/SafeClickService.ts:1)
|
||||
- A safer click abstraction that combines timeouts, modal-dismiss logic and safety checks.
|
||||
|
||||
- Selectors and constants:
|
||||
- [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1)
|
||||
- Additional helper types under `packages/infrastructure/adapters/automation/dom/*`.
|
||||
- [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1)
|
||||
- Additional helper types under `core/infrastructure/adapters/automation/dom/*`.
|
||||
|
||||
**Checkout & pricing**
|
||||
|
||||
- [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1)
|
||||
- [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1)
|
||||
- Reads DOM labels and buttons in the iRacing wizard to produce:
|
||||
- [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1) (if parsable).
|
||||
- [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1) (derived from button classes).
|
||||
- [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1) (if parsable).
|
||||
- [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1) (derived from button classes).
|
||||
- Raw `buttonHtml` for debugging.
|
||||
- Returns results wrapped in [`Result`](packages/shared/result/Result.ts:1) to avoid throwing during automation.
|
||||
- Returns results wrapped in [`Result`](core/shared/result/Result.ts:1) to avoid throwing during automation.
|
||||
|
||||
**Repositories & configuration**
|
||||
|
||||
- [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1)
|
||||
- Simple in-process implementation of [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1), used in the companion app and tests.
|
||||
- [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1)
|
||||
- Simple in-process implementation of [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1), used in the companion app and tests.
|
||||
|
||||
- Config:
|
||||
- [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1)
|
||||
- [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1)
|
||||
- Mode selection: `production`, `development`, `test`.
|
||||
- Default timeouts and base URLs for fixtures vs live.
|
||||
- [`BrowserModeConfig`](packages/infrastructure/config/BrowserModeConfig.ts:1)
|
||||
- Controls headed/headless behavior, with [`BrowserModeConfigLoader`](packages/infrastructure/config/BrowserModeConfig.ts:1) used heavily in [`di-container`](apps/companion/main/di-container.ts:1).
|
||||
- [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1)
|
||||
- [`BrowserModeConfig`](core/infrastructure/config/BrowserModeConfig.ts:1)
|
||||
- Controls headed/headless behavior, with [`BrowserModeConfigLoader`](core/infrastructure/config/BrowserModeConfig.ts:1) used heavily in [`di-container`](apps/companion/main/di-container.ts:1).
|
||||
- [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1)
|
||||
|
||||
- Logging:
|
||||
- [`PinoLogAdapter`](packages/infrastructure/adapters/logging/PinoLogAdapter.ts:1)
|
||||
- [`NoOpLogAdapter`](packages/infrastructure/adapters/logging/NoOpLogAdapter.ts:1) (used in tests to keep noise low).
|
||||
- [`PinoLogAdapter`](core/infrastructure/adapters/logging/PinoLogAdapter.ts:1)
|
||||
- [`NoOpLogAdapter`](core/infrastructure/adapters/logging/NoOpLogAdapter.ts:1) (used in tests to keep noise low).
|
||||
|
||||
**IPC / UI integration**
|
||||
|
||||
- [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1)
|
||||
- [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1)
|
||||
- Bridges application-level checkout confirmation flows to the companion renderer via IPC.
|
||||
|
||||
This layer is where the “messy reality” of Playwright, Electron, file paths and selectors is implemented, while honoring the constraints defined at the domain/application layers.
|
||||
@@ -579,22 +579,22 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
|
||||
- [`di-container`](apps/companion/main/di-container.ts)
|
||||
- Central wiring for:
|
||||
- Logger ([`ILogger`](packages/application/ports/ILogger.ts:1)) via `createLogger()` and [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1).
|
||||
- Session repository ([`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1)) via [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1).
|
||||
- Browser automation adapter via `createBrowserAutomationAdapter()` using [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) or [`MockBrowserAutomationAdapter`](packages/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1) depending on mode.
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) via [`AutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) / [`MockAutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1).
|
||||
- Logger ([`ILogger`](core/application/ports/ILogger.ts:1)) via `createLogger()` and [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1).
|
||||
- Session repository ([`ISessionRepository`](core/application/ports/ISessionRepository.ts:1)) via [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1).
|
||||
- Browser automation adapter via `createBrowserAutomationAdapter()` using [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) or [`MockBrowserAutomationAdapter`](core/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1) depending on mode.
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) via [`AutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) / [`MockAutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1).
|
||||
- Application use-cases:
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](packages/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Overlay sync orchestration via [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1) and [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](core/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Overlay sync orchestration via [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1) and [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1).
|
||||
- Exposes methods like `getStartAutomationUseCase()`, `initializeBrowserConnection()`, `getBrowserModeConfigLoader()`, and `refreshBrowserAutomation()` that are used by IPC handlers and tests.
|
||||
|
||||
- [`ipc-handlers`](apps/companion/main/ipc-handlers.ts)
|
||||
- Translates renderer IPC calls into use-case invocations:
|
||||
- `startAutomation` → [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- `startAutomation` → [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- `checkAuth` / `initiateLogin` / `clearSession` → authentication use-cases.
|
||||
- Browser connection initialization and overlay sync wiring.
|
||||
|
||||
@@ -607,7 +607,7 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
- [`App`](apps/companion/renderer/App.tsx)
|
||||
- Controls high-level UI state:
|
||||
- Authentication state (`AuthState`) and login flow.
|
||||
- Current [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) passed from the session creation form.
|
||||
- Current [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) passed from the session creation form.
|
||||
- Session progress tracking (step, state, errors).
|
||||
- Checkout confirmation dialog and race creation success views.
|
||||
- Talks to Electron via `window.electronAPI`:
|
||||
@@ -618,17 +618,17 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
|
||||
- Components (selection):
|
||||
- [`SessionCreationForm`](apps/companion/renderer/components/SessionCreationForm.tsx)
|
||||
- Collects the data that becomes [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Collects the data that becomes [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx)
|
||||
- Visualizes the current step, completed steps, and error state of the [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1).
|
||||
- Visualizes the current step, completed steps, and error state of the [`AutomationSession`](core/domain/entities/AutomationSession.ts:1).
|
||||
- [`LoginPrompt`](apps/companion/renderer/components/LoginPrompt.tsx)
|
||||
- Renders different messages for `AUTHENTICATED`, `EXPIRED`, `LOGGED_OUT`, `UNKNOWN` states and wires `onLogin`/`onRetry`.
|
||||
- [`BrowserModeToggle`](apps/companion/renderer/components/BrowserModeToggle.tsx)
|
||||
- Allows switching between headed/headless behavior in development, talking to the [`BrowserModeConfigLoader`](packages/infrastructure/config/BrowserModeConfig.ts:1) through IPC.
|
||||
- Allows switching between headed/headless behavior in development, talking to the [`BrowserModeConfigLoader`](core/infrastructure/config/BrowserModeConfig.ts:1) through IPC.
|
||||
- [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx)
|
||||
- Presents a clear, time-bounded dialog where the admin must confirm or cancel a credit purchase-like action.
|
||||
- [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx)
|
||||
- Displays the final result of a successful race creation as modeled by [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1).
|
||||
- Displays the final result of a successful race creation as modeled by [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1).
|
||||
|
||||
The companion app is intentionally a **single presentation layer implemented in this repo**, but the application and domain layers are structured so that other presentation layers (web client, backend orchestration service) can reuse the same automation engine via the same ports.
|
||||
|
||||
@@ -644,7 +644,7 @@ This subsection summarizes how the GridPilot Web App / Website and the companion
|
||||
- League and season management, scheduling and calendars.
|
||||
- Driver and team views, stats, rating, discovery and social features as described in the concept docs.
|
||||
- Runs in browsers, talking to core platform services over HTTP or GraphQL.
|
||||
- Produces configuration artifacts such as hosted-session definitions that can be mapped into [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) on the platform side.
|
||||
- Produces configuration artifacts such as hosted-session definitions that can be mapped into [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) on the platform side.
|
||||
|
||||
**GridPilot Companion App (desktop presentation, this repo)**
|
||||
|
||||
@@ -657,9 +657,9 @@ This subsection summarizes how the GridPilot Web App / Website and the companion
|
||||
**Communication pattern between website, platform and companion**
|
||||
|
||||
- A typical flow for a scheduled league race:
|
||||
- The web app and core platform services use competition data (league, calendar, formats) to derive a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) or equivalent structure server-side.
|
||||
- The web app and core platform services use competition data (league, calendar, formats) to derive a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) or equivalent structure server-side.
|
||||
- The core platform stores and schedules these configs and can expose them via APIs.
|
||||
- The companion app fetches or receives the relevant configs, calls into the application layer (for example [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)) and executes them against iRacing through Playwright.
|
||||
- The companion app fetches or receives the relevant configs, calls into the application layer (for example [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)) and executes them against iRacing through Playwright.
|
||||
- Status and results flow back through overlays and events, and can be consumed both by the companion UI and by platform-side stats and rating services.
|
||||
|
||||
- This repo provides:
|
||||
@@ -679,66 +679,66 @@ This section describes how a typical hosted-session automation run flows through
|
||||
1. **Admin configures a session**
|
||||
|
||||
- In the companion UI, the admin fills out [`SessionCreationForm`](apps/companion/renderer/components/SessionCreationForm.tsx).
|
||||
- The form builds a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)-compatible object and calls `window.electronAPI.startAutomation(config)`.
|
||||
- The form builds a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)-compatible object and calls `window.electronAPI.startAutomation(config)`.
|
||||
|
||||
2. **IPC → main process**
|
||||
|
||||
- The preload script forwards this call to an IPC handler in [`ipc-handlers`](apps/companion/main/ipc-handlers.ts).
|
||||
- The handler resolves the singleton [`DIContainer`](apps/companion/main/di-container.ts:1) and obtains:
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) and [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1) behind the scenes.
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) and [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1) behind the scenes.
|
||||
|
||||
3. **Use-case and domain**
|
||||
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1):
|
||||
- Creates a new [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) by calling `AutomationSession.create(config)`, which validates the core invariants (non-empty session name, track, cars).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1):
|
||||
- Creates a new [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) by calling `AutomationSession.create(config)`, which validates the core invariants (non-empty session name, track, cars).
|
||||
- Calls `automationEngine.validateConfiguration(config)` to perform more detailed checks (e.g. compatibility with supported wizard flows).
|
||||
- Persists the new session via [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1) (implemented by [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1)).
|
||||
- Persists the new session via [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1) (implemented by [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1)).
|
||||
- Returns a DTO to the IPC handler which is forwarded to the renderer.
|
||||
|
||||
4. **Browser and Playwright setup**
|
||||
|
||||
- The [`DIContainer`](apps/companion/main/di-container.ts:1) uses [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1) and [`BrowserModeConfig`](packages/infrastructure/config/BrowserModeConfig.ts:1) to:
|
||||
- The [`DIContainer`](apps/companion/main/di-container.ts:1) uses [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1) and [`BrowserModeConfig`](core/infrastructure/config/BrowserModeConfig.ts:1) to:
|
||||
- Decide between `production`, `development`, `test` modes.
|
||||
- Decide headed vs headless rendering.
|
||||
- Potentially start a [`FixtureServer`](packages/infrastructure/adapters/automation/engine/FixtureServer.ts:1) in test/fixture modes.
|
||||
- [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) connects to a browser and ensures the context is ready via `connect()` / `ensureBrowserContext()`.
|
||||
- Potentially start a [`FixtureServer`](core/infrastructure/adapters/automation/engine/FixtureServer.ts:1) in test/fixture modes.
|
||||
- [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) connects to a browser and ensures the context is ready via `connect()` / `ensureBrowserContext()`.
|
||||
|
||||
5. **Authentication and login**
|
||||
|
||||
- For real iRacing usage:
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1) and [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) verify whether the session is still valid.
|
||||
- If not, the renderer triggers [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1) via IPC.
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1) and [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) verify whether the session is still valid.
|
||||
- If not, the renderer triggers [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1) via IPC.
|
||||
- The Playwright adapter opens a headed browser window, navigates to the login page, and lets the admin log in manually.
|
||||
- Once login is complete, [`PlaywrightAuthSessionService`](packages/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1) stores cookies in [`SessionCookieStore`](packages/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1), and future runs reuse them.
|
||||
- Once login is complete, [`PlaywrightAuthSessionService`](core/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1) stores cookies in [`SessionCookieStore`](core/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1), and future runs reuse them.
|
||||
|
||||
6. **Step-by-step wizard automation**
|
||||
|
||||
- The automation engine (implemented by [`AutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) and backed by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)) proceeds through steps:
|
||||
- The automation engine (implemented by [`AutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) and backed by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)) proceeds through steps:
|
||||
|
||||
- Navigate to hosted sessions.
|
||||
- Open “Create a Race” and the hosted-session wizard.
|
||||
- For each step (race information, server details, admins, cars, tracks, weather, race options, conditions):
|
||||
- Ensure the correct page is active using [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1) and selectors from [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
- Fill fields and toggles using [`IRacingDomInteractor`](packages/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1).
|
||||
- Click the correct “Next” / “Create Race” / “New Race” buttons, guarded by [`SafeClickService`](packages/infrastructure/adapters/automation/dom/SafeClickService.ts:1) and blocked-selector logic.
|
||||
- Ensure the correct page is active using [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1) and selectors from [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
- Fill fields and toggles using [`IRacingDomInteractor`](core/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1).
|
||||
- Click the correct “Next” / “Create Race” / “New Race” buttons, guarded by [`SafeClickService`](core/infrastructure/adapters/automation/dom/SafeClickService.ts:1) and blocked-selector logic.
|
||||
|
||||
- At each step, the Playwright adapter:
|
||||
- Updates the overlay via `updateOverlay(step, message)`.
|
||||
- Emits lifecycle events consumed by [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1), which the companion uses to update [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx).
|
||||
- Emits lifecycle events consumed by [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1), which the companion uses to update [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx).
|
||||
|
||||
7. **Checkout and confirmation**
|
||||
|
||||
- For flows that involve iRacing credits or non-zero prices:
|
||||
- [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) is used by the Playwright adapter to parse price and state from the wizard UI.
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1) sends a confirmation request to the renderer via [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1).
|
||||
- [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) is used by the Playwright adapter to parse price and state from the wizard UI.
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1) sends a confirmation request to the renderer via [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1).
|
||||
- [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx) shows the admin the price and state, with an explicit timeout and cancel path.
|
||||
- Only after explicit confirmation does the adapter simulate the checkout sequence (and in real mode, additional safeguards ensure no ToS-violating clicks occur).
|
||||
|
||||
8. **Completion and result**
|
||||
|
||||
- Once the final step is reached, [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) transitions into a terminal state (`STOPPED_AT_STEP_18`, `FAILED`, etc.).
|
||||
- The companion renderer may present a [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1) via [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx).
|
||||
- Once the final step is reached, [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) transitions into a terminal state (`STOPPED_AT_STEP_18`, `FAILED`, etc.).
|
||||
- The companion renderer may present a [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1) via [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx).
|
||||
- The browser context is closed or re-used based on mode and configuration; debug artifacts may be written by the Playwright adapter for failed runs.
|
||||
|
||||
---
|
||||
@@ -763,7 +763,7 @@ Although this repo focuses on automation and companion, it is deliberately shape
|
||||
|
||||
- The automation engine is designed so that a future league platform can:
|
||||
|
||||
- Generate [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) from league and calendar data (cars, tracks, formats) defined in the core competition services.
|
||||
- Generate [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) from league and calendar data (cars, tracks, formats) defined in the core competition services.
|
||||
- Trigger automation runs at scheduled times, with the admin supervising in the companion app.
|
||||
- Use consistent, error-free sessions as the basis for reliable result capture and stats, supporting the narratives in [`DRIVERS.md`](docs/concept/DRIVERS.md), [`TEAMS.md`](docs/concept/TEAMS.md), [`RACING.md`](docs/concept/RACING.md) and [`STATS.md`](docs/concept/STATS.md).
|
||||
|
||||
@@ -831,7 +831,7 @@ In a future GridPilot platform:
|
||||
|
||||
- The **automation engine** in this repo would be used as a **hosted-session execution backend**:
|
||||
|
||||
- The platform would derive [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) objects from league/season metadata (cars, tracks, formats) defined in the platform.
|
||||
- The platform would derive [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) objects from league/season metadata (cars, tracks, formats) defined in the platform.
|
||||
- It would call into the automation layer via explicit use-cases or IPC/API, using the same ports used by the companion app today.
|
||||
- The Electron companion may remain the primary operator UI, or an additional headless orchestration mode could be added (still respecting ToS and admin control).
|
||||
|
||||
@@ -846,13 +846,13 @@ In a future GridPilot platform:
|
||||
The automation domain (sessions, steps, validation) is free of Electron/Playwright details, making it straightforward to embed into other hosts.
|
||||
|
||||
- **Ports for automation & auth**:
|
||||
Using [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1), [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1), [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1) means new drivers (or alternative browser runtimes) can be introduced without changing the use-cases.
|
||||
Using [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1), [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1), [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1) means new drivers (or alternative browser runtimes) can be introduced without changing the use-cases.
|
||||
|
||||
- **Explicit checkout/confirmation path**:
|
||||
The combination of [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1), [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](packages/domain/value-objects/CheckoutConfirmation.ts:1) and the UI-side confirmation port aligns with the transparency and fairness requirements in [`ADMINS.md`](docs/concept/ADMINS.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
The combination of [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1), [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](core/domain/value-objects/CheckoutConfirmation.ts:1) and the UI-side confirmation port aligns with the transparency and fairness requirements in [`ADMINS.md`](docs/concept/ADMINS.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
|
||||
- **Overlay and lifecycle emitter**:
|
||||
The overlay and [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) abstraction make it easy to:
|
||||
The overlay and [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) abstraction make it easy to:
|
||||
- Drive visual overlays (like those described in admin QoL features) across different frontends.
|
||||
- Feed telemetry into a central stats/ops UI for debugging, while keeping the engine itself small.
|
||||
|
||||
|
||||
@@ -120,8 +120,8 @@ src/apps/companion/
|
||||
```
|
||||
|
||||
**Reused Layers** (100% unchanged):
|
||||
- **Domain**: [`AutomationSession`](../src/packages/domain/entities/AutomationSession.ts:1), [`SessionState`](../src/packages/domain/value-objects/SessionState.ts:1), [`StepId`](../src/packages/domain/value-objects/StepId.ts:1)
|
||||
- **Application**: [`StartAutomationSessionUseCase`](../src/packages/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- **Domain**: [`AutomationSession`](../src/core/domain/entities/AutomationSession.ts:1), [`SessionState`](../src/core/domain/value-objects/SessionState.ts:1), [`StepId`](../src/core/domain/value-objects/StepId.ts:1)
|
||||
- **Application**: [`StartAutomationSessionUseCase`](../src/core/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- **Infrastructure**: [`MockBrowserAutomationAdapter`](../src/infrastructure/adapters/automation/MockBrowserAutomationAdapter.ts:1), [`MockAutomationEngineAdapter`](../src/infrastructure/adapters/automation/MockAutomationEngineAdapter.ts:1), [`InMemorySessionRepository`](../src/infrastructure/repositories/InMemorySessionRepository.ts:1)
|
||||
|
||||
### IPC Communication Flow
|
||||
|
||||
+16
-16
@@ -57,8 +57,8 @@ This track is grounded in the existing code and architecture:
|
||||
|
||||
- Hosted wizard flow and step orchestration (see `tests/e2e/steps/*` and `tests/e2e/workflows/*`).
|
||||
- Auth and cookie/session management.
|
||||
- Overlay lifecycle via [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) and [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1).
|
||||
- Checkout safety via [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1), [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1), [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1) and the renderer dialog.
|
||||
- Overlay lifecycle via [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) and [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1).
|
||||
- Checkout safety via [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1), [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1), [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1) and the renderer dialog.
|
||||
- Electron companion UI and IPC wiring.
|
||||
|
||||
### Phase A: Solid Hosted-Session Engine & Companion Baseline
|
||||
@@ -68,14 +68,14 @@ This track is grounded in the existing code and architecture:
|
||||
**Automation (this repo)**
|
||||
|
||||
- [ ] Stabilize wizard step orchestration:
|
||||
- [ ] Review and align wizard-step domain rules with [`StepTransitionValidator`](packages/domain/services/StepTransitionValidator.ts:1).
|
||||
- [ ] Review and align wizard-step domain rules with [`StepTransitionValidator`](core/domain/services/StepTransitionValidator.ts:1).
|
||||
- [ ] Ensure `tests/e2e/steps/*` cover all 18 hosted wizard steps end to end.
|
||||
- [ ] Harden [`WizardStepOrchestrator`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) behavior for retries and timeouts.
|
||||
- [ ] Harden [`WizardStepOrchestrator`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) behavior for retries and timeouts.
|
||||
- [ ] Strengthen page validation:
|
||||
- [ ] Extend [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1) to cover edge cases found in real-hosted tests.
|
||||
- [ ] Ensure selector sets in `packages/infrastructure/adapters/automation/dom/*` match current iRacing UI.
|
||||
- [ ] Extend [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1) to cover edge cases found in real-hosted tests.
|
||||
- [ ] Ensure selector sets in `core/infrastructure/adapters/automation/dom/*` match current iRacing UI.
|
||||
- [ ] Tighten auth/session flows:
|
||||
- [ ] Verify [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1), [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1), and [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) match the constraints in [`CONCEPT.md`](docs/concept/CONCEPT.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
- [ ] Verify [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1), [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1), and [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) match the constraints in [`CONCEPT.md`](docs/concept/CONCEPT.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
- [ ] Confirm cookie handling in `automation/auth/*` matches the lifecycle described in [`ARCHITECTURE.md`](docs/ARCHITECTURE.md).
|
||||
- [ ] Companion baseline:
|
||||
- [ ] Ensure the Electron app boots and connects reliably on supported platforms (see smoke tests in `tests/smoke/*`).
|
||||
@@ -96,8 +96,8 @@ This track is grounded in the existing code and architecture:
|
||||
**Automation (this repo)**
|
||||
|
||||
- [ ] Lifecycle events:
|
||||
- [ ] Review events emitted by [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) and consumed by [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1).
|
||||
- [ ] Ensure all critical state transitions of [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) are reflected in overlay events.
|
||||
- [ ] Review events emitted by [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) and consumed by [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1).
|
||||
- [ ] Ensure all critical state transitions of [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) are reflected in overlay events.
|
||||
- [ ] Overlay UX:
|
||||
- [ ] Ensure [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx:1) clearly maps steps 1–18 to admin-understandable labels.
|
||||
- [ ] Align overlay messaging with admin QoL themes in [`ADMINS.md`](docs/concept/ADMINS.md) (less repetitive work, more transparency).
|
||||
@@ -119,11 +119,11 @@ This track is grounded in the existing code and architecture:
|
||||
**Automation (this repo)**
|
||||
|
||||
- [ ] Enrich checkout detection:
|
||||
- [ ] Validate selector logic and price parsing in [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) against current iRacing UI.
|
||||
- [ ] Ensure [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1) covers all relevant button states.
|
||||
- [ ] Validate selector logic and price parsing in [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) against current iRacing UI.
|
||||
- [ ] Ensure [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1) covers all relevant button states.
|
||||
- [ ] Harden confirmation logic:
|
||||
- [ ] Confirm [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1) is the *only* entry point for automation that proceeds past a non-zero price.
|
||||
- [ ] Ensure [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1) and [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx:1) enforce explicit admin confirmation and timeouts.
|
||||
- [ ] Confirm [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1) is the *only* entry point for automation that proceeds past a non-zero price.
|
||||
- [ ] Ensure [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1) and [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx:1) enforce explicit admin confirmation and timeouts.
|
||||
- [ ] Failure paths:
|
||||
- [ ] Verify that any parsing failure or ambiguous state results in a safe stop, not a blind click.
|
||||
- [ ] Add tests to cover “weird but possible” UI states observed via fixtures.
|
||||
@@ -143,11 +143,11 @@ This track is grounded in the existing code and architecture:
|
||||
|
||||
- [ ] Map additional hosted workflows:
|
||||
- [ ] Identify additional iRacing hosted flows that align with admin QoL needs from [`ADMINS.md`](docs/concept/ADMINS.md) (e.g. practice-only, league-specific hosted sessions).
|
||||
- [ ] Encode them as configurations on top of [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) where feasible.
|
||||
- [ ] Encode them as configurations on top of [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) where feasible.
|
||||
- [ ] Workflow templates:
|
||||
- [ ] Provide a small set of reusable presets (e.g. “standard league race”, “test session”) that can later be populated by external services.
|
||||
- [ ] Resilience work:
|
||||
- [ ] Improve behavior under partial UI changes (selectors, labels) using the validation patterns from [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1).
|
||||
- [ ] Improve behavior under partial UI changes (selectors, labels) using the validation patterns from [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1).
|
||||
|
||||
**Success criteria**
|
||||
|
||||
@@ -195,7 +195,7 @@ Each phase is intentionally high-level to avoid going stale; details belong in f
|
||||
- Implement league identity, schedules and season configuration:
|
||||
- public league pages, schedules, rules, rosters (see sections 3 and 4 in [`CONCEPT.md`](docs/concept/CONCEPT.md)).
|
||||
- admin tools for creating seasons, calendars, formats (mirroring [`RACING.md`](docs/concept/RACING.md)).
|
||||
- Model leagues, seasons and events as first-class entities that can later produce [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) instances for this repo’s automation engine.
|
||||
- Model leagues, seasons and events as first-class entities that can later produce [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) instances for this repo’s automation engine.
|
||||
|
||||
**Success criteria**
|
||||
|
||||
|
||||
+1
-1
@@ -205,7 +205,7 @@ Two candidates meet accessibility and performance requirements:
|
||||
|
||||
### npm Workspaces
|
||||
- **Rationale:** Built-in, zero configuration, dependency hoisting
|
||||
- **Structure:** `/src/apps/*`, `/src/packages/*`, `/tests/*`
|
||||
- **Structure:** `/src/apps/*`, `/src/core/*`, `/tests/*`
|
||||
|
||||
### Build Orchestration: Under Evaluation
|
||||
|
||||
|
||||
+8
-8
@@ -1131,8 +1131,8 @@ GridPilot's testing strategy ensures:
|
||||
For the iRacing hosted-session automation, confidence is provided by these concrete suites:
|
||||
|
||||
- **Domain/Application unit tests**
|
||||
- Entities and value objects such as [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1), [`SessionState`](packages/domain/value-objects/SessionState.ts:1), [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](packages/domain/value-objects/CheckoutConfirmation.ts:1), and [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1).
|
||||
- Use cases such as [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1), [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1), [`CompleteRaceCreationUseCase`](packages/application/use-cases/CompleteRaceCreationUseCase.ts:1), and [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1).
|
||||
- Entities and value objects such as [`AutomationSession`](core/domain/entities/AutomationSession.ts:1), [`SessionState`](core/domain/value-objects/SessionState.ts:1), [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](core/domain/value-objects/CheckoutConfirmation.ts:1), and [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1).
|
||||
- Use cases such as [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1), [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1), [`CompleteRaceCreationUseCase`](core/application/use-cases/CompleteRaceCreationUseCase.ts:1), and [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1).
|
||||
|
||||
- **Infrastructure / automation integration tests**
|
||||
- Adapter wiring and fixture serving via [`FixtureServer.integration.test.ts`](tests/integration/infrastructure/FixtureServer.integration.test.ts:1).
|
||||
@@ -1140,13 +1140,13 @@ For the iRacing hosted-session automation, confidence is provided by these concr
|
||||
- UI/overlay integration via [`renderer-overlay.integration.test.ts`](tests/integration/interface/renderer/renderer-overlay.integration.test.ts:1).
|
||||
|
||||
- **Fixture-based step E2E tests (per-step behavior)**
|
||||
- One test per wizard step under [`tests/e2e/steps`](tests/e2e/steps:1), all using the shared [`StepHarness`](tests/e2e/support/StepHarness.ts:1) and [`FixtureServer`](packages/infrastructure/adapters/automation/engine/FixtureServer.ts:1).
|
||||
- One test per wizard step under [`tests/e2e/steps`](tests/e2e/steps:1), all using the shared [`StepHarness`](tests/e2e/support/StepHarness.ts:1) and [`FixtureServer`](core/infrastructure/adapters/automation/engine/FixtureServer.ts:1).
|
||||
- These validate DOM-level selectors / flows for each step (1–18) against fixture-backed HTML, and are considered canonical for step behavior.
|
||||
|
||||
- **Fixture-based workflow E2E tests (button → auth entry → automation → confirmation boundary)**
|
||||
- Workflow-focused tests under [`tests/e2e/workflows`](tests/e2e/workflows:1) that drive the `PlaywrightAutomationAdapter` + `WizardStepOrchestrator` across multiple steps using the fixture server.
|
||||
- Example: [`steps-07-09-cars-flow.e2e.test.ts`](tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts:1) exercises cross-step cars flow, while [`full-hosted-session.workflow.e2e.test.ts`](tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts:1) runs a full 1–18 workflow via [`MockAutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1) and [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1), asserting final `SessionState` and step position.
|
||||
- Additional workflow scenarios cover mid-flow failure using [`MockBrowserAutomationAdapter`](packages/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1), ensuring failure states and diagnostics are surfaced without emitting false confirmations.
|
||||
- Example: [`steps-07-09-cars-flow.e2e.test.ts`](tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts:1) exercises cross-step cars flow, while [`full-hosted-session.workflow.e2e.test.ts`](tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts:1) runs a full 1–18 workflow via [`MockAutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1) and [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1), asserting final `SessionState` and step position.
|
||||
- Additional workflow scenarios cover mid-flow failure using [`MockBrowserAutomationAdapter`](core/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1), ensuring failure states and diagnostics are surfaced without emitting false confirmations.
|
||||
|
||||
- **Opt-in real-world automation smoke tests (legacy)**
|
||||
- The legacy real iRacing automation suite [`automation.e2e.test.ts`](tests/e2e/automation.e2e.test.ts:1) is now a skipped, documentation-only layer.
|
||||
@@ -1182,7 +1182,7 @@ The hosted-session automation stack is covered by layered suites that balance re
|
||||
- **Fixture-backed auto-navigation workflows**
|
||||
- [`full-hosted-session.autonav.workflow.e2e.test.ts`](tests/e2e/workflows/full-hosted-session.autonav.workflow.e2e.test.ts:1)
|
||||
- Uses the real Playwright stack (adapter + `WizardStepOrchestrator` + `FixtureServer`) with auto navigation enabled (`__skipFixtureNavigation` forbidden).
|
||||
- Drives a representative subset of steps (e.g., 1 → 3 → 7 → 9 → 13 → 17) and asserts each step lands on the expected wizard container via [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
- Drives a representative subset of steps (e.g., 1 → 3 → 7 → 9 → 13 → 17) and asserts each step lands on the expected wizard container via [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
|
||||
- **Step-level fixture E2Es with explicit mismatch path**
|
||||
- Existing step suites under [`tests/e2e/steps`](tests/e2e/steps:1) now have two execution paths via [`StepHarness`](tests/e2e/support/StepHarness.ts:1):
|
||||
@@ -1265,7 +1265,7 @@ These suites assume the same fixture server and Playwright wiring as the rest of
|
||||
|
||||
#### Selector ↔ fixture ↔ real DOM guardrail
|
||||
|
||||
For hosted-session automation, [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1) must match **either**:
|
||||
For hosted-session automation, [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1) must match **either**:
|
||||
|
||||
- The current `html-dumps-optimized` fixtures under [`html-dumps-optimized/iracing-hosted-sessions`](html-dumps-optimized/iracing-hosted-sessions:1), or
|
||||
- The real-site DOM as exercised by the hosted-real tests above.
|
||||
@@ -1287,7 +1287,7 @@ Manual workflow when the iRacing DOM changes:
|
||||
|
||||
3. Re-align selectors and tests:
|
||||
|
||||
- Update [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1) to reflect the new DOM shape.
|
||||
- Update [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1) to reflect the new DOM shape.
|
||||
- Fix any failing step/workflow E2Es under [`tests/e2e/steps`](tests/e2e/steps:1) and [`tests/e2e/workflows`](tests/e2e/workflows:1) so they again describe the canonical behavior.
|
||||
- Re-run:
|
||||
- `npm test`
|
||||
|
||||
Reference in New Issue
Block a user