import { expect, test } from "@playwright/test" /** * 导航测试:验证各角色的导航链接不会返回 404。 * 需要数据库环境以完成登录流程;未配置 DATABASE_URL 时自动跳过。 */ const ADMIN_EMAIL = process.env.E2E_ADMIN_EMAIL ?? "admin@e2e.local" const ADMIN_PASSWORD = process.env.E2E_ADMIN_PASSWORD ?? "e2e-pass-123456" const TEACHER_EMAIL = process.env.E2E_TEACHER_EMAIL ?? "teacher@e2e.local" const TEACHER_PASSWORD = process.env.E2E_TEACHER_PASSWORD ?? "e2e-pass-123456" const STUDENT_EMAIL = process.env.E2E_STUDENT_EMAIL ?? "student@e2e.local" const STUDENT_PASSWORD = process.env.E2E_STUDENT_PASSWORD ?? "e2e-pass-123456" const ADMIN_NAV_HREFS = [ "/admin/dashboard", "/admin/school", "/admin/school/schools", "/admin/school/grades", "/admin/school/grades/insights", "/admin/school/departments", "/admin/school/classes", "/admin/school/academic-year", "/admin/audit-logs", "/admin/audit-logs/login-logs", "/admin/announcements", "/messages", "/settings", ] const TEACHER_NAV_HREFS = [ "/teacher/dashboard", "/teacher/textbooks", "/teacher/exams", "/teacher/exams/all", "/teacher/homework", "/teacher/homework/assignments", "/teacher/homework/submissions", "/teacher/grades", "/teacher/grades/entry", "/teacher/grades/stats", "/teacher/grades/analytics", "/teacher/questions", "/teacher/classes", "/teacher/classes/my", "/teacher/classes/students", "/teacher/classes/schedule", "/teacher/course-plans", "/teacher/attendance", "/teacher/attendance/sheet", "/teacher/attendance/stats", "/teacher/schedule-changes", "/announcements", "/messages", ] const STUDENT_NAV_HREFS = [ "/student/dashboard", "/student/learning/courses", "/student/learning/assignments", "/student/learning/textbooks", "/student/schedule", "/student/grades", "/student/attendance", "/announcements", "/messages", ] async function login(page: import("@playwright/test").Page, email: string, password: string) { await page.goto("/login") await page.getByLabel("Email").fill(email) await page.getByLabel("Password").fill(password) await page.getByRole("button", { name: "Sign In with Email" }).click() } test.describe("Navigation", () => { test.skip(!process.env.DATABASE_URL, "requires DATABASE_URL for authenticated navigation") test("should not have 404 links in admin nav", async ({ page }) => { await login(page, ADMIN_EMAIL, ADMIN_PASSWORD) for (const href of ADMIN_NAV_HREFS) { const response = await page.goto(href) const status = response?.status() ?? 200 expect(status, `admin nav ${href} returned ${status}`).toBeLessThan(400) await expect(page).not.toHaveURL(/\/login(?:$|[/?#])/) } }) test("should not have 404 links in teacher nav", async ({ page }) => { await login(page, TEACHER_EMAIL, TEACHER_PASSWORD) for (const href of TEACHER_NAV_HREFS) { const response = await page.goto(href) const status = response?.status() ?? 200 expect(status, `teacher nav ${href} returned ${status}`).toBeLessThan(400) await expect(page).not.toHaveURL(/\/login(?:$|[/?#])/) } }) test("should not have 404 links in student nav", async ({ page }) => { await login(page, STUDENT_EMAIL, STUDENT_PASSWORD) for (const href of STUDENT_NAV_HREFS) { const response = await page.goto(href) const status = response?.status() ?? 200 expect(status, `student nav ${href} returned ${status}`).toBeLessThan(400) await expect(page).not.toHaveURL(/\/login(?:$|[/?#])/) } }) })