import assert from 'node:assert/strict'; import test from 'node:test'; import { createOverlayContentMeasurementReporter } from './overlay-content-measurement.js'; function makeElement(textContent: string, rect: DOMRect): HTMLElement { return { textContent, getBoundingClientRect: () => rect, } as unknown as HTMLElement; } test('overlay measurement reports primary and secondary subtitle bars as separate interactive rects', () => { const originalWindow = Object.getOwnPropertyDescriptor(globalThis, 'window'); const reports: unknown[] = []; Object.defineProperty(globalThis, 'window', { configurable: true, writable: true, value: { innerWidth: 1920, innerHeight: 1080, electronAPI: { reportOverlayContentBounds: (payload: unknown) => { reports.push(payload); }, }, }, }); try { const reporter = createOverlayContentMeasurementReporter({ platform: { overlayLayer: 'visible' }, dom: { subtitleRoot: makeElement('primary', { left: 810, top: 910, width: 300, height: 48, } as DOMRect), subtitleContainer: makeElement('primary', { left: 760, top: 890, width: 400, height: 92, } as DOMRect), secondarySubRoot: makeElement('English', { left: 850, top: 50, width: 220, height: 34, } as DOMRect), secondarySubContainer: makeElement('English', { left: 700, top: 40, width: 520, height: 70, } as DOMRect), }, } as never); reporter.emitNow(); const measuredAtMs = (reports[0] as { measuredAtMs?: unknown } | undefined)?.measuredAtMs; if (typeof measuredAtMs !== 'number') { assert.fail('Expected report timestamp.'); } assert.deepEqual(reports, [ { layer: 'visible', measuredAtMs, viewport: { width: 1920, height: 1080 }, contentRect: { x: 700, y: 40, width: 520, height: 942 }, interactiveRects: [ { x: 760, y: 890, width: 400, height: 92 }, { x: 700, y: 40, width: 520, height: 70 }, ], }, ]); } finally { if (originalWindow) { Object.defineProperty(globalThis, 'window', originalWindow); } else { delete (globalThis as { window?: unknown }).window; } } }); test('overlay measurement includes open subtitle sidebar bounds as an interactive rect', () => { const originalWindow = Object.getOwnPropertyDescriptor(globalThis, 'window'); const reports: unknown[] = []; Object.defineProperty(globalThis, 'window', { configurable: true, writable: true, value: { innerWidth: 1920, innerHeight: 1080, electronAPI: { reportOverlayContentBounds: (payload: unknown) => { reports.push(payload); }, }, }, }); try { const reporter = createOverlayContentMeasurementReporter({ platform: { overlayLayer: 'visible' }, state: { subtitleSidebarModalOpen: true }, dom: { subtitleRoot: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), subtitleContainer: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), secondarySubRoot: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), secondarySubContainer: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), subtitleSidebarContent: makeElement('sidebar', { left: 1500, top: 60, width: 380, height: 900, } as DOMRect), }, } as never); reporter.emitNow(); const measuredAtMs = (reports[0] as { measuredAtMs?: unknown } | undefined)?.measuredAtMs; if (typeof measuredAtMs !== 'number') { assert.fail('Expected report timestamp.'); } assert.deepEqual(reports, [ { layer: 'visible', measuredAtMs, viewport: { width: 1920, height: 1080 }, contentRect: { x: 1500, y: 60, width: 380, height: 900 }, interactiveRects: [{ x: 1500, y: 60, width: 380, height: 900 }], }, ]); } finally { if (originalWindow) { Object.defineProperty(globalThis, 'window', originalWindow); } else { delete (globalThis as { window?: unknown }).window; } } }); test('overlay measurement includes overlay notification stack bounds as an interactive rect', () => { const originalWindow = Object.getOwnPropertyDescriptor(globalThis, 'window'); const reports: unknown[] = []; Object.defineProperty(globalThis, 'window', { configurable: true, writable: true, value: { innerWidth: 1920, innerHeight: 1080, electronAPI: { reportOverlayContentBounds: (payload: unknown) => { reports.push(payload); }, }, }, }); try { const reporter = createOverlayContentMeasurementReporter({ platform: { overlayLayer: 'visible' }, state: { subtitleSidebarModalOpen: false }, dom: { subtitleRoot: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), subtitleContainer: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), secondarySubRoot: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), secondarySubContainer: makeElement('', { left: 0, top: 0, width: 0, height: 0, } as DOMRect), overlayNotificationStack: { children: [{}, {}], getBoundingClientRect: () => ({ left: 1540, top: 16, width: 360, height: 220, }) as DOMRect, }, }, } as never); reporter.emitNow(); const measuredAtMs = (reports[0] as { measuredAtMs?: unknown } | undefined)?.measuredAtMs; if (typeof measuredAtMs !== 'number') { assert.fail('Expected report timestamp.'); } assert.deepEqual(reports, [ { layer: 'visible', measuredAtMs, viewport: { width: 1920, height: 1080 }, contentRect: { x: 1540, y: 16, width: 360, height: 220 }, interactiveRects: [{ x: 1540, y: 16, width: 360, height: 220 }], }, ]); } finally { if (originalWindow) { Object.defineProperty(globalThis, 'window', originalWindow); } else { delete (globalThis as { window?: unknown }).window; } } });