You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

66 lines
2.5 KiB

import { test, expect } from "@playwright/test";
import { E2E_ADMIN, FIXED_CAPTCHA, PROTECTED_PATHS, PUBLIC_PATHS } from "../fixtures/test-users";
test.describe("路由守卫", () => {
test.describe("未登录用户", () => {
for (const path of PUBLIC_PATHS) {
test(`公开路径 ${path} 可直接访问`, async ({ page }) => {
await page.goto(path);
// toHaveURL 默认匹配完整 URL,用 path 结尾匹配
const expectedPattern = path === "/" ? /\/$/ : new RegExp(`${path.replace(/\//g, "\\/")}$`);
await expect(page).toHaveURL(expectedPattern);
});
}
for (const path of PROTECTED_PATHS) {
test(`受保护路径 ${path} 重定向到登录页`, async ({ page }) => {
await page.goto(path);
// SSR 中间件重定向到登录页(可能带 redirect 参数也可能不带)
await expect(page).toHaveURL(/\/auth\/login/);
});
}
});
test.describe("已登录用户", () => {
// 通过 UI 登录,确保 cookie 设置在 page context 中
test.beforeEach(async ({ page }) => {
await page.goto("/auth/login");
await page.fill("#login-username", E2E_ADMIN.username);
await page.fill("#login-password", E2E_ADMIN.password);
await page.fill("#login-captcha", FIXED_CAPTCHA);
await page.click('button[type="submit"]');
await page.waitForURL("/", { timeout: 15000 });
});
test("已登录用户访问登录页重定向到首页", async ({ page }) => {
await page.goto("/auth/login");
await page.waitForURL("/", { timeout: 15000 });
});
test("已登录用户访问注册页重定向到首页", async ({ page }) => {
await page.goto("/auth/register");
await page.waitForURL("/", { timeout: 15000 });
});
test("已登录用户可访问受保护页面", async ({ page }) => {
await page.goto("/settings");
await expect(page).toHaveURL(/\/settings/);
});
});
test.describe("API 守卫", () => {
test("未登录访问受保护 API 返回 401", async ({ request }) => {
const res = await request.get("/api/auth/session");
// session API 在白名单中,未登录时应返回 200 但 user 为 null
expect(res.ok()).toBeTruthy();
});
test("未登录访问管理 API 返回 401", async ({ request }) => {
// 尝试访问需要登录的 API
const res = await request.post("/api/cards", {
data: { title: "test" },
});
expect(res.status()).toBe(401);
});
});
});