import { StepId } from '../../../../domain/value-objects/StepId'; import type { IBrowserAutomation } from '../../../../application/ports/IScreenAutomation'; import { NavigationResult, FormFillResult, ClickResult, WaitResult, ModalResult, AutomationResult, } from '../../../../application/ports/AutomationResults'; interface MockConfig { simulateFailures?: boolean; failureRate?: number; } interface StepExecutionResult { success: boolean; stepId: number; wasModalStep?: boolean; shouldStop?: boolean; executionTime: number; metrics: { totalDelay: number; operationCount: number; }; } export class MockBrowserAutomationAdapter implements IBrowserAutomation { private config: MockConfig; private connected: boolean = false; constructor(config: MockConfig = {}) { this.config = { simulateFailures: config.simulateFailures ?? false, failureRate: config.failureRate ?? 0.1, }; } async connect(): Promise { this.connected = true; return { success: true }; } async disconnect(): Promise { this.connected = false; } isConnected(): boolean { return this.connected; } async navigateToPage(url: string): Promise { const delay = this.randomDelay(200, 800); await this.sleep(delay); return { success: true, url, loadTime: delay, }; } async fillFormField(fieldName: string, value: string): Promise { const delay = this.randomDelay(100, 500); await this.sleep(delay); return { success: true, fieldName, valueSet: value, }; } async clickElement(selector: string): Promise { const delay = this.randomDelay(50, 300); await this.sleep(delay); return { success: true, target: selector, }; } async waitForElement(selector: string, maxWaitMs: number = 5000): Promise { const delay = this.randomDelay(100, 1000); await this.sleep(delay); return { success: true, target: selector, waitedMs: delay, found: true, }; } async handleModal(stepId: StepId, action: string): Promise { if (!stepId.isModalStep()) { throw new Error(`Step ${stepId.value} is not a modal step`); } const delay = this.randomDelay(200, 600); await this.sleep(delay); return { success: true, stepId: stepId.value, action, }; } async executeStep(stepId: StepId, config: Record): Promise { if (this.shouldSimulateFailure()) { throw new Error(`Simulated failure at step ${stepId.value}`); } const startTime = Date.now(); let totalDelay = 0; let operationCount = 0; const navigationDelay = this.randomDelay(200, 500); await this.sleep(navigationDelay); totalDelay += navigationDelay; operationCount++; if (stepId.isModalStep()) { const modalDelay = this.randomDelay(200, 400); await this.sleep(modalDelay); totalDelay += modalDelay; operationCount++; } const executionTime = Date.now() - startTime; return { success: true, metadata: { stepId: stepId.value, wasModalStep: stepId.isModalStep(), shouldStop: stepId.isFinalStep(), executionTime, totalDelay, operationCount, }, }; } private randomDelay(min: number, max: number): number { return Math.floor(Math.random() * (max - min + 1)) + min; } private async sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } private shouldSimulateFailure(): boolean { if (!this.config.simulateFailures) { return false; } return Math.random() < (this.config.failureRate || 0.1); } }