import { expect, test } from "@playwright/test" /** * 私信模块 E2E 测试。 * 未登录场景可独立运行;登录后场景需要 DATABASE_URL。 * 参考 announcements.spec.ts 的登录与跳转断言模式。 */ test.describe("Messages module", () => { test.describe("unauthenticated access", () => { test("redirects to login when not authenticated", async ({ page }) => { await page.goto("/messages") await expect(page).toHaveURL(/\/login(?:$|[/?#])/) }) test("redirects message detail to login when not authenticated", async ({ page }) => { await page.goto("/messages/some-id") await expect(page).toHaveURL(/\/login(?:$|[/?#])/) }) test("redirects compose to login when not authenticated", async ({ page }) => { await page.goto("/messages/compose") await expect(page).toHaveURL(/\/login(?:$|[/?#])/) }) }) test.describe("authenticated access", () => { test.beforeEach(async ({ page }) => { test.skip(!process.env.DATABASE_URL, "requires DATABASE_URL for authenticated flow") const email = process.env.E2E_STUDENT_EMAIL ?? "student@e2e.local" const password = process.env.E2E_STUDENT_PASSWORD ?? "e2e-pass-123456" 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("messages page loads and stays authenticated", async ({ page }) => { await page.goto("/messages") await expect(page.locator("body")).toBeVisible() await expect(page).not.toHaveURL(/\/login(?:$|[/?#])/) }) test("messages page has tab navigation", async ({ page }) => { await page.goto("/messages") const tabs = page.locator('[role="tab"]') await expect(tabs.first()).toBeVisible({ timeout: 10000 }) const tabCount = await tabs.count() expect(tabCount).toBeGreaterThanOrEqual(2) }) test("messages page renders without error", async ({ page }) => { await page.goto("/messages") await expect(page.locator("body")).toBeVisible() }) test("message compose page loads", async ({ page }) => { await page.goto("/messages/compose") await expect(page.locator("body")).toBeVisible() }) }) })