import type { Page, Route, Request } from "@playwright/test"; export type StudioSettingsFixture = { version: 1; gateway: { url: string; token: string } | null; focused: Record; avatars: Record>; }; const DEFAULT_SETTINGS: StudioSettingsFixture = { version: 1, gateway: null, focused: {}, avatars: {}, }; const createStudioRoute = (initial: StudioSettingsFixture = DEFAULT_SETTINGS) => { let settings: StudioSettingsFixture = { version: 1, gateway: initial.gateway ?? null, focused: { ...(initial.focused ?? {}) }, avatars: { ...(initial.avatars ?? {}) }, }; return async (route: Route, request: Request) => { if (request.method() === "GET") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ settings }), }); return; } if (request.method() !== "PUT") { await route.fallback(); return; } const patch = JSON.parse(request.postData() ?? "{}") as Record; const next = { ...settings }; if ("gateway" in patch) { next.gateway = (patch.gateway as StudioSettingsFixture["gateway"]) ?? null; } if (patch.focused && typeof patch.focused === "object") { const focusedPatch = patch.focused as Record>; const focusedNext = { ...next.focused }; for (const [key, value] of Object.entries(focusedPatch)) { const existing = focusedNext[key] ?? { mode: "focused" as const, filter: "all", selectedAgentId: null, }; focusedNext[key] = { mode: (value.mode as "focused") ?? existing.mode, filter: (value.filter as string) ?? existing.filter, selectedAgentId: "selectedAgentId" in value ? ((value.selectedAgentId as string | null) ?? null) : existing.selectedAgentId, }; } next.focused = focusedNext; } if (patch.avatars && typeof patch.avatars === "object") { const avatarsPatch = patch.avatars as Record | null>; const avatarsNext: StudioSettingsFixture["avatars"] = { ...next.avatars }; for (const [gatewayKey, gatewayPatch] of Object.entries(avatarsPatch)) { if (gatewayPatch === null) { delete avatarsNext[gatewayKey]; continue; } const existing = avatarsNext[gatewayKey] ? { ...avatarsNext[gatewayKey] } : {}; for (const [agentId, seedPatch] of Object.entries(gatewayPatch)) { if (seedPatch === null) { delete existing[agentId]; continue; } const seed = typeof seedPatch === "string" ? seedPatch.trim() : ""; if (!seed) { delete existing[agentId]; continue; } existing[agentId] = seed; } avatarsNext[gatewayKey] = existing; } next.avatars = avatarsNext; } settings = next; await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ settings }), }); }; }; export const stubStudioRoute = async ( page: Page, initial: StudioSettingsFixture = DEFAULT_SETTINGS ) => { await page.route("**/api/studio", createStudioRoute(initial)); };