import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { loadAutomationConfig, getAutomationMode, AutomationMode } from '../../../packages/infrastructure/config/AutomationConfig'; describe('AutomationConfig', () => { const originalEnv = process.env; beforeEach(() => { // Reset environment before each test process.env = { ...originalEnv }; }); afterEach(() => { // Restore original environment process.env = originalEnv; }); describe('getAutomationMode', () => { describe('NODE_ENV-based mode detection', () => { it('should return development mode when NODE_ENV=development', () => { process.env.NODE_ENV = 'development'; delete process.env.AUTOMATION_MODE; const mode = getAutomationMode(); expect(mode).toBe('development'); }); it('should return production mode when NODE_ENV=production', () => { process.env.NODE_ENV = 'production'; delete process.env.AUTOMATION_MODE; const mode = getAutomationMode(); expect(mode).toBe('production'); }); it('should return test mode when NODE_ENV=test', () => { process.env.NODE_ENV = 'test'; delete process.env.AUTOMATION_MODE; const mode = getAutomationMode(); expect(mode).toBe('test'); }); it('should return development mode when NODE_ENV is not set', () => { delete process.env.NODE_ENV; delete process.env.AUTOMATION_MODE; const mode = getAutomationMode(); expect(mode).toBe('development'); }); it('should return development mode for unknown NODE_ENV values', () => { process.env.NODE_ENV = 'staging'; delete process.env.AUTOMATION_MODE; const mode = getAutomationMode(); expect(mode).toBe('development'); }); }); describe('legacy AUTOMATION_MODE support', () => { it('should map legacy dev mode to development with deprecation warning', () => { process.env.AUTOMATION_MODE = 'dev'; const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const mode = getAutomationMode(); expect(mode).toBe('development'); expect(consoleSpy).toHaveBeenCalledWith( expect.stringContaining('[DEPRECATED] AUTOMATION_MODE') ); consoleSpy.mockRestore(); }); it('should map legacy mock mode to test with deprecation warning', () => { process.env.AUTOMATION_MODE = 'mock'; const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const mode = getAutomationMode(); expect(mode).toBe('test'); expect(consoleSpy).toHaveBeenCalledWith( expect.stringContaining('[DEPRECATED] AUTOMATION_MODE') ); consoleSpy.mockRestore(); }); it('should map legacy production mode to production with deprecation warning', () => { process.env.AUTOMATION_MODE = 'production'; const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const mode = getAutomationMode(); expect(mode).toBe('production'); expect(consoleSpy).toHaveBeenCalledWith( expect.stringContaining('[DEPRECATED] AUTOMATION_MODE') ); consoleSpy.mockRestore(); }); it('should ignore invalid AUTOMATION_MODE and use NODE_ENV', () => { process.env.AUTOMATION_MODE = 'invalid-mode'; process.env.NODE_ENV = 'production'; const mode = getAutomationMode(); expect(mode).toBe('production'); }); }); }); describe('loadAutomationConfig', () => { describe('default configuration', () => { it('should return development mode when NODE_ENV is not set', () => { delete process.env.NODE_ENV; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('development'); }); it('should return default devTools configuration', () => { const config = loadAutomationConfig(); expect(config.devTools?.debuggingPort).toBe(9222); expect(config.devTools?.browserWSEndpoint).toBeUndefined(); }); it('should return default nutJs configuration', () => { const config = loadAutomationConfig(); expect(config.nutJs?.windowTitle).toBe('iRacing'); expect(config.nutJs?.templatePath).toBe('./resources/templates'); expect(config.nutJs?.confidence).toBe(0.9); }); it('should return default shared settings', () => { const config = loadAutomationConfig(); expect(config.defaultTimeout).toBe(30000); expect(config.retryAttempts).toBe(3); expect(config.screenshotOnError).toBe(true); }); it('should return default fixture server configuration', () => { delete process.env.NODE_ENV; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.fixtureServer?.port).toBe(3456); expect(config.fixtureServer?.autoStart).toBe(true); expect(config.fixtureServer?.fixturesPath).toBe('./resources/iracing-hosted-sessions'); }); }); describe('development mode configuration', () => { it('should return development mode when NODE_ENV=development', () => { process.env.NODE_ENV = 'development'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('development'); }); it('should parse CHROME_DEBUG_PORT', () => { process.env.CHROME_DEBUG_PORT = '9333'; const config = loadAutomationConfig(); expect(config.devTools?.debuggingPort).toBe(9333); }); it('should read CHROME_WS_ENDPOINT', () => { process.env.CHROME_WS_ENDPOINT = 'ws://127.0.0.1:9222/devtools/browser/abc123'; const config = loadAutomationConfig(); expect(config.devTools?.browserWSEndpoint).toBe('ws://127.0.0.1:9222/devtools/browser/abc123'); }); }); describe('production mode configuration', () => { it('should return production mode when NODE_ENV=production', () => { process.env.NODE_ENV = 'production'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('production'); }); it('should parse IRACING_WINDOW_TITLE', () => { process.env.IRACING_WINDOW_TITLE = 'iRacing Simulator'; const config = loadAutomationConfig(); expect(config.nutJs?.windowTitle).toBe('iRacing Simulator'); }); it('should parse TEMPLATE_PATH', () => { process.env.TEMPLATE_PATH = '/custom/templates'; const config = loadAutomationConfig(); expect(config.nutJs?.templatePath).toBe('/custom/templates'); }); it('should parse OCR_CONFIDENCE', () => { process.env.OCR_CONFIDENCE = '0.85'; const config = loadAutomationConfig(); expect(config.nutJs?.confidence).toBe(0.85); }); }); describe('environment variable parsing', () => { it('should parse AUTOMATION_TIMEOUT', () => { process.env.AUTOMATION_TIMEOUT = '60000'; const config = loadAutomationConfig(); expect(config.defaultTimeout).toBe(60000); }); it('should parse RETRY_ATTEMPTS', () => { process.env.RETRY_ATTEMPTS = '5'; const config = loadAutomationConfig(); expect(config.retryAttempts).toBe(5); }); it('should parse SCREENSHOT_ON_ERROR=false', () => { process.env.SCREENSHOT_ON_ERROR = 'false'; const config = loadAutomationConfig(); expect(config.screenshotOnError).toBe(false); }); it('should parse SCREENSHOT_ON_ERROR=true', () => { process.env.SCREENSHOT_ON_ERROR = 'true'; const config = loadAutomationConfig(); expect(config.screenshotOnError).toBe(true); }); it('should fallback to defaults for invalid integer values', () => { process.env.CHROME_DEBUG_PORT = 'invalid'; process.env.AUTOMATION_TIMEOUT = 'not-a-number'; process.env.RETRY_ATTEMPTS = ''; const config = loadAutomationConfig(); expect(config.devTools?.debuggingPort).toBe(9222); expect(config.defaultTimeout).toBe(30000); expect(config.retryAttempts).toBe(3); }); it('should fallback to defaults for invalid float values', () => { process.env.OCR_CONFIDENCE = 'invalid'; const config = loadAutomationConfig(); expect(config.nutJs?.confidence).toBe(0.9); }); it('should fallback to development mode for invalid NODE_ENV', () => { process.env.NODE_ENV = 'invalid-env'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('development'); }); }); describe('fixture server configuration', () => { it('should auto-start fixture server in development mode', () => { process.env.NODE_ENV = 'development'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.fixtureServer?.autoStart).toBe(true); }); it('should not auto-start fixture server in production mode', () => { process.env.NODE_ENV = 'production'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.fixtureServer?.autoStart).toBe(false); }); it('should not auto-start fixture server in test mode', () => { process.env.NODE_ENV = 'test'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.fixtureServer?.autoStart).toBe(false); }); it('should parse FIXTURE_SERVER_PORT', () => { process.env.FIXTURE_SERVER_PORT = '4567'; const config = loadAutomationConfig(); expect(config.fixtureServer?.port).toBe(4567); }); it('should parse FIXTURE_SERVER_PATH', () => { process.env.FIXTURE_SERVER_PATH = '/custom/fixtures'; const config = loadAutomationConfig(); expect(config.fixtureServer?.fixturesPath).toBe('/custom/fixtures'); }); it('should respect FIXTURE_SERVER_AUTO_START=false', () => { process.env.NODE_ENV = 'development'; process.env.FIXTURE_SERVER_AUTO_START = 'false'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.fixtureServer?.autoStart).toBe(false); }); }); describe('full configuration scenario', () => { it('should load complete development environment configuration', () => { process.env.NODE_ENV = 'development'; delete process.env.AUTOMATION_MODE; process.env.CHROME_DEBUG_PORT = '9222'; process.env.CHROME_WS_ENDPOINT = 'ws://localhost:9222/devtools/browser/test'; process.env.AUTOMATION_TIMEOUT = '45000'; process.env.RETRY_ATTEMPTS = '2'; process.env.SCREENSHOT_ON_ERROR = 'true'; process.env.FIXTURE_SERVER_PORT = '3456'; process.env.FIXTURE_SERVER_PATH = './resources/iracing-hosted-sessions'; const config = loadAutomationConfig(); expect(config).toEqual({ mode: 'development', devTools: { debuggingPort: 9222, browserWSEndpoint: 'ws://localhost:9222/devtools/browser/test', }, nutJs: { mouseSpeed: 1000, keyboardDelay: 50, windowTitle: 'iRacing', templatePath: './resources/templates', confidence: 0.9, }, fixtureServer: { port: 3456, autoStart: true, fixturesPath: './resources/iracing-hosted-sessions', }, defaultTimeout: 45000, retryAttempts: 2, screenshotOnError: true, }); }); it('should load complete test environment configuration', () => { process.env.NODE_ENV = 'test'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('test'); expect(config.devTools).toBeDefined(); expect(config.nutJs).toBeDefined(); expect(config.fixtureServer).toBeDefined(); expect(config.fixtureServer?.autoStart).toBe(false); }); it('should load complete production environment configuration', () => { process.env.NODE_ENV = 'production'; delete process.env.AUTOMATION_MODE; const config = loadAutomationConfig(); expect(config.mode).toBe('production'); expect(config.devTools).toBeDefined(); expect(config.nutJs).toBeDefined(); expect(config.fixtureServer).toBeDefined(); expect(config.fixtureServer?.autoStart).toBe(false); }); }); }); });