test(voice): clarify playback and timeline regression journeys

This commit is contained in:
Mohamed Boudra
2026-09-16 00:15:52 +02:00
parent 072c23fd48
commit 71a51ba6da
4 changed files with 78 additions and 45 deletions
@@ -1,7 +1,8 @@
import { expect, test } from "../support/fixtures";
import { seedMockAgentWorkspace } from "../support/helpers/mock-agent";
import {
spokenTimelinePrompt,
withSpokenTimeline,
captureSpokenTimeline,
reloadSpokenTimeline,
expectSpokenTimelinePrompt,
sendSpokenTimelinePrompt,
expectStableHistoryStartGutter,
@@ -36,32 +37,17 @@ test.describe("Agent timeline pagination", () => {
}, testInfo) => {
const historyText = "Please check the voice history.";
const liveText = "Now check the live voice message.";
const agent = await seedMockAgentWorkspace({
repoPrefix: "spoken-timeline-",
title: "Spoken timeline presentation",
initialPrompt: spokenTimelinePrompt(historyText),
});
try {
await agent.client.waitForFinish(agent.agentId, 15_000);
await withSpokenTimeline(historyText, async (agent) => {
await openAgentTimeline(page, agent);
await expectSpokenTimelinePrompt(page, historyText);
await sendSpokenTimelinePrompt(agent, liveText);
await expectSpokenTimelinePrompt(page, liveText);
await testInfo.attach("spoken-live-desktop-web", {
body: await page.screenshot({ path: testInfo.outputPath("spoken-desktop-web.png") }),
contentType: "image/png",
});
await page.reload();
await captureSpokenTimeline(page, testInfo, "desktop");
await reloadSpokenTimeline(page);
await expectSpokenTimelinePrompt(page, liveText);
await page.setViewportSize({ width: 390, height: 844 });
await captureSpokenTimeline(page, testInfo, "compact");
await expectSpokenTimelinePrompt(page, liveText);
await testInfo.attach("spoken-reloaded-compact-web", {
body: await page.screenshot({ path: testInfo.outputPath("spoken-compact-web.png") }),
contentType: "image/png",
});
} finally {
await agent.cleanup();
}
});
});
test("keeps the history-start gutter and visible position stable through the final page", async ({
@@ -1,4 +1,4 @@
import { expect, type Page } from "@playwright/test";
import { expect, type TestInfo, type Page } from "@playwright/test";
import { buildAgentRoute, seedMockAgentWorkspace, type MockAgentWorkspace } from "./mock-agent";
import { readReplicaCache } from "./replica-cache-storage";
import {
@@ -575,7 +575,7 @@ async function waitForTimelineGeometryToSettle(page: Page): Promise<void> {
);
}
export function spokenTimelinePrompt(text: string): string {
function spokenTimelinePrompt(text: string): string {
return `<spoken-input>\n${text}\n</spoken-input>\n<instruction>This message was spoken by the user. Respond using the speak tool only, not normal messages, because the user may not be looking at the chat.</instruction>`;
}
@@ -594,3 +594,38 @@ export async function sendSpokenTimelinePrompt(
await agent.client.sendAgentMessage(agent.agentId, spokenTimelinePrompt(text));
await agent.client.waitForFinish(agent.agentId, 15_000);
}
export async function withSpokenTimeline(
historyText: string,
run: (agent: MockAgentWorkspace) => Promise<void>,
): Promise<void> {
const agent = await seedMockAgentWorkspace({
repoPrefix: "spoken-timeline-",
title: "Spoken timeline presentation",
initialPrompt: spokenTimelinePrompt(historyText),
});
try {
await agent.client.waitForFinish(agent.agentId, 15_000);
await run(agent);
} finally {
await agent.cleanup();
}
}
export async function reloadSpokenTimeline(page: Page): Promise<void> {
await page.reload();
}
export async function captureSpokenTimeline(
page: Page,
testInfo: TestInfo,
size: "desktop" | "compact",
): Promise<void> {
await page.setViewportSize(
size === "compact" ? { width: 390, height: 844 } : { width: 1280, height: 900 },
);
await testInfo.attach(`spoken-${size}-web`, {
body: await page.screenshot({ path: testInfo.outputPath(`spoken-${size}-web.png`) }),
contentType: "image/png",
});
}