Files
pikasTech-HWLAB/web/hwlab-cloud-web/tests/workbench-e2e/specs/live-backfill-race.spec.ts
T

65 lines
4.1 KiB
TypeScript

import { expect, gotoWorkbench, saveScreenshot, test } from "../fixtures/test";
import { selectors, sessionTab } from "../fixtures/selectors";
test.describe("live REST backfill without terminal SSE", () => {
test.use({ scenarioId: "live-rest-backfill-without-terminal-sse" });
test("submitted turn catches completed AgentRun projection without switching sessions", async ({ page }, testInfo) => {
await gotoWorkbench(page, "/workbench/sessions/ses_completed");
await page.locator(selectors.commandInput).fill("p0 1189 live backfill race: reply OK and run one command");
await expect(page.locator(selectors.commandSend)).toBeEnabled();
await page.locator(selectors.commandSend).click();
await expect(page.locator(sessionTab("ses_completed"))).toHaveAttribute("data-active", "true");
await expect(page.locator(`${selectors.messageCard}[data-role="agent"][data-status="running"]`).last()).toBeVisible();
await saveScreenshot(page, testInfo, "live-backfill-submitted");
await expect.poll(async () => {
const response = await page.request.get("/v1/workbench/turns/trc_live_backfill");
return response.ok() ? ((await response.json()).turn?.status as string | undefined) : undefined;
}).toBe("completed");
const turnResponse = await page.request.get("/v1/workbench/turns/trc_live_backfill");
expect(turnResponse.ok()).toBe(true);
const turnPayload = await turnResponse.json() as {
turn?: {
running?: boolean;
terminal?: boolean;
agentRun?: { runStatus?: string; commandState?: string; terminalStatus?: string | null; namespace?: string };
traceSummary?: { source?: string; terminalStatus?: string };
};
};
expect(turnPayload.turn?.running).toBe(false);
expect(turnPayload.turn?.terminal).toBe(true);
expect(turnPayload.turn?.agentRun?.runStatus).toBe("claimed");
expect(turnPayload.turn?.agentRun?.commandState).toBe("completed");
expect(turnPayload.turn?.agentRun?.terminalStatus).toBe("completed");
expect(turnPayload.turn?.agentRun?.namespace).toBe("agentrun-v02");
expect(turnPayload.turn?.traceSummary?.source).toBe("agentrun-command-result");
expect(turnPayload.turn?.traceSummary?.terminalStatus).toBe("completed");
const listResponse = await page.request.get("/v1/workbench/sessions?includeSessionId=ses_completed");
const messagesResponse = await page.request.get("/v1/workbench/sessions/ses_completed/messages?limit=100");
expect(listResponse.ok()).toBe(true);
expect(messagesResponse.ok()).toBe(true);
const listPayload = await listResponse.json() as { sessions?: Array<{ sessionId?: string; status?: string; running?: boolean }> };
const messagesPayload = await messagesResponse.json() as { messages?: Array<{ role?: string; traceId?: string; status?: string; text?: string }> };
const sessionSummary = listPayload.sessions?.find((session) => session.sessionId === "ses_completed");
const assistantMessage = messagesPayload.messages?.find((message) => message.role === "agent" && message.traceId === "trc_live_backfill");
expect(sessionSummary?.status).toBe("completed");
expect(sessionSummary?.running).toBe(false);
expect(assistantMessage?.status).toBe("completed");
expect(assistantMessage?.text).toContain("fake AgentRun completed after REST backfill");
await saveScreenshot(page, testInfo, "live-backfill-canonical-completed");
await expect(page.locator(sessionTab("ses_completed"))).toHaveAttribute("data-active", "true");
await expect(page.locator(sessionTab("ses_completed"))).toHaveAttribute("data-status", "completed");
const backfilledFinal = page.locator(`${selectors.messageCard}[data-role="agent"]`).filter({ hasText: "fake AgentRun completed after REST backfill" });
await expect(backfilledFinal).toHaveAttribute("data-status", "completed");
await expect(page.locator(`${selectors.traceTimeline}[data-status="completed"]`).last()).toBeVisible();
await expect(page.locator(selectors.commandSend)).toHaveAttribute("data-action", "turn");
await saveScreenshot(page, testInfo, "live-backfill-ui-completed");
});
});