Files
learnharness/e2e/smoke.spec.ts
T
sorokin.oleg.edu ece228e8ed test: Added sandboxed, isolated Chromium first-run coverage with stat...
- package.json
- package-lock.json
- .gitignore
- playwright.config.ts
- e2e/fixtures.ts
- e2e/smoke.spec.ts
- tests/svg-image.test.tsx

GSD context:
- Milestone: M001 - Merge upstream v0.4.0 into the Gitea fork
- Slice: S02 - Verify combined application behavior
- Task: T01 - Added sandboxed, isolated Chromium first-run coverage with stateful synthetic API fixtures and fail-closed network boundaries.

GSD-Task: S02/T01
2026-10-31 16:20:49 +03:00

75 lines
3.8 KiB
TypeScript

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<void>((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;
});