diff --git a/scripts/web-live-dom-probe.mjs b/scripts/web-live-dom-probe.mjs index 7f793572..a14ca3fa 100644 --- a/scripts/web-live-dom-probe.mjs +++ b/scripts/web-live-dom-probe.mjs @@ -203,8 +203,9 @@ async function startProbe(args) { "--screenshot", screenshotPath, "--timeout-ms", String(args.timeoutMs), "--wait-after-submit-ms", String(args.waitAfterSubmitMs), - "--wait-agent-terminal-ms", String(args.waitAgentTerminalMs) + "--wait-messages-ms", String(args.waitMessagesMs) ]; + if (args.waitAgentTerminalMs > 0) childArgs.push("--wait-agent-terminal-ms", String(args.waitAgentTerminalMs)); if (args.freshSession) childArgs.push("--fresh-session"); if (!args.cancelRunning) childArgs.push("--no-cancel-running"); if (args.conversationId) childArgs.push("--conversation-id", args.conversationId); @@ -275,9 +276,30 @@ async function maybeLogin(page, args, actions) { } return; } + const loginSurface = await waitForLoginSurface(page, args); + if (loginSurface === "workspace") { + actions.push({ action: "login", skipped: "already-authenticated", selectorMode: "workspace", authState: await page.locator("body").getAttribute("data-auth-state").catch(() => null) }); + return; + } + if (loginSurface === "legacy-id") { + await username.fill(args.user); + await page.locator("#login-password").fill(args.pass); + await page.locator("#login-submit").click(); + actions.push({ action: "login", user: args.user, selectorMode: "legacy-id-delayed" }); + await page.locator("#command-input").waitFor({ state: "visible", timeout: args.timeoutMs }); + const finalUrl = new URL(page.url()); + if (finalUrl.searchParams.has("username") || finalUrl.searchParams.has("password")) { + throw new Error("login credentials leaked into URL query"); + } + return; + } + if (loginSurface !== "login-card") { + actions.push({ action: "login", skipped: "login-form-not-visible", authState: await page.locator("body").getAttribute("data-auth-state").catch(() => null) }); + return; + } const cardInputs = page.locator(".login-card input"); if ((await cardInputs.count().catch(() => 0)) < 2) { - actions.push({ action: "login", skipped: "login-form-not-visible", authState: await page.locator("body").getAttribute("data-auth-state").catch(() => null) }); + actions.push({ action: "login", skipped: "login-form-incomplete", selectorMode: "login-card", inputCount: await cardInputs.count().catch(() => 0), authState: await page.locator("body").getAttribute("data-auth-state").catch(() => null) }); return; } await cardInputs.nth(0).fill(args.user); @@ -291,6 +313,17 @@ async function maybeLogin(page, args, actions) { } } +async function waitForLoginSurface(page, args) { + const handle = await page.waitForFunction(() => { + if (document.querySelector("#workspace")) return "workspace"; + if (document.querySelector("#login-username")) return "legacy-id"; + if (document.querySelector(".login-card input")) return "login-card"; + return ""; + }, null, { timeout: args.timeoutMs }).catch(() => null); + if (!handle) return null; + return handle.jsonValue().catch(() => null); +} + async function waitForAuthBootstrap(page, args, actions) { const timeout = Math.min(args.timeoutMs, 12000); const settled = await page.waitForFunction(() => {