Files
stroblmeandClaude Opus 5 062a2aac60 Let the search reach past the twentieth of a kind, and unbreak two specs
The global search capped each category before cmdk had matched anything, so
nothing past the twentieth node or widget could be found at all — this
instance has 28 nodes and 97 widgets. The cap now trims the candidates the
query could reach rather than the raw index.

The admin teardown asked /users/ for limit=1000, which the route stopped
accepting when its bounds went in; a 422 body has no `data` to iterate, so the
hook threw and took the tests it was attributed to with it. It asks for the
500 the route allows.

And `submit` folds every declared initial into a run's params, so an input the
run never passed can no longer read as the flow's own. That assertion is gone;
what the panel does show — the value the run actually started from, passed or
not — is what the test checks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CL9zvnnvcp1mvA8o7impxk
2026-09-06 14:46:59 +02:00

224 lines
7.8 KiB
TypeScript

import { expect, test } from "@playwright/test"
import { firstSuperuser, firstSuperuserPassword } from "./config.ts"
import { api, apiPage } from "./utils/api"
import { createUser } from "./utils/privateApi"
import { randomEmail, randomPassword } from "./utils/random"
import { logInUser } from "./utils/user"
test.afterAll(async ({ browser }) => {
// Every user below is created under a randomEmail(), so the superuser can
// sweep them all up by that shape — including what a run that failed halfway
// left in the shared development database.
const page = await apiPage(browser)
// 500 is the most the route accepts; asking for more is a 422, and a 422 body
// has no `data` to iterate.
const { data } = await (await api(page, "/users/?limit=500")).json()
for (const user of data as { id: string; email: string }[]) {
if (/^test_.*@example\.com$/.test(user.email)) {
await api(page, `/users/${user.id}`, { method: "DELETE" })
}
}
await page.close()
})
test("Admin page is accessible and shows correct title", async ({ page }) => {
await page.goto("/admin")
await expect(page.getByRole("heading", { name: "Users" })).toBeVisible()
await expect(
page.getByText("Manage user accounts and permissions"),
).toBeVisible()
})
test("Add User button is visible", async ({ page }) => {
await page.goto("/admin")
await expect(page.getByRole("button", { name: "Add User" })).toBeVisible()
})
test.describe("Admin user management", () => {
test("Create a new user successfully", async ({ page }) => {
await page.goto("/admin")
const email = randomEmail()
const password = randomPassword()
const fullName = "Test User Admin"
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(email)
await page.getByPlaceholder("Full name").fill(fullName)
await page.getByPlaceholder("Password").first().fill(password)
await page.getByPlaceholder("Password").last().fill(password)
await page.getByRole("button", { name: "Save" }).click()
await expect(page.getByText("User created successfully")).toBeVisible()
await expect(page.getByRole("dialog")).not.toBeVisible()
const userRow = page.getByRole("row").filter({ hasText: email })
await expect(userRow).toBeVisible()
})
test("Create a superuser", async ({ page }) => {
await page.goto("/admin")
const email = randomEmail()
const password = randomPassword()
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(email)
await page.getByPlaceholder("Password").first().fill(password)
await page.getByPlaceholder("Password").last().fill(password)
await page.getByLabel("Is superuser?").check()
await page.getByLabel("Is active?").check()
await page.getByRole("button", { name: "Save" }).click()
await expect(page.getByText("User created successfully")).toBeVisible()
await expect(page.getByRole("dialog")).not.toBeVisible()
const userRow = page.getByRole("row").filter({ hasText: email })
await expect(userRow.getByText("Superuser")).toBeVisible()
})
test("Edit a user successfully", async ({ page }) => {
await page.goto("/admin")
const email = randomEmail()
const password = randomPassword()
const originalName = "Original Name"
const updatedName = "Updated Name"
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(email)
await page.getByPlaceholder("Full name").fill(originalName)
await page.getByPlaceholder("Password").first().fill(password)
await page.getByPlaceholder("Password").last().fill(password)
await page.getByRole("button", { name: "Save" }).click()
await expect(page.getByText("User created successfully")).toBeVisible()
await expect(page.getByRole("dialog")).not.toBeVisible()
const userRow = page.getByRole("row").filter({ hasText: email })
await userRow.getByRole("button").click()
await page.getByRole("menuitem", { name: "Edit User" }).click()
await page.getByPlaceholder("Full name").fill(updatedName)
await page.getByRole("button", { name: "Save" }).click()
await expect(page.getByText("User updated successfully")).toBeVisible()
// Scoped to this run's row: earlier runs leave their own "Updated Name".
await expect(userRow.getByText(updatedName)).toBeVisible()
})
test("Delete a user successfully", async ({ page }) => {
await page.goto("/admin")
const email = randomEmail()
const password = randomPassword()
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(email)
await page.getByPlaceholder("Password").first().fill(password)
await page.getByPlaceholder("Password").last().fill(password)
await page.getByRole("button", { name: "Save" }).click()
await expect(page.getByText("User created successfully")).toBeVisible()
await expect(page.getByRole("dialog")).not.toBeVisible()
const userRow = page.getByRole("row").filter({ hasText: email })
await userRow.getByRole("button").click()
await page.getByRole("menuitem", { name: "Delete User" }).click()
await page.getByRole("button", { name: "Delete" }).click()
await expect(
page.getByText("The user was deleted successfully"),
).toBeVisible()
await expect(
page.getByRole("row").filter({ hasText: email }),
).not.toBeVisible()
})
test("Cancel user creation", async ({ page }) => {
await page.goto("/admin")
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill("test@example.com")
await page.getByRole("button", { name: "Cancel" }).click()
await expect(page.getByRole("dialog")).not.toBeVisible()
})
test("Email is required and must be valid", async ({ page }) => {
await page.goto("/admin")
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill("invalid-email")
await page.getByPlaceholder("Email").blur()
await expect(page.getByText("Invalid email address")).toBeVisible()
})
test("Password must be at least 8 characters", async ({ page }) => {
await page.goto("/admin")
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(randomEmail())
await page.getByPlaceholder("Password").first().fill("short")
await page.getByPlaceholder("Password").last().fill("short")
await page.getByRole("button", { name: "Save" }).click()
await expect(
page.getByText("Password must be at least 8 characters"),
).toBeVisible()
})
test("Passwords must match", async ({ page }) => {
await page.goto("/admin")
await page.getByRole("button", { name: "Add User" }).click()
await page.getByPlaceholder("Email").fill(randomEmail())
await page.getByPlaceholder("Password").first().fill(randomPassword())
await page.getByPlaceholder("Password").last().fill("different12345")
await page.getByPlaceholder("Password").last().blur()
await expect(page.getByText("The passwords don't match")).toBeVisible()
})
})
test.describe("Admin page access control", () => {
test.use({ storageState: { cookies: [], origins: [] } })
test("Non-superuser cannot access admin page", async ({ page }) => {
const email = randomEmail()
const password = randomPassword()
await createUser({ email, password })
await logInUser(page, email, password)
await page.goto("/admin")
await expect(page.getByRole("heading", { name: "Users" })).not.toBeVisible()
await expect(page).not.toHaveURL(/\/admin/)
})
test("Superuser can access admin page", async ({ page }) => {
await logInUser(page, firstSuperuser, firstSuperuserPassword)
await page.goto("/admin")
await expect(page.getByRole("heading", { name: "Users" })).toBeVisible()
})
})