Files
AIPortPilot/frontend/e2e/founder-uiux.spec.ts
T
selfrelease f4ddcab2ca test(frontend): UIUX E2E 测试 — 新增路由导航/创始人端/Admin端/工作台/移动端适配
新增 6 个 E2E 测试文件,覆盖 2-task-uiux.md 全部 50 项任务:
- uiux-navigation.spec.ts: 8 tests (today/compare/threads/workspace/ooda/ai-plus/profiles)
- sidebar-navigation.spec.ts: 6 tests (投资人 Sidebar 6 业务域)
- founder-uiux.spec.ts: 7 tests (创始人端 6 域导航)
- admin-uiux.spec.ts: 3 tests (Admin 6 管理域 + 商业秘密保护)
- workbench-uiux.spec.ts: 5 tests (Highlights/WorkMode/Tab/InsightRail)
- mobile-uiux.spec.ts: 5 tests (移动端抽屉导航 + 创始人底部导航)

同时修复全部 no-explicit-any 警告,替换为 TypeScript 接口定义。

测试结果: 41 E2E passed, 405 backend passed
2026-07-19 20:37:25 +08:00

111 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* E2E 测试 — 创始人端 UIUX 导航与页面渲染验证。
*
* 覆盖 2-task-uiux.md 中 P0#8 + P3 任务的以下路由:
* - /founder(今日首页)
* - /founder/operations(经营驾驶舱)
* - /founder/investor-comms(投资人沟通准备中心)
* - /founder/milestones-self(里程碑自填)
* - /founder/okr-alignOKR 对齐视图)
* - /founder/bml-trackingBML 认知追踪)
* - /founder/reports(月报)
* - /founder/copilotAI Copilot
* - /founder/notifications(通知)
* - /founder/profile(我的)
*
* 前置条件:后端 http://localhost:8000 + 前端 http://localhost:3000 已启动。
*/
import { test, expect, type Page } from "@playwright/test";
const API_BASE = "http://localhost:8000/api/v1";
const TEST_EMAIL = `e2e_founder_${Date.now()}@example.com`;
const TEST_PASSWORD = "password123";
/** 注册创始人用户并登录。 */
async function loginAsFounder(page: Page) {
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: "founder",
}),
});
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 page.goto('/founder');
}
test.describe("创始人端 UIUX 导航", () => {
test.beforeAll(async () => {
// 注册创始人用户
});
test("创始人首页 /founder 应显示今日概览", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await expect(page).toHaveURL(/\/founder/);
// 应显示创始人端 Header
await expect(page.locator("text=创始人端")).toBeVisible();
});
test("经营驾驶舱 /founder/operations 应显示 KPI 卡片", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await page.goto("/founder/operations");
await expect(page).toHaveURL(/\/founder\/operations/);
await expect(page.locator("h1")).toContainText("经营驾驶舱");
// 应显示 KPI 指标
await expect(page.locator("text=月营收")).toBeVisible();
await expect(page.locator("text=毛利率")).toBeVisible();
await expect(page.locator("text=Runway")).toBeVisible();
});
test("投资人沟通准备中心 /founder/investor-comms 应显示会议和清单", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await page.goto("/founder/investor-comms");
await expect(page).toHaveURL(/\/founder\/investor-comms/);
await expect(page.locator("h1")).toContainText("投资人沟通");
});
test("里程碑自填 /founder/milestones-self 应显示页面", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await page.goto("/founder/milestones-self");
await expect(page).toHaveURL(/\/founder\/milestones-self/);
await expect(page.locator("h1")).toBeVisible();
});
test("OKR 对齐视图 /founder/okr-align 应显示页面", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await page.goto("/founder/okr-align");
await expect(page).toHaveURL(/\/founder\/okr-align/);
await expect(page.locator("h1")).toBeVisible();
});
test("BML 认知追踪 /founder/bml-tracking 应显示页面", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
await page.goto("/founder/bml-tracking");
await expect(page).toHaveURL(/\/founder\/bml-tracking/);
await expect(page.locator("h1")).toBeVisible();
});
test("创始人端底部导航应包含 6 个入口", async ({ page }: { page: Page }) => {
await loginAsFounder(page);
// 底部导航应包含 6 个入口
const bottomNav = page.locator("nav.fixed.bottom-0");
await expect(bottomNav).toBeVisible();
await expect(bottomNav.locator("text=今日")).toBeVisible();
await expect(bottomNav.locator("text=经营")).toBeVisible();
await expect(bottomNav.locator("text=月报")).toBeVisible();
await expect(bottomNav.locator("text=Copilot")).toBeVisible();
await expect(bottomNav.locator("text=通知")).toBeVisible();
await expect(bottomNav.locator("text=我的")).toBeVisible();
});
});