import { test, expect, t, expectFitsScreen } from "./fixtures"; test("platform policy is an Owner entry and persists after reload", async ({ page, signIn }) => { await signIn("owner"); await page.goto("/admin/platform"); await expect(page.getByRole("heading", { name: t("admin:platform_title"), exact: true })).toBeVisible(); const limit = page.getByLabel(t("admin:platform_limit")); await expect(limit).toBeEnabled(); await limit.fill("3"); await page.getByLabel(t("admin:platform_cooldown")).fill("45"); await page.getByRole("button", { name: t("admin:platform_save") }).click(); await expect(page.getByText(t("admin:platform_saved"), { exact: true })).toBeVisible(); await page.reload(); await expect(limit).toHaveValue("3"); await expect(page.getByLabel(t("admin:platform_cooldown"))).toHaveValue("45"); await expectFitsScreen(page); await signIn("linked"); await page.goto("/admin/platform"); await expect(page.getByRole("heading", { name: t("admin:platform_title"), exact: true })).toBeHidden(); expect((await page.request.get("/api/v1/settings/wake-policy")).status()).toBe(403); }); test("source disclosure does not scale on press and long pages keep bottom breathing room", async ({ page, signIn }) => { await signIn("owner"); for (const viewport of [{ width: 1440, height: 600 }, { width: 375, height: 812 }]) { await page.setViewportSize(viewport); await page.goto("/admin/auth-sources"); const disclosure = page.getByRole("button", { name: t("authSources:expand", { name: "littleskin" }) }); const box = await disclosure.boundingBox(); await page.mouse.move(box!.x + box!.width / 2, box!.y + box!.height / 2); await page.mouse.down(); await expect.poll(() => disclosure.evaluate((el) => getComputedStyle(el).transform)).toMatch(/^(none|matrix\(1, 0, 0, 1, 0, 0\))$/); await page.mouse.up(); await expect(page.getByRole("button", { name: t("authSources:collapse", { name: "littleskin" }) })).toHaveAttribute("aria-expanded", "true"); const main = page.getByRole("main"); await main.evaluate((el) => { el.scrollTop = el.scrollHeight; }); const save = page.getByRole("button", { name: t("authSources:save"), exact: true }); await expect(save).toBeInViewport(); const room = await save.evaluate((el) => el.closest("main")!.getBoundingClientRect().bottom - el.parentElement!.parentElement!.getBoundingClientRect().bottom); expect(room).toBeGreaterThanOrEqual(23); await expectFitsScreen(page); } }); test("startup shows actual scheduling blockage, stale API state, then recovery", async ({ page, signIn }) => { await signIn("owner"); let state: "blocked" | "outage" | "running" = "blocked"; await page.route("**/api/v1/servers/survival/status", async (route) => { if (state === "outage") { await route.fulfill({ status: 503, json: { error: { code: "upstream_unavailable", message: "test API outage" } } }); return; } const original = await route.fetch(); const data = await original.json(); await route.fulfill({ json: { ...data, phase: state === "running" ? "Running" : "Starting", desiredState: "Running", ready: state === "running", startup: state === "blocked" ? { stage: "scheduling", reason: "Unschedulable", message: "0/1 nodes: Insufficient memory", startedAt: new Date(Date.now() - 60000).toISOString(), logsAvailable: false } : undefined } }); }); await page.goto("/servers/survival"); await expect(page.getByText(t("servers:startup_scheduling"), { exact: true })).toBeVisible(); await expect(page.getByText(t("servers:startup_memory"), { exact: true })).toBeVisible(); await expect(page.getByText(t("servers:log_ended"), { exact: true })).toBeHidden(); await expect(page.getByRole("button", { name: t("servers:retire_delete"), exact: true })).toBeHidden(); state = "outage"; await expect(page.getByText(t("servers:status_stale"), { exact: true })).toBeVisible({ timeout: 7000 }); await expect(page.getByText(t("servers:startup_scheduling"), { exact: true })).toBeHidden(); await expect(page.getByRole("button", { name: t("servers:stop"), exact: true })).toBeHidden(); state = "running"; await expect(page.getByText(t("servers:status_stale"), { exact: true })).toBeHidden({ timeout: 7000 }); await page.getByRole("button", { name: t("servers:more_actions"), exact: true }).click(); await expect(page.getByRole("button", { name: t("servers:retire_delete"), exact: true })).toBeVisible(); }); test("Owner emergency stop stays secondary, confirms name, and distinguishes acceptance from shutdown", async ({ page, signIn }) => { await signIn("owner"); await page.goto("/servers/survival"); await page.getByRole("button", { name: t("servers:more_actions"), exact: true }).click(); await page.getByRole("button", { name: t("servers:emergency_stop"), exact: true }).click(); const confirm = page.getByRole("button", { name: t("servers:emergency_stop"), exact: true }); await expect(confirm).toBeDisabled(); await page.getByLabel(t("servers:retire_confirm_label"), { exact: false }).fill("survival"); await confirm.click(); await expect(page.getByText(t("servers:emergency_stop_accepted"), { exact: true })).toBeVisible(); await expect(confirm).toBeDisabled(); await page.getByRole("dialog").getByRole("button", { name: t("common:close_sr"), exact: true }).last().click(); await expectFitsScreen(page); await page.goto("/admin/platform"); const ownerNav = page.getByRole("navigation").getByRole("link"); const links = await ownerNav.evaluateAll((elements) => elements.map((el) => el.getAttribute("href"))); expect(links.at(-1)).toBe("/admin/platform"); });