diff --git a/frontend/e2e/evaluation-uiux.spec.ts b/frontend/e2e/evaluation-uiux.spec.ts new file mode 100644 index 0000000..143e0d9 --- /dev/null +++ b/frontend/e2e/evaluation-uiux.spec.ts @@ -0,0 +1,118 @@ +/** 评价体系前端 E2E 测试 — 模板配置页 + 评分对比页。 */ + +import { test, expect, type Page } from "@playwright/test"; + +const API_BASE = "http://localhost:8000/api/v1"; +const TEST_EMAIL = `e2e_eval_${Date.now()}@example.com`; +const TEST_PASSWORD = "password123"; + +test.use({ viewport: { width: 1280, height: 720 } }); + +/** 登录并跳转到指定路径。 */ +async function loginAndGoto(page: Page, path: string) { + await fetch(`${API_BASE}/auth/register`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + email: TEST_EMAIL, + password: TEST_PASSWORD, + name: "E2E评价用户", + tenant_name: "E2E评价机构", + role: "investor", + }), + }); + + await page.goto("/login"); + await page.fill('input[id="email"]', TEST_EMAIL); + await page.fill('input[id="password"]', TEST_PASSWORD); + await page.click('button[type="submit"]'); + await expect(page).toHaveURL(/\/dashboard|\/today/); + + await page.goto(path); + await page.waitForLoadState("networkidle"); +} + +test.describe("评价指标体系", () => { + test("模板配置页 — 6 轴选择器 + 权重预览", async ({ page }: { page: Page }) => { + await loginAndGoto(page, "/evaluation"); + + // 验证页面标题 + await expect(page.locator("h1")).toContainText("评价模板配置"); + + // 验证 6 轴选择器存在 + const selects = page.locator("select"); + await expect(selects).toHaveCount(6); + + // 验证权重预览区域 + await expect(page.getByText("权重预览")).toBeVisible(); + + // 切换产业赛道为硬科技(第 4 个 select) + await page.locator("select").nth(3).selectOption("hardware"); + await page.waitForTimeout(1000); + + // 验证禁用维度出现 + await expect(page.getByText("禁用维度")).toBeVisible(); + await page.getByText("禁用维度").click(); + await expect(page.locator("text=AI商业化").first()).toBeVisible(); + + // 验证专属指标出现 + await expect(page.getByText("赛道专属指标")).toBeVisible(); + await expect(page.locator("text=专利数").first()).toBeVisible(); + await expect(page.locator("text=流片进度").first()).toBeVisible(); + }); + + test("模板配置页 — 新建模板对话框", async ({ page }: { page: Page }) => { + await loginAndGoto(page, "/evaluation"); + + // 点击新建模板 + await page.getByRole("button", { name: "新建模板" }).click(); + + // 验证对话框出现 + await expect(page.getByText("新建评价模板")).toBeVisible(); + await expect(page.getByPlaceholder(/早期VC-AI/)).toBeVisible(); + + // 输入模板名称并创建 + await page.getByPlaceholder(/早期VC-AI/).fill("E2E测试模板"); + await page.getByRole("button", { name: "创建" }).click(); + await page.waitForTimeout(2000); + + // 验证对话框关闭 + await expect(page.getByText("新建评价模板")).not.toBeVisible(); + }); + + test("评分对比页 — 模板选择 + 表格/雷达图切换", async ({ page }: { page: Page }) => { + await loginAndGoto(page, "/evaluation/compare"); + + // 验证页面标题 + await expect(page.locator("h1")).toContainText("评分对比"); + + // 验证视图切换按钮存在 + await expect(page.getByRole("button", { name: "表格" })).toBeVisible(); + await expect(page.getByRole("button", { name: "雷达图" })).toBeVisible(); + + // 切换到雷达图视图(无数据时显示空状态) + await page.getByRole("button", { name: "雷达图" }).click(); + await page.waitForTimeout(500); + + // 验证空状态提示存在 + await expect(page.getByText("暂无模板")).toBeVisible(); + + // 切换回表格 + await page.getByRole("button", { name: "表格" }).click(); + await page.waitForTimeout(500); + }); + + test("侧边栏导航 — 评价模板入口", async ({ page }: { page: Page }) => { + await loginAndGoto(page, "/today"); + + // 验证侧边栏中有评价模板导航项 + const sidebar = page.locator("aside"); + await expect(sidebar.getByText("评价模板")).toBeVisible(); + await expect(sidebar.getByText("评分对比")).toBeVisible(); + + // 点击评价模板 + await sidebar.getByText("评价模板").click(); + await expect(page).toHaveURL(/\/evaluation$/); + await expect(page.locator("h1")).toContainText("评价模板配置"); + }); +});