Files
moeka-project/packages/testing-audio/src/runtimes/prepare-electron.ts
T
2026-08-26 19:49:58 +08:00

47 lines
1.6 KiB
TypeScript

import type { FakemicElectronPrepareContext } from '@proj-airi/vitest-plugin-fakemic'
import type { Page } from 'playwright'
import type { AudioInputSession } from '../types'
import { piniaActionTracingChannelName } from '@proj-airi/stage-shared/types/pinia-action-event'
import { stubForBrowser } from '../setup/browser-probe'
import { createSession } from '../setup/session'
/** Adapts a Fakemic Electron process into an AIRI desktop audio session. */
export default async function prepareElectronRuntime(context: FakemicElectronPrepareContext): Promise<AudioInputSession> {
await context.app.context().addInitScript(stubForBrowser, piniaActionTracingChannelName)
const page = await waitForPage(context, (page) => {
const url = new URL(page.url())
return url.pathname.endsWith('/index.html') && url.hash === '#/'
})
await page.locator('[i-solar\\:alt-arrow-up-line-duotone]').first().waitFor({ state: 'visible', timeout: 30_000 })
await page.evaluate(stubForBrowser, piniaActionTracingChannelName)
return createSession({
close: context.close,
electronApp: context.app,
page,
target: 'electron',
})
}
async function waitForPage(
context: FakemicElectronPrepareContext,
predicate: (page: Page) => boolean,
timeoutMs = 60_000,
): Promise<Page> {
const deadline = Date.now() + timeoutMs
while (Date.now() < deadline) {
const page = context.app.windows().find(predicate)
if (page) {
await page.waitForLoadState('domcontentloaded')
return page
}
await new Promise(resolveWait => setTimeout(resolveWait, 100))
}
throw new Error('Timed out while waiting for the Electron renderer')
}