/** * Regression: switching conversations while a Files-panel HTML preview is open must * return the panel to the NEW session's file list — not resurrect the old session's * preview against the new session. * * The trap this guards: the panel stays mounted across a sidebar switch (client-side * navigation, `session` prop flips), and the openRequest locate effect also re-runs when * previewPath's identity changes with session.sessionId. The parent clears openRequest * only after child effects, so without a handled-once guard the old request replays * against the new session — with the isolated iframe that committed a preview-redirect * URL for a file the new Workspace doesn't have, i.e. a raw 404 page in the panel. */ import { test, expect } from "@playwright/test"; import { provisionAndLogin } from "./auth.mjs"; const BASE = process.env.BASE_URL; const MOCK = process.env.MOCK_URL; const U = "e2eswitch"; const P = "password123"; test("switching conversations closes the old session's HTML preview and shows the new session's list", async ({ page, }) => { // --- seed via API: one project, two sessions; demo.html exists only in A --- await provisionAndLogin(page.request, U, P); const projects = await (await page.request.get(`${BASE}/api/projects`)).json(); const projectId = projects.projects[0].projectId; const put = await page.request.put(`${BASE}/api/projects/${projectId}/models`, { data: { defaultModel: { provider: "custom", modelId: "claude-4-8" }, models: [ { provider: "custom", modelId: "claude-4-8", apiKey: "sk-mock", baseUrl: MOCK, contextWindow: 200000, pricing: { cacheRead: 1, cacheWrite: 5, output: 10 }, }, ], }, }); expect(put.ok(), "put models").toBeTruthy(); const mkSession = async () => ( await ( await page.request.post(`${BASE}/api/projects/${projectId}/agents/default_agent/sessions`, { data: {}, }) ).json() ).session.sessionId; const sidA = await mkSession(); const sidB = await mkSession(); const html = Buffer.from("