import { expect, test } from "@playwright/test" import { setupAuthState } from "./helpers/auth" import { buildMaskOption, maskDynamicElements, setTheme, setViewport, waitForPageReady } from "./helpers/visual-helpers" import { SCREENSHOT_DEFAULT_OPTIONS, THEMES, VIEWPORT_LIST, snapshotName } from "./visual.config" /** * 学生仪表盘视觉回归测试 * * 登录后访问 /student/dashboard,在 desktop/tablet/mobile 三种视口 * 以及 light/dark 两种主题下进行整页快照, * 并单独对关键组件做组件级快照。 * * 需要数据库环境以完成登录流程;未配置 DATABASE_URL 时自动跳过。 */ test.describe("Student dashboard visual regression", () => { test.skip(!process.env.DATABASE_URL, "requires DATABASE_URL for authenticated visual tests") for (const viewport of VIEWPORT_LIST) { for (const theme of THEMES) { test(`student-dashboard @ ${viewport} @ ${theme}`, async ({ page }) => { await setViewport(page, viewport) await setTheme(page, theme) await setupAuthState(page, "student") await page.goto("/student/dashboard") await waitForPageReady(page) const masks = await maskDynamicElements(page, ["[data-testid='grade-value']", "[data-testid='attendance-rate']", "[data-testid='assignment-item']"]) await expect(page).toHaveScreenshot(snapshotName("student-dashboard", viewport, theme), { ...SCREENSHOT_DEFAULT_OPTIONS, ...buildMaskOption(masks), }) }) } } test("student-dashboard sidebar component @ desktop @ light", async ({ page }) => { test.skip(!process.env.DATABASE_URL, "requires DATABASE_URL for authenticated visual tests") await setViewport(page, "desktop") await setTheme(page, "light") await setupAuthState(page, "student") await page.goto("/student/dashboard") await waitForPageReady(page) const sidebar = page.locator("[data-testid='sidebar'], aside, nav").first() const masks = await maskDynamicElements(page) await expect(sidebar).toHaveScreenshot("student-dashboard-sidebar-desktop-light.png", { ...SCREENSHOT_DEFAULT_OPTIONS, ...buildMaskOption(masks), }) }) test("student-dashboard main content @ desktop @ light", async ({ page }) => { test.skip(!process.env.DATABASE_URL, "requires DATABASE_URL for authenticated visual tests") await setViewport(page, "desktop") await setTheme(page, "light") await setupAuthState(page, "student") await page.goto("/student/dashboard") await waitForPageReady(page) const main = page.locator("main").first() const masks = await maskDynamicElements(page, ["[data-testid='grade-value']", "[data-testid='attendance-rate']", "[data-testid='assignment-item']"]) await expect(main).toHaveScreenshot("student-dashboard-main-desktop-light.png", { ...SCREENSHOT_DEFAULT_OPTIONS, ...buildMaskOption(masks), }) }) })