fix: polish hwpod groups and performance probes (#1494)
This commit is contained in:
@@ -311,6 +311,17 @@ export async function runProbe(args) {
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const finalUrl = page ? page.url() : null;
|
||||
const failureDom = page ? await collectFailureDomEvidence(page).catch((domError) => ({ error: domError instanceof Error ? domError.message : String(domError) })) : null;
|
||||
let screenshotCapture = null;
|
||||
if (page && !page.isClosed()) {
|
||||
try {
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
screenshotCapture = { ok: true };
|
||||
} catch (screenshotError) {
|
||||
screenshotCapture = { ok: false, error: screenshotError instanceof Error ? screenshotError.message : String(screenshotError) };
|
||||
}
|
||||
}
|
||||
result = {
|
||||
ok: false,
|
||||
status: "blocked",
|
||||
@@ -322,10 +333,10 @@ export async function runProbe(args) {
|
||||
actions,
|
||||
credentials: args.credentials,
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
degradedReason: classifyRunProbeError(error),
|
||||
finalUrl: page ? page.url() : null,
|
||||
failureDom: page ? await collectFailureDomEvidence(page).catch((domError) => ({ error: domError instanceof Error ? domError.message : String(domError) })) : null,
|
||||
artifacts: { reportPath, screenshotPath }
|
||||
degradedReason: classifyRunProbeError(error, { finalUrl, failureDom }),
|
||||
finalUrl,
|
||||
failureDom,
|
||||
artifacts: { reportPath, screenshotPath, screenshotCapture }
|
||||
};
|
||||
} finally {
|
||||
if (browser) await browser.close().catch(() => {});
|
||||
@@ -889,12 +900,16 @@ async function submitPrompt(page, args, actions) {
|
||||
const targetConversationId = firstNonEmpty(fresh?.alignment?.check?.conversationId, fresh?.alignment?.after?.routeConversationId, fresh?.after?.routeConversationId);
|
||||
if (targetConversationId) await ensureConversationAligned(page, args, targetConversationId, actions, "pre-submit-realign");
|
||||
await page.locator("#command-input").fill(args.message);
|
||||
await page.waitForFunction((expected) => {
|
||||
const enabled = await page.waitForFunction((expected) => {
|
||||
const input = document.querySelector("#command-input");
|
||||
const send = document.querySelector("#command-send");
|
||||
return input?.value === expected && send && !send.disabled;
|
||||
}, args.message, { timeout: Math.min(args.timeoutMs, 5000) });
|
||||
}, args.message, { timeout: Math.min(args.timeoutMs, 5000) }).catch(() => null);
|
||||
const afterFill = await collectCommandState(page);
|
||||
if (!enabled) {
|
||||
const session = await collectSessionState(page, args).catch((error) => ({ error: error instanceof Error ? error.message : String(error) }));
|
||||
throw new Error(`command composer is not ready for submit: ${JSON.stringify({ readyBefore, afterFill, session: compactSessionState(session) })}`);
|
||||
}
|
||||
const submittedAt = new Date().toISOString();
|
||||
await page.locator("#command-send").click();
|
||||
const afterClick = await collectCommandState(page);
|
||||
@@ -1132,8 +1147,14 @@ function runProbeDegradedReason({ traceSummary, sessionSummary, promptValidation
|
||||
return null;
|
||||
}
|
||||
|
||||
function classifyRunProbeError(error) {
|
||||
function classifyRunProbeError(error, context = {}) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
const finalUrl = typeof context.finalUrl === "string" ? context.finalUrl : "";
|
||||
const failureDom = context.failureDom && typeof context.failureDom === "object" ? context.failureDom : {};
|
||||
const login = failureDom.login && typeof failureDom.login === "object" ? failureDom.login : {};
|
||||
if (/\/login(?:\?|$)/u.test(finalUrl) || failureDom.authState === "login" || login.cardVisible === true) return "auth-redirect-login";
|
||||
if (/session_required|session-not-selected/u.test(message)) return "session-not-selected";
|
||||
if (/composer|command-send|command bar|disabledReason|button_disabled/u.test(message)) return "composer-disabled";
|
||||
if (/fresh session/u.test(message)) return "fresh-session-not-aligned";
|
||||
if (/login|auth/u.test(message)) return "auth-login-failed";
|
||||
if (/Timeout|timed out|timeout/u.test(message)) return "browser-timeout";
|
||||
@@ -1159,12 +1180,13 @@ async function waitForCommandReady(page, args, actions) {
|
||||
const ready = await page.waitForFunction(() => {
|
||||
const input = document.querySelector("#command-input");
|
||||
const send = document.querySelector("#command-send");
|
||||
return Boolean(input && send && !input.disabled);
|
||||
const warning = document.querySelector(".composer-warning")?.textContent?.trim() ?? "";
|
||||
return Boolean(input && send && !input.disabled && !warning);
|
||||
}, null, { timeout: timeoutMs }).catch(() => null);
|
||||
const after = await collectCommandState(page);
|
||||
const result = { action: "command-ready", ready: Boolean(ready), timeoutMs, before, after };
|
||||
actions.push(result);
|
||||
if (!ready) throw new Error(`command bar is not ready for submit: ${JSON.stringify(result)}`);
|
||||
if (!ready) throw new Error(`command composer is not ready for submit: ${JSON.stringify(result)}`);
|
||||
return after;
|
||||
}
|
||||
|
||||
@@ -1179,6 +1201,9 @@ async function collectCommandState(page) {
|
||||
inputLength: input && typeof input.value === "string" ? input.value.length : null,
|
||||
sendVisible: Boolean(send),
|
||||
sendDisabled: send ? Boolean(send.disabled) : null,
|
||||
sendAction: send?.getAttribute("data-action") ?? null,
|
||||
disabledReason: document.querySelector(".composer-warning")?.textContent?.trim() ?? null,
|
||||
modeText: document.querySelector(".composer-mode")?.textContent?.trim() ?? null,
|
||||
sendText: send?.textContent?.trim() ?? null,
|
||||
formTitle: form?.getAttribute("title") ?? null,
|
||||
messageCount: document.querySelectorAll(".message-card").length,
|
||||
|
||||
Reference in New Issue
Block a user