AI made playwright tests + add them to the github.

This commit is contained in:
KingKDot
2026-07-15 12:12:13 -05:00
parent 22b0eed5e1
commit 8ad81efdc3
16 changed files with 554 additions and 9 deletions
+116
View File
@@ -0,0 +1,116 @@
import { expect, test } from "@playwright/test";
import { OPERATOR, VIEWER } from "./credentials";
import { collectBrowserIssues, login } from "./helpers";
test.describe("authentication and authorization", () => {
test("rejects invalid credentials without creating a session", async ({ page }) => {
await page.goto("/login.html");
await page.locator("#user").fill("not-a-real-user");
await page.locator("#pass").fill("not-the-password");
await page.locator("#login-form button[type='submit']").click();
await expect(page.locator("#error")).toContainText("Invalid credentials");
await expect(page).toHaveURL(/\/login\.html$/);
const me = await page.request.get("/api/auth/me");
expect(me.status()).toBe(401);
});
test("serves login instead of protected content when unauthenticated", async ({ page }) => {
const response = await page.goto("/settings");
expect(response?.status()).toBe(200);
await expect(page.locator("#login-form")).toBeVisible();
await expect(page.getByRole("heading", { name: "Settings" })).toHaveCount(0);
});
test("logout revokes the browser session", async ({ page }) => {
await login(page);
page.once("dialog", (dialog) => dialog.accept());
await page.locator("#user-actions-btn").click();
await Promise.all([
page.waitForURL((url) => url.pathname === "/"),
page.locator("#logout-btn").click(),
]);
await expect(page.locator("#login-form")).toBeVisible();
const me = await page.request.get("/api/auth/me");
expect(me.status()).toBe(401);
await page.goto("/users");
await expect(page.locator("#login-form")).toBeVisible();
});
test("viewer navigation and direct routes enforce read-only access", async ({ page }) => {
await login(page, VIEWER);
await expect(page.locator("#role-badge")).toContainText("Viewer");
for (const id of [
"users-link",
"build-link",
"plugins-link",
"scripts-link",
"file-share-link",
"notifications-link",
"enrollment-link",
]) {
await expect(page.locator(`#${id}`)).toBeHidden();
}
const denied = await page.goto("/users");
expect(denied?.status()).toBe(403);
await expect(page.locator("body")).toContainText("Admin access required");
const allowed = await page.goto("/metrics");
expect(allowed?.status()).toBe(200);
await expect(page.getByRole("heading", { name: "Metrics Dashboard" })).toBeVisible();
});
test("operator can use operational pages but not admin pages", async ({ page }) => {
await login(page, OPERATOR);
await expect(page.locator("#role-badge")).toContainText("Operator");
await expect(page.locator("#build-link")).not.toHaveClass(/hidden/);
await expect(page.locator("#users-link")).toBeHidden();
const build = await page.goto("/build");
expect(build?.status()).toBe(200);
await expect(page.locator("#build-form")).toBeVisible();
const users = await page.goto("/users");
expect(users?.status()).toBe(403);
});
});
test("admin page sweep loads without browser errors", async ({ page }) => {
// This test validates each page's static/HTTP initialization. Opening two
// long-lived sockets for every rapid hard navigation would only exercise the
// server's WebSocket rate limiter; socket lifecycle is covered separately.
await page.routeWebSocket(/.*/, (socket) => socket.close());
const issues = collectBrowserIssues(page);
await login(page);
const routes = [
["/", "#grid"],
["/metrics", "h1"],
["/graph", "h1"],
["/settings", "#prefs-form"],
["/logs", "#page-info"],
["/notifications", "#notification-table"],
["/users", "#users-table-body"],
["/build", "#build-form"],
["/sol-publish", "#rpc-endpoint-list"],
["/plugins", "#plugin-list"],
["/scripts", "#saved-scripts-list"],
["/deploy", "#client-list"],
["/socks5-manager", "body"],
["/file-share", "#upload-form"],
["/purgatory", "#enrollment-table"],
] as const;
for (const [path, selector] of routes) {
const response = await page.goto(path);
expect(response?.status(), `${path} should return 200`).toBe(200);
await expect(page.locator("#top-nav"), `${path} should mount navigation`).toBeVisible();
await expect(page.locator(selector).first(), `${path} should render ${selector}`).toBeVisible();
await page.waitForTimeout(250);
}
expect(issues).toEqual([]);
});