Files
paseo/packages/app/e2e/browser/plugin-timeline.spec.ts
T
paseo-bot[bot] 1d203d780e test(plugins): verify repeated timeline IDs in a real browser
Exercise the installed plugin through the real daemon and chat viewport. Read the oldest virtualized replacement before and after reload, using actual browser row heights instead of extending the legacy JSDOM harness.
2026-11-01 22:50:24 +00:00

72 lines
2.7 KiB
TypeScript

import { test } from "../support/fixtures";
import { installDaemonWebSocketGate } from "../support/helpers/daemon-websocket-gate";
import {
withTimelinePlugin,
viewInlineThinkingExample,
requestPluginTimeline,
interactWithStreamingCard,
expectWholeCompletedCard,
expectBothConsecutiveTools,
trackPluginChatRecovery,
reconnectPluginChat,
withRepeatedOutputTimeline,
readOldestPluginReplacement,
expectOldestPluginReplacementReadable,
} from "../support/helpers/plugin-timeline";
for (const width of [1100, 390]) {
test(`assistant plugin receives the whole streaming message at width ${width}`, async ({
page,
}, info) => {
await page.setViewportSize({ width, height: 900 });
const gate = await installDaemonWebSocketGate(page);
await withTimelinePlugin(page, info, "assistant", async (agent) => {
await requestPluginTimeline(agent);
await interactWithStreamingCard(page);
await agent.client.waitForFinish(agent.agentId, 30_000);
await expectWholeCompletedCard(page);
// Local state is checked during growth; the viewport remounts on the history handoff.
const recovery = trackPluginChatRecovery(page);
gate.holdTimelineResponses(agent.agentId);
await page.reload({ waitUntil: "domcontentloaded" });
await gate.waitForHeldTimelineResponse();
await recovery.expectCatalogWithoutRetransmission();
gate.releaseHeldTimelineResponses();
await expectWholeCompletedCard(page);
await recovery.expectRecoveredWithoutRetransmission();
recovery.reset();
await reconnectPluginChat(page, gate);
await recovery.expectRecoveredWithoutRetransmission();
await expectWholeCompletedCard(page);
});
});
}
test("Overview preserves both consecutive tool plugin cards", async ({ page }, info) => {
await withTimelinePlugin(page, info, "tools", async (agent) => {
await requestPluginTimeline(agent);
await agent.client.waitForFinish(agent.agentId, 30_000);
await expectBothConsecutiveTools(page);
await page.reload({ waitUntil: "domcontentloaded" });
await expectBothConsecutiveTools(page);
});
});
test("inline-thinking example renders a streamed thought through host UI", async ({
page,
}, info) => {
await viewInlineThinkingExample(page, info);
});
test("keeps older plugin replacements readable when source messages reuse local output IDs", async ({
page,
}, info) => {
await withRepeatedOutputTimeline(page, info, async () => {
await readOldestPluginReplacement(page);
await expectOldestPluginReplacementReadable(page);
await page.reload({ waitUntil: "domcontentloaded" });
await readOldestPluginReplacement(page);
await expectOldestPluginReplacementReadable(page);
});
});