import { expect, fakeServerState, gotoWorkbench, saveScreenshot, test } from "../fixtures/test"; import { selectors, sessionTab } from "../fixtures/selectors"; test.use({ scenarioId: "empty-session-gc" }); test("server-side empty session GC archives only stale empty sessions", async ({ page }, testInfo) => { await gotoWorkbench(page); await expect(page.locator(sessionTab("ses_empty_ttl"))).toHaveCount(1); await expect(page.locator(sessionTab("ses_empty_fresh"))).toHaveCount(1); await expect(page.locator(sessionTab("ses_empty_ttl_has_message"))).toHaveCount(1); await saveScreenshot(page, testInfo, "empty-session-gc-before"); const gc = await page.request.post("/__e2e/gc-empty-sessions", { data: { ttlMs: 600_000, now: "2026-06-18T16:20:30.000Z" } }); expect(gc.ok()).toBeTruthy(); const gcBody = await gc.json() as { archivedSessionIds?: string[]; keptByReason?: Record }; expect(gcBody.archivedSessionIds).toEqual(["ses_empty_ttl"]); expect(gcBody.keptByReason?.ttl_not_elapsed).toBeGreaterThanOrEqual(1); expect(gcBody.keptByReason?.terminal_result_status).toBeGreaterThanOrEqual(1); await page.reload(); await expect(page.locator(sessionTab("ses_empty_ttl"))).toHaveCount(0); await expect(page.locator(sessionTab("ses_empty_fresh"))).toHaveCount(1); await expect(page.locator(sessionTab("ses_empty_ttl_has_message"))).toHaveCount(1); await saveScreenshot(page, testInfo, "empty-session-gc-after-rail"); const state = await fakeServerState(page); const archived = (state.sessions as Array<{ sessionId?: string; status?: string }>).find((item) => item.sessionId === "ses_empty_ttl"); expect(archived?.status).toBe("archived"); await gotoWorkbench(page, "/workbench/sessions/ses_empty_ttl"); await expect(page.locator(sessionTab("ses_empty_ttl"))).toHaveCount(0); await expect(page.locator(".conversation-error-hint")).toContainText(/archived|归档|session/u); await expect(page.locator(selectors.commandSend)).toBeDisabled(); await saveScreenshot(page, testInfo, "empty-session-gc-deeplink"); });