diff --git a/packages/app/e2e/browser/turn-collapse.spec.ts b/packages/app/e2e/browser/turn-collapse.spec.ts index d990e33009..82d653208e 100644 --- a/packages/app/e2e/browser/turn-collapse.spec.ts +++ b/packages/app/e2e/browser/turn-collapse.spec.ts @@ -3,6 +3,7 @@ import path from "node:path"; import { holdOlderHistoryPages, userScrollsTimelineToHistoryStart, + waitForTimelineGeometryToSettle, } from "../support/helpers/timeline-pagination"; import { getActiveTabTestId } from "../support/helpers/launcher"; import type { Page, Locator } from "@playwright/test"; @@ -407,6 +408,38 @@ async function seedWholeTurnHistory() { return agent; } +/** Read every command across the scroll window, without requiring offscreen rows to mount. */ +async function expectExpandedCommandsReadable(page: Page, count: number) { + const timeline = page.getByTestId("agent-chat-scroll"); + const commands = new Set(); + await timeline.hover(); + for (let step = 0; step < count && commands.size < count; step += 1) { + const labels = await timeline + .getByRole("button", { name: /echo stress-\d+/ }) + .allTextContents(); + for (const label of labels) { + const command = /echo stress-(\d+)/.exec(label); + if (command) commands.add(Number(command[1])); + } + if (commands.size < count) { + await page.mouse.wheel(0, 300); + await waitForTimelineGeometryToSettle(page); + } + } + expect([...commands].sort((a, b) => a - b)).toEqual( + Array.from({ length: count }, (_, index) => index), + ); +} + +async function returnToExpandedSummary(page: Page, summary: Locator) { + await page.getByTestId("agent-chat-scroll").hover(); + for (let step = 0; step < 120 && !(await summary.isVisible()); step += 1) { + await page.mouse.wheel(0, -300); + await waitForTimelineGeometryToSettle(page); + } + await summary.scrollIntoViewIfNeeded(); +} + test("loads complete long turns and preserves expansion while revealing older history", async ({ page, }) => { @@ -423,7 +456,7 @@ test("loads complete long turns and preserves expansion while revealing older hi await expect(latest).toBeVisible(); await expect.poll(() => rowsBetweenLatestSummaryAndReply(page)).toBe(0); await latest.click(); - await expect.poll(() => rowsBetweenLatestSummaryAndReply(page)).toBe(120); + await expectExpandedCommandsReadable(page, 120); await userScrollsTimelineToHistoryStart(page); await history.expectRequestedPages(1); history.releasePage(1); @@ -432,9 +465,9 @@ test("loads complete long turns and preserves expansion while revealing older hi .getByTestId("turn-summary") .getByRole("button", { name: "Ran 60 commands", exact: true }), ).toBeVisible(); - await expect.poll(() => rowsBetweenLatestSummaryAndReply(page)).toBe(120); + await expectExpandedCommandsReadable(page, 120); history.expectNoRepeatedEntries(); - await latest.scrollIntoViewIfNeeded(); + await returnToExpandedSummary(page, latest); await latest.click(); await expect.poll(() => rowsBetweenLatestSummaryAndReply(page)).toBe(0); } finally {