This commit is contained in:
2025-12-12 21:39:48 +01:00
parent ddbd99b747
commit cae81b1088
49 changed files with 777 additions and 269 deletions

View File

@@ -3,7 +3,7 @@ import { DIContainer } from '../../apps/companion/main/di-container';
test('renderer -> preload -> main: set/get updates BrowserModeConfigLoader (reproduces headless-toggle bug)', () => {
// Ensure environment is development so toggle is available
process.env.NODE_ENV = 'development';
(process.env as any).NODE_ENV = 'development';
// Provide a minimal electron.app mock so DIContainer can resolve paths in node test environment
// This avoids calling the real Electron runtime during unit/runner tests.

View File

@@ -23,7 +23,7 @@ vi.mock('electron', () => ({
describe('Electron DIContainer Smoke Tests', () => {
beforeEach(() => {
(DIContainer as typeof DIContainer & { instance?: unknown }).instance = undefined;
(DIContainer as unknown as { instance?: unknown }).instance = undefined;
});
it('DIContainer initializes without errors', () => {

View File

@@ -52,12 +52,15 @@ export class ConsoleMonitor {
// Monitor uncaught exceptions
page.on('pageerror', (error: Error) => {
this.errors.push({
const errorObj: ConsoleError = {
type: 'pageerror',
message: error.message,
location: error.stack,
timestamp: new Date(),
});
};
if (error.stack) {
errorObj.location = error.stack;
}
this.errors.push(errorObj);
});
this.isMonitoring = true;

View File

@@ -22,19 +22,21 @@ export class ElectronTestHarness {
async launch(): Promise<void> {
// Path to the built Electron app entry point
const electronEntryPath = path.join(__dirname, '../../../apps/companion/dist/main/main.cjs');
// Launch Electron app with the compiled entry file
// Note: Playwright may have compatibility issues with certain Electron versions
// regarding --remote-debugging-port flag
this.app = await electron.launch({
const launchOptions: any = {
args: [electronEntryPath],
env: {
...process.env,
...Object.fromEntries(Object.entries(process.env).filter(([_, v]) => v !== undefined)),
NODE_ENV: 'test',
},
// Try to disable Chrome DevTools Protocol features that might conflict
executablePath: process.env.ELECTRON_EXECUTABLE_PATH,
});
};
if (process.env.ELECTRON_EXECUTABLE_PATH) {
launchOptions.executablePath = process.env.ELECTRON_EXECUTABLE_PATH;
}
this.app = await electron.launch(launchOptions);
// Wait for first window (renderer process)
this.mainWindow = await this.app.firstWindow({

View File

@@ -61,12 +61,15 @@ export class IPCVerifier {
const typed: IpcHandlerResult = result as IpcHandlerResult;
return {
const resultObj: IPCTestResult = {
channel,
success: !typed.error,
error: typed.error,
duration: Date.now() - start,
};
if (typed.error) {
resultObj.error = typed.error;
}
return resultObj;
} catch (error) {
return {
channel,
@@ -114,12 +117,15 @@ export class IPCVerifier {
const typed: IpcHandlerResult = result as IpcHandlerResult;
return {
const resultObj: IPCTestResult = {
channel,
success: !typed.error,
error: typed.error,
duration: Date.now() - start,
};
if (typed.error) {
resultObj.error = typed.error;
}
return resultObj;
} catch (error) {
return {
channel,
@@ -173,12 +179,15 @@ export class IPCVerifier {
const typed: IpcHandlerResult = result as IpcHandlerResult;
return {
const resultObj: IPCTestResult = {
channel,
success: !typed.error,
error: typed.error,
duration: Date.now() - start,
};
if (typed.error) {
resultObj.error = typed.error;
}
return resultObj;
} catch (error) {
return {
channel,

View File

@@ -1,10 +1,12 @@
import { describe, it, expect, afterEach, beforeAll, afterAll } from 'vitest';
import { PlaywrightAutomationAdapter, FixtureServer } from 'packages/automation/infrastructure/adapters/automation';
import { NoOpLogAdapter } from '../../packages/automation/infrastructure/adapters/logging/NoOpLogAdapter';
describe('Playwright Adapter Smoke Tests', () => {
let adapter: PlaywrightAutomationAdapter | undefined;
let server: FixtureServer | undefined;
let unhandledRejectionHandler: ((reason: unknown) => void) | null = null;
const logger = new NoOpLogAdapter();
beforeAll(() => {
unhandledRejectionHandler = (reason: unknown) => {
@@ -15,7 +17,7 @@ describe('Playwright Adapter Smoke Tests', () => {
}
throw reason;
};
process.on('unhandledRejection', unhandledRejectionHandler);
(process as any).on('unhandledRejection', unhandledRejectionHandler);
});
afterEach(async () => {
@@ -39,7 +41,7 @@ describe('Playwright Adapter Smoke Tests', () => {
afterAll(() => {
if (unhandledRejectionHandler) {
process.removeListener('unhandledRejection', unhandledRejectionHandler);
(process as any).removeListener('unhandledRejection', unhandledRejectionHandler);
unhandledRejectionHandler = null;
}
});
@@ -50,7 +52,7 @@ describe('Playwright Adapter Smoke Tests', () => {
headless: true,
mode: 'mock',
timeout: 5000,
});
}, logger);
}).not.toThrow();
});
@@ -59,7 +61,7 @@ describe('Playwright Adapter Smoke Tests', () => {
headless: true,
mode: 'mock',
timeout: 5000,
});
}, logger);
const result = await adapter.connect();
expect(result.success).toBe(true);
@@ -74,7 +76,7 @@ describe('Playwright Adapter Smoke Tests', () => {
headless: true,
mode: 'mock',
timeout: 5000,
});
}, logger);
await adapter.connect();
const navResult = await adapter.navigateToPage(server.getFixtureUrl(2));
@@ -87,12 +89,12 @@ describe('Playwright Adapter Smoke Tests', () => {
headless: true,
mode: 'mock',
timeout: 5000,
});
}, logger);
const adapter2 = new PlaywrightAutomationAdapter({
headless: true,
mode: 'mock',
timeout: 5000,
});
}, logger);
expect(adapter1).not.toBe(adapter2);
}).not.toThrow();
});