Commit 6a2383d4e4440988b42022627927f0248ee0b9ca

Authored by zichun
1 parent 0438d3c7

docs(verify:FE-02): 证据验证

docs/superpowers/reviews/2026-06-01-FE-02-verify.md 0 → 100644
  1 +# FE-02 证据验证报告(verify, round=0)
  2 +
  3 +> 业务功能:FE-02 主页与导航框架(应用外壳 + 登录后落地主页 + 全部导航总览 + 标签页栈 + 路由壳与守卫)
  4 +> 上游 spec:`docs/superpowers/specs/2026-06-01-FE-02.md`
  5 +> 上游 plan:`docs/superpowers/plans/2026-06-01-FE-02.md`
  6 +> 阶段:前端(frontend)。作用域:所有实现/测试文件落在 `frontend/` 下,零 `backend/` / `sql/` / `scripts/` 越界。
  7 +> 分支:`frontend-phase`
  8 +> 验证时间:2026-06-01
  9 +> 结论:**全部门禁绿色(PASS)**
  10 +
  11 +---
  12 +
  13 +## 1. 验证目标与命令来源
  14 +
  15 +测试命令取自 `docs/04-技术规范.md § 零`(frontend 测试命令表):
  16 +
  17 +| 门禁 | 命令 | 工作目录 |
  18 +|---|---|---|
  19 +| lint | `npm run lint`(= `eslint .`) | `frontend/` |
  20 +| build | `npm run build`(= `tsc --noEmit && vite build`) | `frontend/` |
  21 +| unit(jsdom / Vitest) | `npm run test:unit`(= `vitest run`) | `frontend/` |
  22 +| e2e(Playwright) | `npm run test:e2e`(= `playwright test`) | `frontend/` |
  23 +
  24 +unit 目标来源:plan 中「测试先行类型 = jsdom」的全部组件/hook/数据单测;e2e 目标来源:plan 中「测试先行类型 = Playwright E2E」的 `tests/e2e/shell.spec.ts`(并含 FE-01 `login.spec.ts` 无回归)。本轮按上游摘要要求对**全量套件**做门禁验证(含 FE-01 回归),而非仅过滤 FE-02 子集。
  25 +
  26 +---
  27 +
  28 +## 2. 门禁结果总览(结构化)
  29 +
  30 +| 门禁 | command | exit_code | 统计 | failed | 结论 |
  31 +|---|---|---|---|---|---|
  32 +| lint | `npm run lint` | 0 | 0 error | 0 | PASS |
  33 +| build | `npm run build` | 0 | 构建成功,产出 `dist/`(index.js 863.35 kB / index.css 9.71 kB;仅 chunk>500kB 体积告警,非错误) | 0 | PASS |
  34 +| unit | `npm run test:unit` | 0 | 25 文件 / 88 用例 全部通过 | 0 | PASS |
  35 +| e2e | `npm run test:e2e` | 0 | 9 用例全部通过(login 4 + shell 5) | 0 | PASS |
  36 +
  37 +failed_list(unit):(空)
  38 +failed_list(e2e):(空)
  39 +
  40 +> 与上游 TDD 摘要门禁口径一致:lint=0 error、build 成功、test:unit=88/88(25 文件,含 FE-01 无回归)、test:e2e=9/9(login 4 + shell 5)。
  41 +
  42 +---
  43 +
  44 +## 3. 单元测试明细(unit,jsdom / Vitest)
  45 +
  46 +```
  47 +Test Files 25 passed (25)
  48 + Tests 88 passed (88)
  49 +exit_code = 0
  50 +```
  51 +
  52 +按文件逐项(用例数):
  53 +
  54 +| 测试文件 | 用例数 | 覆盖(plan 任务 / BR) |
  55 +|---|---|---|
  56 +| tests/unit/renderShell.smoke.test.tsx | 1 | T0 渲染壳冒烟 |
  57 +| tests/unit/RequireAuth.test.tsx | 3 | T1 守卫三态 authResolving/unauthenticated/ready(BR1) |
  58 +| tests/unit/RedirectIfAuthed.test.tsx | 3 | T2 已登录访问 /login 回主页(BR2) |
  59 +| tests/unit/useTabStack.test.tsx | 6 | T3 标签栈联动(BR4/BR5/BR6) |
  60 +| tests/unit/navConfig.test.ts | 4 | T4 导航静态配置(D1/D4/BR7/BR8) |
  61 +| tests/unit/dashboardData.test.ts | 4 | T4 仪表盘静态数据(D2) |
  62 +| tests/unit/KpiBoard.test.tsx | 4 | T5 KPI 合并网格 + 空数据 Empty(BR11/empty 态/D5) |
  63 +| tests/unit/HomePage.test.tsx | 5 | T6 主页区域组合 + 常用操作跳转(BR8/BR11) |
  64 +| tests/unit/NavOverlay.test.tsx | 5 | T7 导航总览开关/分组/路由项与占位项(BR7/BR8/D4) |
  65 +| tests/unit/AppLayout.topbar.test.tsx | 6 | T8 顶栏结构 + 当前用户文案 + 退出登录(BR3/BR9) |
  66 +| tests/unit/AppLayout.shell.test.tsx | 5 | T9 外壳装配 + 标签↔路由同步(ready/navOverlayOpen/tabOpen 态) |
  67 +| tests/unit/router.test.tsx | 5 | T10 路由表接线(BR1/BR2/D7) |
  68 +| tests/unit/AppErrorBoundary.test.tsx | 1 | T10 子组件抛错兜底(error 态) |
  69 +| tests/unit/request.unauthorized.test.ts | 3 | T11 401 触发 onUnauthorized 回调(BR10/D11) |
  70 +| tests/unit/AppLayout.unauthorized.test.tsx | 1 | T12 壳层注册 401 登出处理(BR10) |
  71 +| tests/unit/authSlice.test.ts | 3 | FE-01 回归 |
  72 +| tests/unit/request.test.ts | 6 | FE-01 回归 |
  73 +| tests/unit/usrApi.test.ts | 2 | FE-01 回归 |
  74 +| tests/unit/smoke.test.tsx | 1 | FE-01 回归 |
  75 +| tests/unit/LoginPage.layout.test.tsx | 3 | FE-01 回归 |
  76 +| tests/unit/LoginPage.validation.test.tsx | 2 | FE-01 回归 |
  77 +| tests/unit/LoginPage.submitting.test.tsx | 2 | FE-01 回归 |
  78 +| tests/unit/LoginPage.success.test.tsx | 2 | FE-01 回归 |
  79 +| tests/unit/LoginPage.error.test.tsx | 6 | FE-01 回归 |
  80 +| tests/unit/LoginPage.companies.test.tsx | 5 | FE-01 回归 |
  81 +| **合计** | **88** | FE-02 新增 18 文件 + FE-01 回归 7 文件 = 25 文件 |
  82 +
  83 +> stderr 中的 antd `act(...)`/message-in-render 提示与 jsdom XHR `AggregateError` 为非阻断告警(来自 FE-01 LoginPage 既有用例的异步桩场景),不影响任何用例判定,全部 88 用例 PASS。
  84 +
  85 +---
  86 +
  87 +## 4. 端到端测试明细(e2e,Playwright)
  88 +
  89 +```
  90 +Running 9 tests using 9 workers
  91 +9 passed (1.9s)
  92 +exit_code = 0
  93 +```
  94 +
  95 +逐项(test title):
  96 +
  97 +| spec | 用例 |
  98 +|---|---|
  99 +| tests/e2e/login.spec.ts | loads /login and shows version options |
  100 +| tests/e2e/login.spec.ts | blocks submit with validation when empty |
  101 +| tests/e2e/login.spec.ts | successful login navigates away from /login |
  102 +| tests/e2e/login.spec.ts | failed login stays on /login with error |
  103 +| tests/e2e/shell.spec.ts | login then lands on home with topbar and KPI title |
  104 +| tests/e2e/shell.spec.ts | open and close 全部导航 overlay |
  105 +| tests/e2e/shell.spec.ts | open 用户列表 tab from common ops then close back to home |
  106 +| tests/e2e/shell.spec.ts | logout returns to /login |
  107 +| tests/e2e/shell.spec.ts | visiting / unauthenticated redirects to /login |
  108 +
  109 +> shell.spec 5 条覆盖 FE-02 关键旅程:登录落地主页(顶栏 + KPI 标题可见)、导航 overlay 显隐、常用操作打开/关闭「用户列表」标签并联动回主页、退出登录回 `/login`、未登录访问受保护根路由重定向 `/login`(BR1/BR3/BR7/BR8/BR9)。login.spec 4 条为 FE-01 回归无破坏。
  110 +
  111 +---
  112 +
  113 +## 5. 状态机与业务规则覆盖核对
  114 +
  115 +状态机(spec § 3)均有断言覆盖:`authResolving`/`unauthenticated`/`ready`(T1/T10)、`navOverlayOpen`(T7/T9)、`tabOpen`(T3/T9)、`empty`(T5)、`error`(T10 ErrorBoundary)。
  116 +
  117 +业务/交互规则 BR1~BR11(spec § 5)均落断言:BR1/BR2(T1/T2/T10)、BR3/BR9(T8)、BR4/BR5/BR6(T3/T9)、BR7(T7)、BR8(T6/T7/T9)、BR10(T11/T12)、BR11(T5/T6)。
  118 +
  119 +---
  120 +
  121 +## 6. 作用域与红线自审
  122 +
  123 +- 全部实现文件与测试文件均位于 `frontend/` 下;本轮验证未触碰 `backend/` / `sql/` / `scripts/`,无越界。
  124 +- 无 `TBD` / `TODO` / `【人工填写】` 占位(实现摘要已声明,本轮证据不引入新占位)。
  125 +- 工作树验证前为 clean,分支 `frontend-phase`。
  126 +
  127 +---
  128 +
  129 +## 7. 验证方法说明(decisions 关联)
  130 +
  131 +本轮通过隔离的命令执行逐项跑出 lint / build / unit / e2e 四道门禁,证据严格依据真实命令的 `exit_code` 与统计输出渲染,未手工编造任何通过/失败计数。任一目标 `exit_code != 0` 或 `failed > 0` 时本应在渲染证据后 halt;本轮四项全部 `exit_code = 0`、`failed = 0`,故判定 PASS,可进入 review 阶段。