feat(overlay-sync): wire OverlaySyncService into DI, IPC and renderer gating

This commit is contained in:
2025-11-26 19:14:25 +01:00
parent d08f9e5264
commit 1d7c4f78d1
20 changed files with 611 additions and 561 deletions

View File

@@ -0,0 +1,31 @@
import { jest } from '@jest/globals'
import { MockAutomationLifecycleEmitter } from '../mocks/MockAutomationLifecycleEmitter'
import { PlaywrightAutomationAdapter } from '../../../packages/infrastructure/adapters/automation/PlaywrightAutomationAdapter'
describe('CarsFlow integration', () => {
test('adapter emits panel-attached then action-started then action-complete for performAddCar', async () => {
const adapter = new PlaywrightAutomationAdapter({} as any)
const received: any[] = []
adapter.onLifecycle?.((e: any) => { received.push(e) })
// Use mock page fixture: minimal object with required methods
const mockPage: any = {
waitForSelector: async () => {},
evaluate: async () => {},
waitForTimeout: async () => {},
click: async () => {},
setDefaultTimeout: () => {},
}
// call attachPanel which emits panel-attached and then action-started
await adapter.attachPanel(mockPage, 'add-car')
// simulate complete event
await adapter.emitLifecycle?.({ type: 'action-complete', actionId: 'add-car', timestamp: Date.now() } as any)
const types = received.map(r => r.type)
expect(types.indexOf('panel-attached')).toBeGreaterThanOrEqual(0)
expect(types.indexOf('action-started')).toBeGreaterThanOrEqual(0)
expect(types.indexOf('action-complete')).toBeGreaterThanOrEqual(0)
})
})

View File

@@ -0,0 +1,22 @@
import { jest } from '@jest/globals'
import { MockAutomationLifecycleEmitter } from '../mocks/MockAutomationLifecycleEmitter'
import { OverlaySyncService } from '../../packages/application/services/OverlaySyncService'
describe('renderer overlay integration', () => {
test('renderer shows confirmed only after main acks confirmed', async () => {
const emitter = new MockAutomationLifecycleEmitter()
const publisher = { publish: async () => {} }
const svc = new OverlaySyncService({ lifecycleEmitter: emitter as any, publisher: publisher as any, logger: console as any })
// simulate renderer request
const promise = svc.startAction({ id: 'add-car', label: 'Adding...' })
// ack should be tentative until emitter emits action-started
await new Promise((r) => setTimeout(r, 20))
const tentative = await Promise.race([promise, Promise.resolve({ id: 'add-car', status: 'tentative' })])
// since no events yet, should still be pending promise; but we assert tentative fallback works after timeout in other tests
emitter.emit({ type: 'action-started', actionId: 'add-car', timestamp: Date.now() })
const ack = await promise
expect(ack.status).toBe('confirmed')
})
})