Files
gridpilot.gg/tests/integration/infrastructure/MockBrowserAutomationAdapter.test.ts

282 lines
8.1 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { MockBrowserAutomationAdapter } from '../../../packages/infrastructure/adapters/automation/MockBrowserAutomationAdapter';
import { StepId } from '../../../packages/domain/value-objects/StepId';
describe('MockBrowserAutomationAdapter Integration Tests', () => {
let adapter: MockBrowserAutomationAdapter;
beforeEach(() => {
adapter = new MockBrowserAutomationAdapter();
});
describe('navigateToPage', () => {
it('should simulate navigation with delay', async () => {
const url = 'https://members.iracing.com/membersite/HostedRacing';
const result = await adapter.navigateToPage(url);
expect(result.success).toBe(true);
expect(result.loadTime).toBeGreaterThan(0);
});
it('should return navigation URL in result', async () => {
const url = 'https://members.iracing.com/membersite/HostedRacing';
const result = await adapter.navigateToPage(url);
expect(result.url).toBe(url);
});
it('should simulate realistic delays', async () => {
const url = 'https://members.iracing.com/membersite/HostedRacing';
const result = await adapter.navigateToPage(url);
expect(result.loadTime).toBeGreaterThanOrEqual(200);
expect(result.loadTime).toBeLessThanOrEqual(800);
});
});
describe('fillFormField', () => {
it('should simulate form field fill with delay', async () => {
const fieldName = 'session-name';
const value = 'Test Race Session';
const result = await adapter.fillFormField(fieldName, value);
expect(result.success).toBe(true);
expect(result.fieldName).toBe(fieldName);
expect(result.valueSet).toBe(value);
});
it('should simulate typing speed delay', async () => {
const fieldName = 'session-name';
const value = 'A'.repeat(50);
const result = await adapter.fillFormField(fieldName, value);
expect(result.valueSet).toBeDefined();
});
it('should handle empty field values', async () => {
const fieldName = 'session-name';
const value = '';
const result = await adapter.fillFormField(fieldName, value);
expect(result.success).toBe(true);
expect(result.valueSet).toBe('');
});
});
describe('clickElement', () => {
it('should simulate button click with delay', async () => {
const selector = '#create-session-button';
const result = await adapter.clickElement(selector);
expect(result.success).toBe(true);
expect(result.target).toBe(selector);
});
it('should simulate click delays', async () => {
const selector = '#submit-button';
const result = await adapter.clickElement(selector);
expect(result.target).toBeDefined();
});
});
describe('waitForElement', () => {
it('should simulate waiting for element to appear', async () => {
const selector = '.modal-dialog';
const result = await adapter.waitForElement(selector);
expect(result.success).toBe(true);
expect(result.target).toBe(selector);
});
it('should simulate element load time', async () => {
const selector = '.loading-spinner';
const result = await adapter.waitForElement(selector);
expect(result.waitedMs).toBeGreaterThanOrEqual(100);
expect(result.waitedMs).toBeLessThanOrEqual(1000);
});
it('should timeout after maximum wait time', async () => {
const selector = '.non-existent-element';
const maxWaitMs = 5000;
const result = await adapter.waitForElement(selector, maxWaitMs);
expect(result.success).toBe(true);
});
});
describe('handleModal', () => {
it('should simulate modal handling for step 6', async () => {
const stepId = StepId.create(6);
const action = 'close';
const result = await adapter.handleModal(stepId, action);
expect(result.success).toBe(true);
expect(result.stepId).toBe(6);
expect(result.action).toBe(action);
});
it('should simulate modal handling for step 9', async () => {
const stepId = StepId.create(9);
const action = 'confirm';
const result = await adapter.handleModal(stepId, action);
expect(result.success).toBe(true);
expect(result.stepId).toBe(9);
});
it('should simulate modal handling for step 12', async () => {
const stepId = StepId.create(12);
const action = 'select';
const result = await adapter.handleModal(stepId, action);
expect(result.success).toBe(true);
expect(result.stepId).toBe(12);
});
it('should throw error for non-modal steps', async () => {
const stepId = StepId.create(1);
const action = 'close';
await expect(adapter.handleModal(stepId, action)).rejects.toThrow(
'Step 1 is not a modal step'
);
});
it('should simulate modal interaction delays', async () => {
const stepId = StepId.create(6);
const action = 'close';
const result = await adapter.handleModal(stepId, action);
expect(result.success).toBe(true);
expect(result.stepId).toBe(6);
expect(result.action).toBe(action);
});
});
describe('executeStep', () => {
it('should execute step 1 (navigation)', async () => {
const stepId = StepId.create(1);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapter.executeStep(stepId, config);
expect(result.success).toBe(true);
expect(result.stepId).toBe(1);
});
it('should execute step 6 (modal step)', async () => {
const stepId = StepId.create(6);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapter.executeStep(stepId, config);
expect(result.success).toBe(true);
expect(result.stepId).toBe(6);
expect(result.wasModalStep).toBe(true);
});
it('should execute step 18 (final step)', async () => {
const stepId = StepId.create(18);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapter.executeStep(stepId, config);
expect(result.success).toBe(true);
expect(result.stepId).toBe(18);
expect(result.shouldStop).toBe(true);
});
it('should simulate realistic step execution times', async () => {
const stepId = StepId.create(5);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapter.executeStep(stepId, config);
expect(result.executionTime).toBeGreaterThan(0);
});
});
describe('error simulation', () => {
it('should simulate random failures when enabled', async () => {
const adapterWithFailures = new MockBrowserAutomationAdapter({
simulateFailures: true,
failureRate: 1.0, // Always fail
});
const stepId = StepId.create(5);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
await expect(adapterWithFailures.executeStep(stepId, config)).rejects.toThrow();
});
it('should not fail when failure simulation disabled', async () => {
const adapterNoFailures = new MockBrowserAutomationAdapter({
simulateFailures: false,
});
const stepId = StepId.create(5);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapterNoFailures.executeStep(stepId, config);
expect(result.success).toBe(true);
});
});
describe('performance metrics', () => {
it('should track operation metrics', async () => {
const stepId = StepId.create(1);
const config = {
sessionName: 'Test Race',
trackId: 'spa',
carIds: ['dallara-f3'],
};
const result = await adapter.executeStep(stepId, config);
expect(result.metrics).toBeDefined();
expect(result.metrics.totalDelay).toBeGreaterThan(0);
expect(result.metrics.operationCount).toBeGreaterThan(0);
});
});
});