import { test, expect, syntheticModel } from "./fixtures"; test("first run configures all model slots and opens settings without sending the draft", async ({ page, harness }) => { await page.goto("/"); const draft = page.getByRole("textbox", { name: "What do you want to learn?", exact: true }); await expect(page.getByTestId("setup-cta-keys")).toBeVisible(); await draft.fill("Synthetic learning topic — do not send"); await page.getByRole("button", { name: "Start session", exact: true }).click(); await expect(page.getByTestId("setup-stage-keys")).toBeVisible(); await expect(page.getByTestId("setup-stage-pickers")).toHaveCount(0); await page.getByTestId("setup-key-provider").click(); await page.getByTestId("provider-option-openai").click(); await page.getByTestId("setup-key-input").fill("synthetic-smoke-key-not-a-credential"); await page.getByTestId("setup-key-save").click(); await expect(page.getByTestId("setup-stage-pickers")).toBeVisible(); await expect(page.getByTestId("setup-save")).toBeDisabled(); for (const slot of ["strong", "cheap", "vision"]) { await page.getByTestId(`setup-trigger-${slot}`).click(); await page.getByTestId(`model-option-${syntheticModel.id}`).click(); } await expect(page.getByTestId("setup-save")).toBeEnabled(); await page.getByTestId("setup-save").click(); await expect(page.getByTestId("setup-dialog")).toHaveCount(0); await expect(page.getByTestId("setup-cta")).toHaveCount(0); await expect(draft).toHaveText("Synthetic learning topic — do not send"); const pin = { model: { provider: "openai", id: syntheticModel.id }, thinkingLevel: "off" }; expect(harness.writes).toEqual([ { path: "/api/keys/OPENAI_API_KEY", body: { value: "synthetic-smoke-key-not-a-credential" } }, { path: "/api/settings/models", body: { strong: pin, cheap: pin, vision: pin } }, ]); await page.getByRole("button", { name: "Settings", exact: true }).click(); await expect(page.getByTestId("settings-dialog")).toBeVisible(); await expect(page.getByTestId("settings-nav-keys")).toBeVisible(); await page.getByTestId("settings-close").click(); await expect(draft).toHaveText("Synthetic learning topic — do not send"); expect(harness.generation).toEqual([]); await expect(page).toHaveURL("http://127.0.0.1:3005/"); }); test("catalog failure is visible and cannot save incomplete slots", async ({ page, harness }) => { harness.catalogFailure = true; await page.goto("/"); await page.getByTestId("setup-cta").click(); await expect(page.getByTestId("setup-catalog-error")).toContainText("Model catalog could not be loaded. Check the connection and retry."); await expect(page.getByTestId("setup-stage-keys")).toHaveCount(0); await expect(page.getByTestId("setup-save")).toHaveCount(0); harness.catalogFailure = false; await page.getByTestId("setup-retry").click(); await expect(page.getByTestId("setup-stage-keys")).toBeVisible(); await expect(page.getByTestId("setup-catalog-error")).toHaveCount(0); expect(harness.writes).toEqual([]); }); test("network boundary rejects external requests and unknown API writes", async ({ page, harness }) => { await page.goto("/"); await page.evaluate(async () => { await Promise.all([ fetch("https://example.invalid/must-not-leave-host").catch(() => undefined), fetch("/api/unexpected-write", { method: "POST", body: "synthetic" }).catch(() => undefined), new Promise((resolve) => { const socket = new WebSocket("wss://example.invalid/must-not-connect"); socket.onclose = () => resolve(); socket.onerror = () => resolve(); }), ]); }); expect(harness.blocked.sort()).toEqual([ "GET https://example.invalid/must-not-leave-host", "POST http://127.0.0.1:3005/api/unexpected-write", "WS wss://example.invalid/must-not-connect", ]); // Only these deliberately asserted denials are consumed; every other denial fails teardown. harness.blocked.length = 0; });