import { expect, fakeServerState, gotoWorkbench, saveScreenshot, test } from "../fixtures/test"; import { selectors, sessionTab } from "../fixtures/selectors"; test.use({ scenarioId: "session-rail-many" }); test("session rail does not issue per-tab status requests", async ({ page }) => { await gotoWorkbench(page); await expect(page.locator(".session-tab")).toHaveCount(20); await page.waitForTimeout(1200); const state = await fakeServerState(page); const requests = state.requestLedger as Array<{ method?: string; path?: string }>; const sessionStatusRequests = requests.filter((request) => /^\/v1\/agent\/sessions\/ses_/u.test(String(request.path ?? ""))); const uniquePaths = new Set(sessionStatusRequests.map((request) => request.path)); expect(sessionStatusRequests.length).toBeLessThanOrEqual(3); expect(uniquePaths.size).toBeLessThanOrEqual(1); expect((state.legacyRequestLedger as unknown[]).length).toBe(0); await expect(page.locator(selectors.commandInput)).toBeVisible(); }); test("session rail loads historical pages and keeps deep-linked old sessions visible", async ({ page }, testInfo) => { const firstPage = await page.request.get("/v1/workbench/sessions?limit=20"); expect(firstPage.ok()).toBeTruthy(); const firstBody = await firstPage.json() as { count?: number; hasMore?: boolean; nextCursor?: string | null; sessions?: Array<{ sessionId?: string }> }; expect(firstBody.count).toBe(20); expect(firstBody.hasMore).toBe(true); expect(firstBody.nextCursor).toBe("idx:20"); await gotoWorkbench(page, "/workbench/sessions/ses_completed"); await expect(page.locator(".session-tab")).toHaveCount(20); await expect(page.locator("#session-load-more")).toBeVisible(); const page1Ids = await visibleSessionIds(page); expect(new Set(page1Ids).size).toBe(20); const messageCountBefore = await page.locator(selectors.messageCard).count(); expect(messageCountBefore).toBeGreaterThan(0); await saveScreenshot(page, testInfo, "session-pagination-first-page"); await page.locator("#session-load-more").click(); await expect(page.locator(".session-tab")).toHaveCount(40); await expect(page.locator(selectors.messageCard)).toHaveCount(messageCountBefore); const page2Ids = await visibleSessionIds(page); expect(new Set(page2Ids).size).toBe(40); for (const sessionId of page1Ids) expect(page2Ids).toContain(sessionId); await saveScreenshot(page, testInfo, "session-pagination-second-page"); await page.locator("#session-load-more").click(); await expect(page.locator(".session-tab")).toHaveCount(55); await expect(page.locator("#session-list-complete")).toBeVisible(); await expect(page.locator("#session-load-more")).toHaveCount(0); const allIds = await visibleSessionIds(page); expect(new Set(allIds).size).toBe(55); expect(allIds).toContain("ses_many_42"); await saveScreenshot(page, testInfo, "session-pagination-no-more"); await gotoWorkbench(page, "/workbench/sessions/ses_many_42"); const oldTab = page.locator(sessionTab("ses_many_42")); await expect(oldTab).toBeVisible(); await expect(oldTab).toHaveAttribute("data-active", "true"); await saveScreenshot(page, testInfo, "session-pagination-deep-link"); }); async function visibleSessionIds(page: { locator: (selector: string) => { evaluateAll: (callback: (nodes: Element[]) => T) => Promise } }): Promise { return await page.locator(".session-tab").evaluateAll((nodes) => nodes.map((node) => node.getAttribute("data-session-id") || "")); }