// A passkey step in a bot's browser on today's engine (agent-browser), started as the server starts it: through the // generated launcher and the identity connection, headless. The step's request must end at once, as a dismissed passkey // sheet does, so the page's own "Try another way" works. Runs where browser-identity.e2e.test.ts runs. import { mkdtempSync } from "node:fs"; import { tmpdir, userInfo } from "node:os"; import { join } from "node:path"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { resolveAgentBrowserBinary } from "../../server/browser-engine.ts"; import { FixtureServer } from "../../server/browser/cdp/testing/fixtures.ts"; import { ChromeLauncher } from "../../server/browser/chrome/launcher.ts"; import { chromeHost, installedGoogleChrome, isHeadlessShell } from "../../server/browser/chrome/resolve.ts"; import { removeTempDir } from "../../server/testing/cleanup.ts"; import { openOwnPageAsBot, withBotBrowser, type BotCall } from "../verify-browser-identity.ts"; import { ensureUiBrowser, UI_TOOLS_DIR } from "./control-omb-ui.ts"; const enabled = process.env.OMB_UI_E2E === "1" || Boolean(resolveAgentBrowserBinary({ dataDir: UI_TOOLS_DIR, env: process.env })); if (!enabled) console.log("skipping browser passkey e2e: no agent-browser binary resolves; set OMB_UI_E2E=1 to install the pinned release"); const out = mkdtempSync(join(tmpdir(), "omb-passkey-e2e-")); const home = userInfo().homedir; const machineEnv = { ...process.env, HOME: home, USERPROFILE: home }; /** The step's request, and what the page shows once it ends. WebAuthn needs a registrable RP ID: localhost, not 127.0.0.1. */ const PASSKEY_STEP = `
Complete sign-in using your passkey
Try another wayWaiting…
`; afterAll(async () => { await removeTempDir(out); }); function text(result: unknown): string { const answer = result as { content?: Array<{ type?: string; text?: string }>; isError?: boolean } | null; if (!answer || answer.isError) throw new Error(`the tool call failed: ${JSON.stringify(result).slice(0, 300)}`); return (answer.content ?? []).map((part) => part.text ?? "").join("\n"); } async function pageSays(call: BotCall, expression: string, wanted: (value: string) => boolean, timeoutMs = 5_000): Promise