# 批次三-B 的四支验证台 —— 怎么跑、看什么 这四支是**验收用**的:不连库、不连上游、**不发任何网络请求**,也不需要登录凭据。 它们直接编译真的 Vue SFC、跑 `frontend/` 里那份真的 `vue`、驱动页面的真 `setup()`, 只把 `@/api` 与上传子组件桩掉。 来源与搬迁经过见 `.claude/plan/2026-09-23-lsy-onboarding-B-交付说明.md` §四 4。 **本 README 的每一条命令与读数都是 2026-09-23 在交付提交 `20a222b` 上实跑取的,不是转述。** --- ## 0. 公共前提 - Node:实测 `v22.22.3`。 - 工作目录:README 里的命令以**仓库根** `D:/project2/payment-platform` 为 cwd 写。 台子内部用的是绝对路径,换 cwd 不影响结果(已实测:从 `D:\` 跑同样通过)。 - 依赖 `frontend/node_modules`:台子用 `createRequire` 指到 `frontend/package.json` 来加载 `vue` 与 `@vue/compiler-sfc` ⇒ 那个目录不存在时**加载这一关就过不去**,先 `pnpm i`。 - **跑之前 `git status -- frontend/` 应当是干净的**,跑完还应当是干净的(下面每支都不写生产文件, `fe-update-mutate` 的 `restore` 分支也一样)。 ## 1. 两支要传页面路径的台子(**不传会崩**) 这两支把目标页面当**命令行参数**读(`process.argv[2]`): ```bash PG="D:/project2/payment-platform/frontend/src/views/module_payment/collection/onboarding/index.vue" node .claude/plan/2026-09-23-lsy-onboarding-B-harness/task-9-fix1-harness.mjs "$PG" node .claude/plan/2026-09-23-lsy-onboarding-B-harness/fe-update-harness.mjs "$PG" ``` **忘了传参数会怎样**:立刻崩,`TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string ... Received undefined` (栈顶是 `compileSfc` 里的 `readFileSync`),**退出码 1**。看到这个就是漏了页面路径,不是台子坏了。 ### 判成败只看 `SUMMARY` 行 两支都会在最后打一行汇总。**不要看退出码**:台子**故意不设** `process.exitCode` (`fe-update-harness.mjs` 第 14 行的注释就是这么写的),所以**有 `FAIL` 也退 0**; 唯一会给出非 0 退出码的情况是上面那种「参数没传」的崩溃。 所以判据是这两行里的 `fail=`: ``` SUMMARY <页面路径>: pass=25 fail=0 ← task-9-fix1-harness.mjs SUMMARY <页面路径>: pass=43 fail=0 ← fe-update-harness.mjs ``` 有失败时同一行会追加失败用例名:`... fail=2 -> <用例名> | <用例名>`。 交付提交 `20a222b` 上的实测读数就是上面这两个(各 1 次,`exit=0`,`frontend/` 跑完仍干净)。 ★ 顺手可以把 stderr 丢掉,屏幕只剩 PASS 与 `SUMMARY`(实测:`2>/dev/null` 后 stdout 为 27 行 且不含 `[Vue warn]`)—— 台子的告警与桩报错**都在 stderr**,stdout 是干净的判据流。 ### 各自钉什么 - **`task-9-fix1-harness.mjs`(25 条)**:进件页 Task 9 那处修复(商户号回显 / 警示)的判定逻辑, 含两条**正对照**(G4「正常商户号 ⇒ 显示出来」、G5「正常商户号 ⇒ 不置警示」) —— 没有正对照的话「一律不显示」也会全绿。 - **`fe-update-harness.mjs`(43 条)**:R-7c「建号 / 更新」两个模式各自的报文形状 (U1/U1b 更新报文不含 `merchant_name_business`;Z5/Z6 更新集与建号集里都没有 `category` / `tenant_id` / `rate_code`)。 ### 已知局限(别把它的绿读大) - **模板不渲染** ⇒ 它证明的是**函数判定逻辑**,**不证明浏览器里的表现**。 - stderr 上会出现一条 `[Vue warn]: onMounted is called when there is no active component instance...` —— 这是桩环境没有组件实例导致的,**预期内**,不是失败。 - stderr 上还会有一段桩出来的报错(例如 `级联数据加载失败: Error: 网络挂了`), 那是**故意注入的网络失败**用例在走错误分支,同样不是失败。 (这两条都实测过只在 stderr:`2>/dev/null` 之后 stdout 里一个都没有。) ## 2. 静态键名核对台(不需要参数) ```bash node .claude/plan/2026-09-23-lsy-onboarding-B-harness/fe-update-keycheck.mjs ``` **退出码 0** + 末行 `SUMMARY keycheck: 全绿`。它比对前后端两侧的字段键名集合, 确认没有拼错的键(跨端键名拼错在运行时只会表现为「字段悄悄没发出去」)。 ★ 这支是四支里**唯一搬过家时改过内容**的一支:原先写死了兄弟台子的工作区绝对路径, 搬完就成了一个已删除的文件 ⇒ 改成按**自身位置**相对定位 (`fileURLToPath(new URL("./fe-update-harness.mjs", import.meta.url))`)。 所以它必须与 `fe-update-harness.mjs` **待在同一个目录**里。 ## 3. 变异驱动(跑之前先看清楚) ```bash node .claude/plan/2026-09-23-lsy-onboarding-B-harness/fe-update-mutate.mjs restore ``` - `restore`:把备份 `.mut-bak` 还原回生产文件。**没有备份时什么都不做,退出码 0。** - 传其它任何 id(`M-U1` / `M-U2` / `M-U3` / `M-U5` / `M-T1` / `M-T2`):**会真的改生产前端文件** (`frontend/src/views/module_payment/collection/onboarding/index.vue` 与 `frontend/src/api/module_payment/onboarding.ts`),并在同目录留 `.mut-bak`。 跑完**必须**用 `restore` 还原,再用 `git status -- frontend/` 确认干净。 **验收不需要跑变异。** 想跑的话按「先 `git status` 干净 → 变异 → 跑第 1 节的两支台子看读数变化 → `restore` → 再 `git status` 干净」的顺序。 ## 4. 核指纹时注意行尾 本仓 `core.autocrlf = true` 且**没有 `.gitattributes`** ⇒ **重新 checkout 会把工作区文件抹成 CRLF**。 两种形态**都实测过**,不是按行数推算的(LF 即当前工作区形态): | 文件 | LF 字节 | LF sha256 | |---|---|---| | `task-9-fix1-harness.mjs` | 10796 | `7f07de4099c96a23c56c1238aeb002857ed8bc10c83458feab5b979cac5bc095` | | `fe-update-harness.mjs` | 12783 | `5b91fa4b452d6aa6816ec523c2c057d28422a3a055d2e725c87af74b63984dad` | | `fe-update-keycheck.mjs` | 6874 | `3d4033167ed8950cda71c3396d77fe4968f70aafef915f2616193a675eba1767` | | `fe-update-mutate.mjs` | 4197 | `a3e68dff6d58fd86a6b219c2de50f98493434bc929c544d9f77bb1af9565a330` | CRLF 形态:11049 / 13057 / 7002 / 4294 字节,sha256 见交付说明 §四 4。 **核出 CRLF 那组数不是文件被改过,是行尾。**