import { expect, type Page } from '@playwright/test'; /** Read how many signaling managers are currently connected for this page. */ export async function getConnectedSignalManagerCount(page: Page): Promise { return page.evaluate(() => { interface AngularDebugApi { getComponent: (element: Element) => Record; } const host = document.querySelector('app-rooms-side-panel'); const debugApi = (window as { ng?: AngularDebugApi }).ng; if (!host || !debugApi?.getComponent) { return 0; } const component = debugApi.getComponent(host); const realtime = component['realtime'] as { signalingTransportHandler?: { getConnectedSignalingManagers?: () => unknown[]; }; } | undefined; return realtime?.signalingTransportHandler?.getConnectedSignalingManagers?.().length ?? 0; }); } /** * Dual-signal setups create one RTCPeerConnection per remote peer per active * signaling manager, so the harness tracks `remotePeerCount * signalCount` * connected peer connections. */ export async function waitForConnectedRemotePeerMesh( page: Page, remotePeerCount: number, timeout = 45_000 ): Promise { const signalCount = Math.max(await getConnectedSignalManagerCount(page), 1); const expectedCount = remotePeerCount * signalCount; const minimumCount = Math.max(remotePeerCount, expectedCount - signalCount); await page.waitForFunction( (min) => ((window as unknown as { __rtcConnections?: RTCPeerConnection[]; }).__rtcConnections ?? []).filter( (pc) => pc.connectionState === 'connected' ).length >= min, minimumCount, { timeout } ); } export async function getMinimumConnectedPeerMeshCount( page: Page, remotePeerCount: number ): Promise { const signalCount = Math.max(await getConnectedSignalManagerCount(page), 1); const expectedCount = remotePeerCount * signalCount; return Math.max(remotePeerCount, expectedCount - signalCount); } export async function waitForConnectedSignalManagerCount( page: Page, expectedCount: number, timeout = 30_000 ): Promise { await expect.poll(async () => await getConnectedSignalManagerCount(page), { timeout, intervals: [500, 1_000] }).toBe(expectedCount); }