CI / check (push) Successful in 39s
CI / tests-imaging-browsers (push) Successful in 1m46s
CI / tests-unit (push) Successful in 2m16s
CI / tests-integration (push) Successful in 2m12s
CI / tests-ui (push) Failing after 3m45s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
- unit: captcha env fallback/precedence (DB wins, explicit "none") and perf-ttls defaults, overrides and invalid values - e2e: public page render + image health, register form and Turnstile widget consistency, anonymous auth-guard redirects, plus warm latency budgets and cache-control contracts
49 lines
1.8 KiB
TypeScript
49 lines
1.8 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { expectNoApplicationError } from "./helpers";
|
|
|
|
// Unauthenticated requests to private routes must bounce to the login form —
|
|
// never render private content and never 500. Two guard paths exist: the edge
|
|
// proxy rewrites `/admin/*` to `/login?from=…` (`src/proxy.ts`), while the
|
|
// member pages and the mod console redirect from their layouts with a bare
|
|
// `/login`.
|
|
|
|
// Routes where the proxy preserves the requested destination.
|
|
const PROXY_ROUTES = ["/admin", "/admin/settings"] as const;
|
|
// Routes guarded by a page/layout `redirect("/login")` with no destination.
|
|
const LAYOUT_ROUTES = [
|
|
"/settings",
|
|
"/me",
|
|
"/messages",
|
|
"/notifications",
|
|
"/friends",
|
|
"/redeem",
|
|
"/mod",
|
|
"/client",
|
|
] as const;
|
|
|
|
for (const route of PROXY_ROUTES) {
|
|
test(`${route} redirects to login and keeps the return path`, async ({
|
|
page,
|
|
}) => {
|
|
const response = await page.goto(route);
|
|
expect(response?.ok(), `GET ${route} -> ${response?.status()}`).toBe(true);
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await expect(page.locator('input[type="password"]').first()).toBeVisible();
|
|
await expectNoApplicationError(page);
|
|
|
|
const from = new URL(page.url()).searchParams.get("from");
|
|
expect(from, "login lost the return destination").toBeTruthy();
|
|
expect(new URL(from as string, "http://localhost").pathname).toBe(route);
|
|
});
|
|
}
|
|
|
|
for (const route of LAYOUT_ROUTES) {
|
|
test(`${route} redirects an anonymous visitor to login`, async ({ page }) => {
|
|
const response = await page.goto(route);
|
|
expect(response?.ok(), `GET ${route} -> ${response?.status()}`).toBe(true);
|
|
await expect(page).toHaveURL(/\/login/);
|
|
await expect(page.locator('input[type="password"]').first()).toBeVisible();
|
|
await expectNoApplicationError(page);
|
|
});
|
|
}
|