feat: unify installation model catalog

This commit is contained in:
Codex
2026-09-02 18:45:33 +02:00
parent ae053961a3
commit 7b7927bfe5
169 changed files with 3696 additions and 4572 deletions
+74 -331
View File
@@ -13,111 +13,42 @@ const readyStatus = {
checkedAt: "2026-08-05T10:00:00.000Z",
};
const options = {
providers: ["zai", "deepseek"],
models: [
{ provider: "zai", id: "glm-5.2" },
{ provider: "deepseek", id: "deepseek-v4" },
],
reasoning: ["low", "medium", "high"],
checkedAt: "2026-08-05T10:00:00.000Z",
};
function renderManagement() {
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
return render(<QueryClientProvider client={client}><PiManagement open onClose={() => undefined} /></QueryClientProvider>);
return render(
<QueryClientProvider client={client}>
<PiManagement open onClose={() => undefined} />
</QueryClientProvider>,
);
}
beforeEach(() => {
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json(readyStatus)),
http.get("/api/pi-management/options", () => HttpResponse.json(options)),
);
server.use(http.get("/api/pi-management/status", () => HttpResponse.json(readyStatus)));
});
test("loads Pi version and readiness as an accessible operational rail", async () => {
test("shows the catalog default as read-only installation state", async () => {
renderManagement();
expect(screen.getByText("Loading Pi management…")).toBeVisible();
expect(await screen.findByRole("heading", { name: "Pi management" })).toBeVisible();
await screen.findByLabelText("Provider");
const dialog = screen.getByRole("dialog", { name: "Pi management" });
expect(dialog).toHaveAttribute("aria-modal", "false");
expect(dialog).toHaveAttribute("data-work-area-panel");
expect(dialog.querySelectorAll(':scope > [data-work-area-panel-region="header"]')).toHaveLength(1);
expect(dialog.querySelectorAll(':scope > [data-work-area-panel-region="body"]')).toHaveLength(1);
expect(await screen.findByText("Pi 0.80.3")).toBeVisible();
expect(screen.getByTestId("pi-readiness-rail")).toHaveTextContent("Runtime ready");
expect(screen.getByRole("status", { name: "Pi readiness" })).toHaveTextContent("Ready");
expect(screen.getByText("Pi 0.80.3")).toBeVisible();
expect(screen.getByText("Defaults ready")).toBeVisible();
expect(screen.getByRole("button", { name: "Test saved defaults" })).toBeVisible();
});
test("uses closed provider, model, and reasoning choices without a secret field or terminal", async () => {
renderManagement();
const provider = await screen.findByLabelText("Provider");
expect(provider).toHaveValue("zai");
expect(screen.getByLabelText("Model")).toHaveValue("glm-5.2");
expect(screen.getByLabelText("Reasoning level")).toHaveValue("medium");
expect(within(provider).getAllByRole("option").map((option) => option.textContent)).toEqual(["zai", "deepseek"]);
expect(screen.getByLabelText("Model")).toHaveTextContent("GLM 5.2");
expect(screen.queryByRole("textbox", { name: /provider|model|reasoning|credential/i })).not.toBeInTheDocument();
const catalog = screen.getByRole("region", { name: "Installation catalog default" });
expect(catalog).toHaveTextContent("zai");
expect(catalog).toHaveTextContent("glm-5.2");
expect(catalog).toHaveTextContent("medium");
expect(screen.getByRole("button", { name: "Test catalog default" })).toBeVisible();
expect(screen.queryByRole("button", { name: /save defaults/i })).not.toBeInTheDocument();
expect(screen.queryByRole("combobox", { name: /provider|model|reasoning/i })).not.toBeInTheDocument();
expect(document.querySelector('input[type="password"]')).toBeNull();
expect(screen.queryByRole("button", { name: /terminal|shell access/i })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Update Pi" })).not.toBeInTheDocument();
});
test("saves only a selected non-secret configuration", async () => {
const user = userEvent.setup();
let saved: unknown;
server.use(http.put("/api/pi-management/config", async ({ request }) => {
saved = await request.json();
return HttpResponse.json({ ...saved as object, updatedAt: "2026-08-05T10:02:00.000Z" });
}));
renderManagement();
await user.selectOptions(await screen.findByLabelText("Provider"), "deepseek");
await user.selectOptions(screen.getByLabelText("Reasoning level"), "high");
await user.click(screen.getByRole("button", { name: "Save defaults" }));
await waitFor(() => expect(saved).toEqual({ provider: "deepseek", model: "deepseek-v4", reasoning: "high" }));
expect(screen.getByRole("status", { name: "Pi management feedback" })).toHaveTextContent("Defaults saved");
});
// Catches a provider switch updating only the saved config while leaving the credential rail
// attached to the previously selected provider.
test("shows authoritative credential presence after saving a different provider", async () => {
const user = userEvent.setup();
let saved = false;
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json(saved ? {
...readyStatus,
credentials: "missing",
config: { provider: "deepseek", model: "deepseek-v4", reasoning: "medium" },
checkedAt: "2026-08-05T10:02:00.000Z",
} : readyStatus)),
http.put("/api/pi-management/config", async ({ request }) => {
saved = true;
return HttpResponse.json({
...await request.json() as object,
updatedAt: "2026-08-05T10:01:00.000Z",
});
}),
);
renderManagement();
expect(await screen.findByText("Credentials present")).toBeVisible();
await user.selectOptions(screen.getByLabelText("Provider"), "deepseek");
await user.click(screen.getByRole("button", { name: "Save defaults" }));
expect(await screen.findByText("Credentials missing")).toBeVisible();
expect(screen.queryByText("Credentials present")).not.toBeInTheDocument();
expect(screen.getByLabelText("Provider")).toHaveValue("deepseek");
expect(screen.getByRole("status", { name: "Pi management feedback" })).toHaveTextContent("Defaults saved");
});
test("runs the saved-configuration test without changing credential presence", async () => {
test("tests the catalog default without mutating credential presence", async () => {
const user = userEvent.setup();
let tests = 0;
server.use(http.post("/api/pi-management/test", () => {
@@ -128,204 +59,95 @@ test("runs the saved-configuration test without changing credential presence", a
}));
renderManagement();
const testButton = await screen.findByRole("button", { name: "Test saved defaults" });
expect(screen.getByText("Defaults ready")).toBeVisible();
expect(screen.queryByText("Changes are not saved yet.")).not.toBeInTheDocument();
expect(testButton).toBeEnabled();
const testButton = await screen.findByRole("button", { name: "Test catalog default" });
await user.click(testButton);
await waitFor(() => expect(tests).toBe(1));
expect(await screen.findByText("Saved configuration test passed")).toBeVisible();
expect(await screen.findByText("Catalog default test passed.")).toBeVisible();
expect(screen.getByText("Credentials present")).toBeVisible();
await user.click(screen.getByRole("button", { name: "Test saved defaults" }));
expect(await screen.findByText("Saved configuration test failed")).toBeVisible();
await user.click(testButton);
expect(await screen.findByText(/Catalog default test failed/)).toBeVisible();
expect(screen.getByText("Credentials present")).toBeVisible();
});
test("fetches and displays bounded sanitized diagnostic logs only on request", async () => {
test("fetches bounded sanitized diagnostics only on request", async () => {
const user = userEvent.setup();
let logRequests = 0;
server.use(http.get("/api/pi-management/logs", () => {
logRequests += 1;
return HttpResponse.json({ lines: ["Pi smoke check succeeded", "provider token=[REDACTED]"], checkedAt: "2026-08-05T10:04:00.000Z" });
return HttpResponse.json({
lines: ["Pi smoke check succeeded", "provider token=[REDACTED]"],
checkedAt: "2026-08-05T10:04:00.000Z",
});
}));
renderManagement();
await screen.findByLabelText("Provider");
await screen.findByText("Pi 0.80.3");
expect(logRequests).toBe(0);
await user.click(screen.getByRole("button", { name: "Show sanitized logs" }));
expect(await screen.findByLabelText("Sanitized Pi diagnostics")).toHaveTextContent("provider token=[REDACTED]");
expect(logRequests).toBe(1);
expect(screen.queryByText("raw-provider-token")).not.toBeInTheDocument();
});
test("explains forbidden management access without offering mutation controls", async () => {
server.use(
http.get("/api/pi-management/status", () =>
HttpResponse.json({ code: "pi_management_forbidden", error: "Pi management is not permitted" }, { status: 403 })),
);
test("explains forbidden management access without offering controls", async () => {
server.use(http.get("/api/pi-management/status", () =>
HttpResponse.json(
{ code: "pi_management_forbidden", error: "Pi management is not permitted" },
{ status: 403 },
)));
renderManagement();
expect(await screen.findByRole("alert", { name: "Pi management unavailable" })).toHaveTextContent("Pi management is not permitted");
expect(screen.queryByLabelText("Provider")).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Save defaults" })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Test saved defaults" })).not.toBeInTheDocument();
expect(await screen.findByRole("alert", { name: "Pi management unavailable" }))
.toHaveTextContent("Pi management is not permitted");
expect(screen.queryByRole("button", { name: "Test catalog default" })).not.toBeInTheDocument();
});
test("shows a seven-step host-terminal workflow in scrollable platform tabs", async () => {
test("shows the single-source host workflow in accessible platform tabs", async () => {
const user = userEvent.setup();
renderManagement();
const tablist = await screen.findByRole("tablist", { name: "Pi host platform" });
const [linuxTab, macosTab, windowsTab] = within(tablist).getAllByRole("tab");
expect([linuxTab, macosTab, windowsTab].map((tab) => tab.textContent)).toEqual(["Linux", "macOS", "Windows"]);
expect(screen.getByRole("dialog", { name: "Pi management" })).toHaveAttribute("data-width", "standard");
expect(screen.getByTestId("pi-platform-instructions-scroll")).toHaveClass("overflow-y-scroll");
expect(screen.queryByRole("tabpanel")).not.toBeInTheDocument();
expect([linuxTab, macosTab, windowsTab].every((tab) => tab.getAttribute("aria-selected") === "false")).toBe(true);
expect(linuxTab).toHaveAttribute("tabindex", "0");
expect(macosTab).toHaveAttribute("tabindex", "-1");
expect(windowsTab).toHaveAttribute("tabindex", "-1");
for (const tab of [linuxTab, macosTab, windowsTab]) {
const panelId = tab.getAttribute("aria-controls");
const panel = panelId ? document.getElementById(panelId) : null;
expect(panel).toBeInTheDocument();
expect(panel).toHaveAttribute("role", "tabpanel");
expect(panel).toHaveAttribute("aria-labelledby", tab.id);
expect(panel).toHaveAttribute("hidden");
expect(panel).toHaveAttribute("tabindex", "-1");
}
expect(screen.getByText("Using the host terminal:")).toBeVisible();
expect(screen.queryByText(/not this browser page/i)).not.toBeInTheDocument();
expect(screen.queryByRole("region", { name: "Host update" })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Copy update command" })).not.toBeInTheDocument();
expect(screen.queryByText(/:5173/)).not.toBeInTheDocument();
expect(await screen.findByText("Select the provider, model, and reasoning used for new Pi work. Credentials stay in protected host files.")).toBeVisible();
expect(screen.getByText("Shows at most 200 recent lines with declared secret values removed.")).toBeVisible();
linuxTab.focus();
await user.keyboard("{ArrowRight}");
expect(macosTab).toHaveFocus();
expect(macosTab).toHaveAttribute("aria-selected", "true");
expect(macosTab).toHaveAttribute("tabindex", "0");
expect(linuxTab).toHaveAttribute("tabindex", "-1");
await user.keyboard("{ArrowRight}");
expect(windowsTab).toHaveFocus();
expect(windowsTab).toHaveAttribute("aria-selected", "true");
expect(windowsTab).toHaveAttribute("tabindex", "0");
expect(macosTab).toHaveAttribute("tabindex", "-1");
await user.keyboard("{ArrowRight}");
expect(linuxTab).toHaveFocus();
expect(linuxTab).toHaveAttribute("aria-selected", "true");
await user.keyboard("{ArrowLeft}");
expect(windowsTab).toHaveFocus();
await user.keyboard("{Home}");
expect(linuxTab).toHaveFocus();
await user.keyboard("{End}");
expect(windowsTab).toHaveFocus();
await user.click(windowsTab);
expect(windowsTab).toHaveAttribute("aria-selected", "false");
expect(screen.queryByRole("tabpanel")).not.toBeInTheDocument();
await user.keyboard(" ");
expect(windowsTab).toHaveAttribute("aria-selected", "true");
await user.keyboard(" ");
expect(windowsTab).toHaveAttribute("aria-selected", "false");
await user.keyboard("{Enter}");
expect(windowsTab).toHaveAttribute("aria-selected", "true");
await user.keyboard("{Enter}");
expect(windowsTab).toHaveAttribute("aria-selected", "false");
await user.click(linuxTab);
const linux = screen.getByRole("tabpanel", { name: "Linux" });
expect(within(linux).getAllByRole("listitem")).toHaveLength(7);
expect(within(linux).getAllByRole("heading", { level: 4 }).map((heading) => heading.textContent)).toEqual([
"Open the project root",
"Edit the provider catalog",
"Enable the model",
"Edit the Installation Model Catalog",
"Choose eligibility and defaults",
"Complete the provider setup",
"Reload Pi configuration",
"Update the Pi version",
"Diagnose and recover a failed operation",
]);
expect(linux).toHaveTextContent("cd /absolute/path/to/ThothII");
expect(linux).toHaveTextContent("tht pi status");
expect(linux).toHaveTextContent("tht pi doctor");
expect(linux).toHaveTextContent("Invalid JSON");
expect(linux).toHaveTextContent("Provider connectivity");
expect(linux).toHaveTextContent("If maintenance is inactive");
expect(linux).toHaveTextContent("active after an update");
expect(linux).toHaveTextContent("active after a restart");
expect(linux).toHaveTextContent("run every command in this list from that directory");
expect(linux).toHaveTextContent("deploy/pi/models.json");
expect(linux).toHaveTextContent("deploy/pi/settings.json");
expect(linux).toHaveTextContent("baseUrl is the provider API endpoint");
expect(linux).toHaveTextContent("enabledModels uses provider/model identifiers");
expect(linux).toHaveTextContent("During the initial installation");
expect(linux).toHaveTextContent("Pi credentials file location");
expect(linux).toHaveTextContent("tht pi restart --yes --drain");
expect(linux).toHaveTextContent("tht pi update");
expect(linux).toHaveTextContent("tht pi update --version <VERSION> --source pull --image <IMAGE>@sha256:<DIGEST> --yes --drain");
expect(linux).toHaveTextContent("tht pi maintenance status");
expect(linux).toHaveTextContent("tht pi logs");
expect(linux).toHaveTextContent("tht pi rollback --yes");
expect(linux).toHaveTextContent("tht pi maintenance recover --yes");
expect(linux).not.toHaveTextContent("PI_AUTH_FILE");
expect(linux).not.toHaveTextContent("thothctl");
expect(linux).not.toHaveTextContent("~/.pi/agent/");
for (const expected of [
"deploy/<installation-id>/thothii-installation.yaml",
"modelCatalog.defaults.session",
"provider/model",
"generated projections",
"tht pi restart --yes --drain",
"tht pi doctor",
"Invalid YAML",
]) expect(linux).toHaveTextContent(expected);
for (const retired of ["deploy/pi/models.json", "deploy/pi/settings.json", "tht pi configure", "enabledModels"])
expect(linux).not.toHaveTextContent(retired);
await user.click(macosTab);
const macos = screen.getByRole("tabpanel", { name: "macOS" });
expect(within(macos).getAllByRole("listitem")).toHaveLength(7);
expect(within(macos).getAllByRole("heading", { level: 4 }).map((heading) => heading.textContent)).toEqual([
"Open the project root",
"Edit the provider catalog",
"Enable the model",
"Complete the provider setup",
"Reload Pi configuration",
"Update the Pi version",
"Diagnose and recover a failed operation",
]);
expect(macos).toHaveTextContent("cd /absolute/path/to/ThothII");
expect(macos).toHaveTextContent("run every command in this list from that directory");
expect(macos).toHaveTextContent("deploy/pi/models.json");
expect(macos).toHaveTextContent("deploy/pi/settings.json");
expect(macos).toHaveTextContent("tht pi restart --yes --drain");
expect(macos).toHaveTextContent("tht pi update");
expect(macos).toHaveTextContent("tht pi update --version <VERSION> --source pull --image <IMAGE>@sha256:<DIGEST> --yes --drain");
expect(macos).toHaveTextContent("tht pi maintenance status");
expect(macos).toHaveTextContent("tht pi logs");
expect(macos).toHaveTextContent("tht pi rollback --yes");
expect(macos).toHaveTextContent("tht pi maintenance recover --yes");
expect(screen.getByRole("tabpanel", { name: "macOS" }))
.toHaveTextContent("deploy/<installation-id>/thothii-installation.yaml");
await user.click(windowsTab);
const windows = screen.getByRole("tabpanel", { name: "Windows" });
expect(within(windows).getAllByRole("listitem")).toHaveLength(7);
expect(within(windows).getAllByRole("heading", { level: 4 }).map((heading) => heading.textContent)).toEqual([
"Open the project root",
"Edit the provider catalog",
"Enable the model",
"Complete the provider setup",
"Reload Pi configuration",
"Update the Pi version",
"Diagnose and recover a failed operation",
]);
expect(windows).toHaveTextContent("Set-Location C:\\absolute\\path\\to\\ThothII");
expect(windows).toHaveTextContent("run every command in this list from that directory");
expect(windows).toHaveTextContent("deploy\\pi\\models.json");
expect(windows).toHaveTextContent("deploy\\pi\\settings.json");
expect(windows).toHaveTextContent('tht pi restart --yes --drain');
expect(windows).toHaveTextContent('tht pi update');
expect(windows).toHaveTextContent('tht pi update --version <VERSION> --source pull --image <IMAGE>@sha256:<DIGEST> --yes --drain');
expect(windows).toHaveTextContent('tht pi maintenance status');
expect(windows).toHaveTextContent('tht pi logs');
expect(windows).toHaveTextContent('tht pi rollback --yes');
expect(windows).toHaveTextContent('tht pi maintenance recover --yes');
expect(windows).not.toHaveTextContent("PI_AUTH_FILE");
expect(windows).not.toHaveTextContent("thothctl");
expect(screen.getByRole("tabpanel", { name: "Windows" }))
.toHaveTextContent("deploy\\<installation-id>\\thothii-installation.yaml");
});
test("reloads installation defaults when the panel is reopened", async () => {
test("reloads the catalog-derived default when reopened", async () => {
let statusCalls = 0;
server.use(http.get("/api/pi-management/status", () => {
statusCalls += 1;
@@ -334,70 +156,32 @@ test("reloads installation defaults when the panel is reopened", async () => {
: { ...readyStatus, config: { provider: "deepseek", model: "deepseek-v4", reasoning: "high" } });
}));
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
const view = render(<QueryClientProvider client={client}><PiManagement open onClose={() => undefined} /></QueryClientProvider>);
const view = render(
<QueryClientProvider client={client}><PiManagement open onClose={() => undefined} /></QueryClientProvider>,
);
expect(await screen.findByLabelText("Provider")).toHaveValue("zai");
view.rerender(<QueryClientProvider client={client}><PiManagement open={false} onClose={() => undefined} /></QueryClientProvider>);
expect(await screen.findByText("glm-5.2")).toBeVisible();
view.rerender(
<QueryClientProvider client={client}><PiManagement open={false} onClose={() => undefined} /></QueryClientProvider>,
);
await waitFor(() => expect(screen.queryByRole("dialog", { name: "Pi management" })).not.toBeInTheDocument());
view.rerender(<QueryClientProvider client={client}><PiManagement open onClose={() => undefined} /></QueryClientProvider>);
await waitFor(() => expect(screen.getByLabelText("Provider")).toHaveValue("deepseek"));
view.rerender(
<QueryClientProvider client={client}><PiManagement open onClose={() => undefined} /></QueryClientProvider>,
);
expect(await screen.findByText("deepseek-v4")).toBeVisible();
});
test("shows an explicit recoverable incomplete state when no provider model is available", async () => {
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json({ ...readyStatus, credentials: "present" })),
http.get("/api/pi-management/options", () => HttpResponse.json({
...options,
providers: ["zai"],
models: [],
})),
);
test("shows an explicit incomplete state when the catalog default is unavailable", async () => {
server.use(http.get("/api/pi-management/status", () => HttpResponse.json({
...readyStatus,
config: { reasoning: "medium" },
})));
renderManagement();
const incomplete = await screen.findByRole("alert", { name: "Pi configuration incomplete" });
expect(incomplete).toHaveTextContent("No provider or model options are available");
expect(incomplete).toHaveTextContent("Check the host-managed Pi model configuration");
expect(screen.queryByText("Loading Pi management…")).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: "Save defaults" })).toBeDisabled();
expect(screen.getByRole("button", { name: "Test saved defaults" })).toBeDisabled();
});
test("keeps suggested draft choices distinct from invalid persisted defaults until save succeeds", async () => {
let configured = false;
const persisted = {
...readyStatus,
credentials: "missing",
config: { provider: "retired", model: "old-model", reasoning: "medium" },
};
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json(configured ? {
...readyStatus,
credentials: "missing",
config: { provider: "zai", model: "glm-5.2", reasoning: "medium" },
checkedAt: "2026-08-05T10:05:00.000Z",
} : persisted)),
http.put("/api/pi-management/config", () => {
configured = true;
return HttpResponse.json({
provider: "zai",
model: "glm-5.2",
reasoning: "medium",
updatedAt: "2026-08-05T10:05:00.000Z",
});
}),
);
const user = userEvent.setup();
renderManagement();
expect(await screen.findByLabelText("Provider")).toHaveValue("zai");
expect(screen.getByText("Defaults incomplete")).toBeVisible();
expect(screen.getByText("Suggested choices are not saved yet.")).toBeVisible();
expect(screen.getByRole("button", { name: "Test saved defaults" })).toBeDisabled();
await user.click(screen.getByRole("button", { name: "Save defaults" }));
expect(await screen.findByText("Defaults ready")).toBeVisible();
expect(screen.getByRole("button", { name: "Test saved defaults" })).toBeEnabled();
expect(incomplete).toHaveTextContent("The catalog default is unavailable");
expect(incomplete).toHaveTextContent("modelCatalog.defaults.session");
expect(screen.getByRole("button", { name: "Test catalog default" })).toBeDisabled();
});
test.each(["present", "missing"] as const)(
@@ -408,47 +192,6 @@ test.each(["present", "missing"] as const)(
credentials,
})));
renderManagement();
expect(await screen.findByText(`Credentials ${credentials}`)).toBeVisible();
},
);
test("labels smoke only as a saved-configuration test and resets it when the draft changes", async () => {
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json({ ...readyStatus, credentials: "present" })),
http.post("/api/pi-management/test", () => HttpResponse.json({
ready: true,
checkedAt: "2026-08-05T10:06:00.000Z",
})),
);
const user = userEvent.setup();
renderManagement();
await user.click(await screen.findByRole("button", { name: "Test saved defaults" }));
expect(await screen.findByText("Saved configuration test passed")).toBeVisible();
expect(screen.getByText("Credentials present")).toBeVisible();
await user.selectOptions(screen.getByLabelText("Provider"), "deepseek");
expect(screen.getByText("Saved configuration test not run")).toBeVisible();
expect(screen.getByText("Save these changes before testing. The test always uses saved defaults.")).toBeVisible();
expect(screen.getByRole("button", { name: "Test saved defaults" })).toBeDisabled();
expect(screen.getByText("Credentials present")).toBeVisible();
});
test("a failed saved-configuration test does not change backend credential presence", async () => {
server.use(
http.get("/api/pi-management/status", () => HttpResponse.json({ ...readyStatus, credentials: "present" })),
http.post("/api/pi-management/test", () => HttpResponse.json({
ready: false,
message: "Pi runtime is unavailable",
checkedAt: "2026-08-05T10:07:00.000Z",
})),
);
const user = userEvent.setup();
renderManagement();
await user.click(await screen.findByRole("button", { name: "Test saved defaults" }));
expect(await screen.findByText("Saved configuration test failed")).toBeVisible();
expect(screen.getByText("Credentials present")).toBeVisible();
expect(screen.queryByText("Credentials missing")).not.toBeInTheDocument();
});