Files
openworker/surfaces/gui/e2e/settings.spec.ts
T
Rohit C PrasadandDevika 2b45018ffa OpenWorker: initial import
Imported from andrewyng/aisuite@1b4bbf303e
(contents of its platform/ directory, hoisted to the repo root).
Development history prior to this commit lives in that repository.

Co-authored-by: Devika <devikaverma11@gmail.com>
2026-07-21 11:09:41 -07:00

122 lines
6.5 KiB
TypeScript

import { test, expect } from "./fixtures";
// Guards the Settings-as-page refactor (§13, IA per UX-021): the ⚙ menu opens a full-page
// surface with a left sub-nav — General · Models · Voice input — and each section renders.
// Files is a card inside General; Personas is launch-flagged off.
test("Settings opens as a full page and navigates sections", async ({ page }) => {
await page.goto("/");
await page.getByTestId("account-row").click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
// Full-page: left sub-nav + the General section (no modal backdrop).
await expect(page.getByRole("heading", { name: "General" })).toBeVisible();
await expect(page.locator(".modal-backdrop")).toHaveCount(0);
for (const label of ["General", "Models", "Voice input"]) {
await expect(page.getByRole("button", { name: label, exact: true })).toBeVisible();
}
// Folded/hidden tabs: Files is a General card now; Personas is launch-flagged off.
await expect(page.getByRole("button", { name: "Files", exact: true })).toHaveCount(0);
await expect(page.getByRole("button", { name: "Personas", exact: true })).toHaveCount(0);
// The Files card lives inside General.
await expect(page.getByText("Each conversation gets its own folder")).toBeVisible();
await page.getByRole("button", { name: "Models", exact: true }).click();
await expect(page.getByTestId("set-provider-openai")).toBeVisible();
});
// The launch flag brings the Personas tab back (the gallery/persona suites rely on it).
test("Settings: Personas tab returns behind the launch flag", async ({ page }) => {
await page.addInitScript(() => localStorage.setItem("ocw.flag.personas", "1"));
await page.goto("/");
await page.getByTestId("account-row").click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
await page.getByRole("button", { name: "Personas", exact: true }).click();
await expect(page.getByText("Add personas")).toBeVisible();
});
// UX-021: Settings ▸ Models is the shared provider gallery (§39 components). Cards wear
// their own state (✓ Connected · used …); a vendor card opens the shared key form with the
// prefilled endpoint behind the disclosure; unconfigured providers preview their models.
test("Models: provider gallery states; vendor form previews models", async ({ page }) => {
await page.goto("/");
await page.getByTestId("account-row").click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
await page.getByRole("button", { name: "Models", exact: true }).click();
// Card states from the fixtures: openai configured+used, anthropic configured, zai not.
await expect(page.getByTestId("set-provider-openai")).toContainText("✓ Connected · used 2h ago");
await expect(page.getByTestId("set-provider-anthropic")).toContainText("✓ Connected");
await expect(page.getByTestId("set-provider-zai")).toContainText("Not set up");
await expect(page.getByTestId("set-provider-ollama")).toContainText("No key needed");
// The composer-picker card lists the curated models with provider tags.
const picker = page.getByTestId("composer-picker");
await expect(picker).toContainText("In the composer's picker");
// Vendor form: blurb renders; the prefilled endpoint hides behind the disclosure.
await page.getByTestId("set-provider-zai").click();
await expect(page.getByText(/Uses Z AI's OpenAI-compatible API/)).toBeVisible();
await page.getByTestId("set-endpoint-link").click();
await expect(page.getByTestId("set-field-base_url")).toHaveValue("https://api.z.ai/api/paas/v4");
// Unconfigured providers still preview their curated models (read-only, matrix labels).
const preview = page.getByTestId("model-preview");
await expect(preview).toContainText("Included models");
await expect(preview).toContainText("GLM-5.2 · Z AI");
// Back to the gallery via the crumb.
await page.getByTestId("set-back").click();
await expect(page.getByTestId("set-provider-openai")).toBeVisible();
});
// UX-021: a configured provider's form shows the in-field saved state and the Remove key…
// affordance; removing reverts the card to "Not set up".
test("Models: Remove key reverts a configured provider", async ({ page }) => {
await page.goto("/");
page.on("dialog", (d) => d.accept());
await page.getByTestId("account-row").click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
await page.getByRole("button", { name: "Models", exact: true }).click();
await page.getByTestId("set-provider-anthropic").click();
await expect(page.getByTestId("set-saved-pill")).toContainText("Tested & saved");
await page.getByTestId("set-remove-key").click();
// Back on the gallery, the card has forgotten its key.
await expect(page.getByTestId("set-provider-anthropic")).toContainText("Not set up");
});
// Token savings (owner ask 2026-07-17; moved under Models by UX-021): the card renders with
// the PDF fallback segmented control + attach thresholds, and edits POST through.
test("Settings: Token savings card edits PDF fallback and thresholds", async ({ page }) => {
await page.goto("/");
await page.getByTestId("account-row").click();
await page.getByRole("button", { name: "Settings", exact: true }).click();
await page.getByRole("button", { name: "Models", exact: true }).click();
const card = page.getByTestId("token-savings-card");
await expect(card).toBeVisible();
await expect(card.getByText("Token savings")).toBeVisible();
// Fallback mode: fixture says "text"; switching marks "Send page images" active.
const seg = page.getByTestId("pdf-fallback");
await expect(seg.getByRole("button", { name: "Extract text" })).toHaveClass(/active/);
const [req] = await Promise.all([
page.waitForRequest((r) => r.url().endsWith("/v1/settings/pdf") && r.method() === "POST"),
seg.getByRole("button", { name: "Send page images" }).click(),
]);
expect(req.postDataJSON()).toEqual({ pdf_fallback: "images" });
await expect(seg.getByRole("button", { name: "Send page images" })).toHaveClass(/active/);
// Thresholds: fixture starts at 2 pages / 10 MB; editing pages POSTs the clamped value.
await expect(card.getByTestId("pdf-max-pages")).toHaveValue("2");
await expect(card.getByTestId("pdf-max-mb")).toHaveValue("10");
const [req2] = await Promise.all([
page.waitForRequest((r) => r.url().endsWith("/v1/settings/pdf") && r.method() === "POST"),
card.getByTestId("pdf-max-pages").fill("30"),
]);
expect(req2.postDataJSON()).toEqual({ pdf_max_pages: 30 });
});