Files
openworker/surfaces/gui/e2e/seeded-history.spec.ts
T
Devika Verma bd202ad125 e2e: seedSessionMessages seam + replayed-transcript specs
Seeds rich history per session so the reopen path is testable.
Covers replayed tool groups, filter counts, connector cards, tail-error Retry.
2026-08-21 15:17:14 -07:00

99 lines
4.2 KiB
TypeScript

// Seeded-transcript replay (the reopen path). Everything here renders from
// GET /v1/sessions/{id}/messages via itemsFromMessages — no live turns are driven —
// which is the one path the fake agent's echo scripting could never reach: replayed
// tool calls with results, privacy-filter counts, reasoning disclosures, persisted
// notices, and connector-sourced inbound messages.
import { expect } from "@playwright/test";
import { test, seedSessionMessages } from "./fixtures";
const TS = 1755600000; // fixed epoch — replay must not depend on "now"
const RICH_HISTORY = [
{ role: "user", content: "Audit the release branch", ts: TS },
{
role: "assistant",
content: "",
tool_calls: [
{ id: "t1", function: { name: "run_shell", arguments: JSON.stringify({ command: "git log --oneline -5" }) } },
{ id: "t2", function: { name: "read_file", arguments: JSON.stringify({ path: "CHANGELOG.md" }) } },
],
},
{ role: "tool", tool_call_id: "t1", content: "abc123 release: cut 0.1.7" },
{ role: "tool", tool_call_id: "t2", content: "## 0.1.7 — fixes", _display: { hidden_by_filters: 3 } },
{
role: "assistant",
content: "The branch is clean — **two checks** passed.",
reasoning: "Compared the log against the changelog; both entries line up.",
ts: TS + 40,
},
{ role: "notice", kind: "compacted", text: "Context compacted" },
{ role: "assistant", content: "Anything else before I file the summary?" },
];
test("a reopened session replays rich history: tools, filters, reasoning, notices", async ({
page,
}) => {
await seedSessionMessages(page, "pinned-cowork-1", RICH_HISTORY);
await page.goto("/");
await page.getByText("Draft the launch note").first().click();
// Plain items replay as they rendered live.
await expect(page.getByText("Audit the release branch")).toBeVisible();
await expect(page.locator(".md strong", { hasText: "two checks" })).toBeVisible();
await expect(page.getByText("Context compacted")).toBeVisible();
// The turn's tools fold into a collapsed step group; the filter count rides the summary.
const group = page.locator(".stepgroup").first();
await expect(group).toContainText("2 steps");
await expect(page.getByTestId("stepgroup-hidden")).toContainText("3 hidden");
// Expanding reveals the replayed rows with their results wired by tool_call_id.
await group.locator("summary").click();
await expect(page.getByTestId("turn-step")).toHaveCount(2);
await expect(page.getByTestId("tool-hidden-count")).toBeVisible();
// Reasoning persists as the collapsed disclosure, not live "Thinking…".
await expect(page.getByTestId("thinking-toggle")).toContainText("Thought process");
});
test("a connector-sourced message replays as its structured card", async ({ page }) => {
await seedSessionMessages(page, "pinned-cowork-1", [
{
role: "user",
content: "[slack] Priya: Ship it when the checks are green",
source: {
connector: "slack",
kind: "channel",
channel_id: "C0REL",
channel_name: "#release",
sender_id: "U1",
sender_name: "Priya",
ts: TS,
text: "Ship it when the checks are green",
},
},
{ role: "assistant", content: "Will do — watching the checks now." },
]);
await page.goto("/");
await page.getByText("Draft the launch note").first().click();
const card = page.locator(".connector-card[data-brand='slack']");
await expect(card).toBeVisible();
await expect(card).toContainText("Priya");
await expect(card).toContainText("Ship it when the checks are green");
// The framed model-facing content must NOT double-render as a plain bubble.
await expect(page.getByText("[slack] Priya:")).toHaveCount(0);
});
test("a replayed error notice at the tail offers Retry", async ({ page }) => {
await seedSessionMessages(page, "pinned-cowork-1", [
{ role: "user", content: "run the report", ts: TS },
{ role: "notice", kind: "error", text: "provider unavailable" },
]);
await page.goto("/");
await page.getByText("Draft the launch note").first().click();
await expect(page.getByText("Error: provider unavailable")).toBeVisible();
await expect(page.getByTestId("notice-retry")).toBeVisible();
});