# 前端 Expect CLI 测试框架接入记录 日期:2026-06-08 ## 范围 本记录对应 `water-frontend` 仓库新增 `expect-cli` 浏览器测试框架入口,用于在现有 Playwright 与 `node:test` 测试之外,提供 agent 驱动的浏览器测试能力。 ## 前端基线 - 仓库:`water-frontend` - 工作目录:`/Volumes/Dpan/github/water-workspace/water-frontend` - 分支:`develop` - 基础提交:`35fb598c9059b0ea933de533892a0473512ad662` - 状态:测试框架接入已在工作区实现,尚未提交 ## 实现内容 - 新增开发依赖:`expect-cli@^0.1.3` - 新增脚本: - `pnpm test:expect` - `pnpm test:expect:smoke` - `pnpm test:expect:watch` - `pnpm test:expect:acceptance` - 新增 runner:`tools/expect/run-expect.mjs` - 默认目标地址为 `http://localhost:18080` - 支持 `EXPECT_BASE_URL` 覆盖目标地址 - 本地服务不可达时自动启动 `pnpm dev` - 复用已有本地服务时不接管其生命周期 - 支持 `--no-dev-server` 禁止自动启动 - 新增验收场景库:`tests/expect/revenue-bugfix-clear-scope/scenarios.json` - 覆盖 `#78`、`#39`、`#50`、`#53`、`#58/#59`、`#69/#76` 和基础回归。 - 场景来源为 `docs/superpowers/plans/2026-06-08-revenue-bugfix-clear-scope-acceptance-test.md`。 - 使用环境占位符表达测试账号、客户和业务数据,不在前端仓硬编码 live 数据。 - 新增验收场景加载模块:`tools/expect/acceptance-scenarios.mjs` - 验收指令默认使用严格黑盒规约:正式验收计划为 oracle,不以源码、路由、store、API 封装或既有自动化测试作为通过依据。 - 通过标准固定为 `PASS / FAIL / BLOCKED`,缺数据、缺权限或业务状态不足时必须标记 `BLOCKED`。 - 新增验收数据预检: - `acceptance` 运行前检查场景所需环境变量。 - 缺少测试账号、客户或业务记录时直接输出 `BLOCKED` 并以退出码 `2` 结束,不启动浏览器,不使用占位符继续测试。 - 新增 runner/场景单元测试: - `tests/expect/revenueBugfixAcceptanceScenarios.test.mjs` - `tests/expect/runExpectRunnerArgs.test.mjs` - 新增使用说明:`tests/expect/README.md` ## 验证命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --check tools/expect/run-expect.mjs node --check tools/expect/acceptance-scenarios.mjs node tools/expect/run-expect.mjs --help pnpm exec expect tui --help node -e "const pkg=require('./package.json'); console.log(pkg.scripts['test:expect']); console.log(pkg.scripts['test:expect:smoke']); console.log(pkg.scripts['test:expect:watch']); console.log(pkg.devDependencies['expect-cli'])" node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs pnpm test:expect:acceptance -- --list pnpm test:expect:acceptance -- rev-bugfix-39-counter-prepay-settlement ``` ## 验证结果 - runner 语法检查:通过。 - 验收场景加载模块语法检查:通过。 - runner 帮助输出:通过,显示 `test:expect`、`test:expect:smoke`、`test:expect:watch` 用法及 `EXPECT_BASE_URL` 等环境变量。 - `expect-cli` 本地可执行性:通过,`pnpm exec expect tui --help` 成功输出 CLI 参数说明。 - `package.json` 脚本解析:通过,`test:expect`、`test:expect:smoke`、`test:expect:watch`、`test:expect:acceptance` 均指向 `tools/expect/run-expect.mjs`,开发依赖版本为 `^0.1.3`。 - 验收场景单元测试:通过,8 项通过、0 项失败。 - 验收场景列表命令:通过,列出 7 个场景及各自 requiredData。 - 严格数据预检:通过。执行 `pnpm test:expect:acceptance -- rev-bugfix-39-counter-prepay-settlement` 时,由于未提供 `EXPECT_TEST_CASHIER_A_USERNAME` 和 `EXPECT_TEST_CUSTOMER_C4`,命令输出 `BLOCKED` 并以退出码 `2` 结束,未启动浏览器。 - `typecheck/vue-tsc`:按用户要求未继续执行,后续本项不作为该接入任务的默认验证。 - 浏览器实际 smoke:未执行。本次完成框架接入、验收场景库和 CLI 可用性验证;真实业务验收需要测试环境提供 C1-C5、收费员 A/B、审批账号、水价模板、未结账/已结账记录等数据后运行。 ## 使用入口 ```bash pnpm test:expect pnpm test:expect:smoke pnpm test:expect:watch -- -m "test the flow you changed" pnpm test:expect:acceptance -- --list pnpm test:expect:acceptance -- rev-bugfix-53-prepaid-deduction pnpm test:expect:acceptance -- all EXPECT_BASE_URL=http://localhost:18081 pnpm test:expect ``` ## 重新测试记录:2026-06-08 严格验收重跑 ### 触发背景 前端工作区新增了红冲记录页面的时间范围默认时间处理: - `src/views/operatingCharges/redReversalRecord/index.vue` - `tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` ### 执行命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend pnpm test:expect:acceptance -- all pnpm test:expect:acceptance -- rev-bugfix-58-59-red-reversal-record node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs ``` ### 结果 - 严格全量验收:`BLOCKED`。当前 shell 未提供 `EXPECT_TEST_*` 测试账号、客户和业务记录数据,runner 未启动浏览器,未使用占位符继续测试。 - `#58/#59` 红冲记录严格验收:`BLOCKED`。缺少: - `EXPECT_TEST_CASHIER_A_USERNAME` - `EXPECT_TEST_SETTLED_COUNTER_RECORD` - 代码契约验证:通过,`tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` 共 5 项通过、0 项失败。 - Expect 场景/runner 单元测试:通过,8 项通过、0 项失败。 - `typecheck/vue-tsc`:未执行。 ### 结论 本次只确认了红冲记录代码契约和 Expect 严格验收框架本身仍可用。正式黑盒业务验收未通过也未失败,状态为 `BLOCKED`,需要提供测试账号、客户和已结账可红冲记录后重新执行。 ## 收费与账务闭环场景库接入:2026-06-08 ### 范围 基于 `/Volumes/Dpan/github/water-workspace/docs` 中收费、结账、预存抵扣业务资料,以及 `../water-docs/specs/001-rev004-accounting/` 中账务处理一期口径,新增前端 `expect-cli` 可执行场景 suite: - `tests/expect/revenue-accounting-closures/scenarios.json` - `tests/expect/revenue-accounting-closures/README.md` ### 场景 初版纳入 12 条场景: - P0 小闭环: - `revenue-charge-normal-payment` - `revenue-charge-no-arrears-topup` - `revenue-charge-prepay-zero-confirm` - `revenue-charge-prepay-partial-deduction` - `revenue-charge-prepay-full-deduction` - P0 跨页面大闭环: - `closure-charge-to-settlement` - `closure-prepay-charge-to-settlement` - `closure-settlement-to-red-reversal-record` - P1 账务处理小闭环: - `accounting-unsold-split-submit` - `accounting-unsold-bad-debt-submit` - `accounting-unsold-price-diff-submit` - `accounting-unsold-penalty-remission-submit` ### 工具调整 - `tools/expect/acceptance-scenarios.mjs` 支持多 suite 加载。 - 场景引用支持: - `revenue-accounting-closures:all` - `revenue-accounting-closures:` - 全局唯一场景可直接使用 `` - `requiredData` 扩展到账务和收费闭环数据键,例如 `customerArrears`、`customerNoArrears`、`unsoldBillCustomer` 等。 ### 验证命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --test tests/expect/revenueAccountingClosureScenarios.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs node --check tools/expect/acceptance-scenarios.mjs node --check tools/expect/run-expect.mjs pnpm test:expect:acceptance -- --list pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement ``` ### 结果 - 多 suite 场景加载、schema、requiredData 映射、prompt 生成测试:通过,15 项通过、0 项失败。 - runner 语法检查:通过。 - 场景列表命令:通过,可列出 bugfix suite 和 `revenue-accounting-closures` suite。 - 严格业务执行:`pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement` 返回 `BLOCKED`,缺少 `EXPECT_TEST_CASHIER_A_USERNAME` 与 `EXPECT_TEST_CUSTOMER_ARREARS`,未启动浏览器,不作为失败或通过。 - `typecheck/vue-tsc`:未执行。 ## 验证记录:2026-06-08 收费与账务闭环 suite ### 执行命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --check tools/expect/acceptance-scenarios.mjs node --check tools/expect/run-expect.mjs node --test tests/expect/revenueAccountingClosureScenarios.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/runExpectRunnerArgs.test.mjs node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs pnpm test:expect:acceptance -- --list pnpm test:expect:acceptance -- revenue-accounting-closures:all pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement ``` ### 结果 - runner 语法检查:通过。 - Expect 场景/runner 单元测试:通过,15 项通过、0 项失败。 - 营收缺陷代码契约测试:通过,5 项通过、0 项失败。 - 场景列表:通过,列出 `revenue-bugfix-clear-scope` 与 `revenue-accounting-closures` 两个 suite。 - `revenue-accounting-closures:all`:`BLOCKED`。缺少收费员、欠费客户、无欠费客户、预存余额客户、已结账红冲记录、管理员和未销账单客户等测试数据。 - `revenue-accounting-closures:closure-charge-to-settlement`:`BLOCKED`。缺少: - `EXPECT_TEST_CASHIER_A_USERNAME` - `EXPECT_TEST_CUSTOMER_ARREARS` - 浏览器黑盒业务执行:未启动。阻塞发生在 requiredData 预检阶段,符合严格验收规则。 - `typecheck/vue-tsc`:未执行。 ## 验证记录:2026-06-08 Expect runner 与页面 smoke 重跑 ### 触发背景 前端工作区继续调整了 Expect runner 可执行性,并对红冲记录页的红冲时间范围默认时间进行了补充: - `tools/expect/run-expect.mjs` - `tests/expect/runExpectRunnerArgs.test.mjs` - `src/views/operatingCharges/redReversalRecord/index.vue` - `tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs` ### 工具调整 - `tools/expect/run-expect.mjs` 改为优先调用本地 `node_modules/.bin/expect`,避免 `pnpm exec expect` 在当前工作区触发隐式 `pnpm install`。 - runner 增加 `EXPECT_BIN` 覆盖入口,便于特殊环境指定 Expect 可执行文件。 - runner 过滤 npm/pnpm 转发参数中的独立 `--` 分隔符,修复 `pnpm test:expect:acceptance -- ` 被 Expect 识别为多余位置参数的问题。 ### 执行命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --test tests/expect/runExpectRunnerArgs.test.mjs node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs corepack pnpm@9.15.9 test:expect:acceptance -- --list source /tmp/revenue-acceptance-env.sh corepack pnpm@9.15.9 test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose ./node_modules/.bin/eslint tools/expect/run-expect.mjs tests/expect/runExpectRunnerArgs.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs src/views/operatingCharges/redReversalRecord/index.vue corepack pnpm@9.15.9 ts:check NODE_OPTIONS=--max-old-space-size=16384 corepack pnpm@9.15.9 ts:check corepack pnpm@9.15.9 build:dev ``` ### 结果 - runner 单元测试:通过,5 项通过、0 项失败。 - Expect 场景加载测试:通过,12 项通过、0 项失败。 - 营收缺陷代码契约测试:通过,5 项通过、0 项失败。 - 场景列表命令:通过。需使用 `corepack pnpm@9.15.9`;当前 shell 的全局 `pnpm@11.5.1` 会在脚本执行前尝试清理并重装 `node_modules`,无 TTY 时退出。 - `rev-bugfix-50-cashier-filter` 严格黑盒验收:`BLOCKED`。requiredData 环境变量已提供,但 Expect 启动 Codex ACP 后返回 `401 Unauthorized`,提示当前 Codex agent 未认证或 API key 无效;未进入浏览器业务步骤,不可判定 `PASS` 或 `FAIL`。 - 页面 smoke(Playwright fallback):通过登录默认租户 `福建水投集团`、用户 `admin` 后访问真实菜单路由: - `/operatingCharges/counterCheckout`:页面标题为 `营业收费管理系统 - 柜台结账`,未出现 404,无 failed network request;截图在 `water-frontend/test-results/counter-checkout-smoke.png`。 - `/operatingCharges/redReversalRecord`:页面标题为 `营业收费管理系统 - 红冲记录`,查询区显示 `红冲时间`,表格显示柜台红冲记录字段,无 failed network request;截图在 `water-frontend/test-results/red-reversal-record-smoke.png`。 - 页面 smoke 备注:运行时存在既有 Vue/router warning,包括未解析菜单组件 `system/userformconfig/index`、`pay/demo/transfer/index`,以及 `inject() can only be used inside setup()` 等;未在本次范围内修复。 - focused ESLint:通过。 - `ts:check`:失败。默认堆内存运行先 OOM;增大到 16G 后完成但暴露 repo-wide 既有 TypeScript 错误,涉及 mall statistics、BPM designer、pay views、system views、settings 等大量非本次修改文件。本结果不作为本次改动通过项。 - `build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍有既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 ### 结论 Expect runner 的本地执行入口和 pnpm 参数转发问题已修复并由单元测试覆盖。`rev-bugfix-50-cashier-filter` 严格黑盒验收当前阻塞于 Codex ACP 认证,状态为 `BLOCKED`;页面级 fallback smoke 只证明页面可登录访问和基础渲染,不替代正式黑盒业务验收。 ## 修复记录:2026-06-08 Expect runner 完整收敛 ### 触发背景 上一轮验证后仍有三个仓库内可控问题: - 当前 shell 的全局 `pnpm@11.5.1` 与 `node_modules/.modules.yaml` 中的 `pnpm@9.15.9` 布局不一致,未 pin 时会触发脚本前置安装/清理风险。 - runner 自动启动 dev server 时仍通过 `pnpm dev`,在 pnpm 版本不一致时可能复现同类问题。 - `tests/expect` 场景中存在 `/operating-charges/...` 旧路由元数据,而当前真实菜单路由为 `/operatingCharges/...`。 - Expect 调用 Codex ACP 认证失败时输出原始栈,不够符合严格验收的 `BLOCKED` 语义。 ### 实现内容 - `package.json` 新增 `packageManager: pnpm@9.15.9`。 - `tools/expect/run-expect.mjs`: - dev server 启动改为直接调用本地 `node_modules/vite/bin/vite.js --mode dev`。 - 保留 `EXPECT_DEV_SERVER_BIN` 用于特殊环境覆盖。 - 捕获 Expect 输出并识别 Codex ACP `401 Unauthorized` / `AcpProviderUnauthenticatedError`,转为清晰 `BLOCKED` 输出和退出码 `2`。 - `tests/expect/revenue-bugfix-clear-scope/scenarios.json`: - 为 bugfix 场景补充真实页面路由元数据。 - `tests/expect/revenue-accounting-closures/scenarios.json`: - 将收费、结账、红冲场景的旧路由更新为 `/operatingCharges/counterCharging`、`/operatingCharges/counterCheckout`、`/operatingCharges/redReversalRecord`。 - `tests/expect/runExpectRunnerArgs.test.mjs`、`tests/expect/revenueBugfixAcceptanceScenarios.test.mjs`、`tests/expect/revenueAccountingClosureScenarios.test.mjs` 补充回归测试覆盖上述行为。 ### 执行命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --test tests/expect/runExpectRunnerArgs.test.mjs node --test tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs node --test tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs node --test tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs ./node_modules/.bin/eslint tools/expect/run-expect.mjs tools/expect/acceptance-scenarios.mjs tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs src/views/operatingCharges/redReversalRecord/index.vue pnpm test:expect:acceptance -- --list pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement source /tmp/revenue-acceptance-env.sh pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose pnpm build:dev ``` ### 结果 - runner 单测:通过,9 项通过、0 项失败。 - Expect 场景测试:通过,14 项通过、0 项失败。 - 合并执行 Expect runner/场景测试:通过,23 项通过、0 项失败。 - 营收缺陷契约测试:通过,5 项通过、0 项失败。 - focused ESLint:通过。 - `pnpm test:expect:acceptance -- --list`:通过,可在 plain `pnpm` 下列出两个 suite 的场景。 - `pnpm test:expect:acceptance -- revenue-accounting-closures:closure-charge-to-settlement`:按 requiredData 预检返回 `BLOCKED`,缺少 `EXPECT_TEST_CASHIER_A_USERNAME` 与 `EXPECT_TEST_CUSTOMER_ARREARS`,退出码 `2`。 - `pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter --target unstaged --timeout 120000 --verbose`:requiredData 已提供,但 Codex ACP 认证失败,runner 输出清晰 `BLOCKED: Codex ACP authentication failed before browser acceptance steps ran...`,退出码 `2`,未再输出原始 ACP 栈。 - `pnpm build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍存在既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 ### 结论 本次已将仓库内可控问题收敛:pnpm 版本、runner 启动路径、场景路由元数据、Codex ACP 认证失败语义均已有自动化测试覆盖。严格黑盒业务验收仍取决于外部 Codex ACP 认证状态;认证未完成时应按 `BLOCKED` 处理,不应判定业务 `PASS` 或 `FAIL`。 ## 本地 Playwright smoke 入口:2026-06-08 无 ACP 场景 ### 触发背景 用户本机没有 Codex ACP 认证,`pnpm test:expect:acceptance -- rev-bugfix-50-cashier-filter` 只能得到 `BLOCKED`,无法进入浏览器业务步骤。为保证前端页面链路仍可在本地验证,本次新增不依赖 ACP 的 Playwright smoke runner。 ### 实现内容 - `package.json` 新增 `test:revenue:smoke`,执行 `node tools/revenue/run-local-smoke.mjs`。 - `tools/revenue/run-local-smoke.mjs`: - 默认读取 `/tmp/revenue-acceptance-env.sh`,支持 `REVENUE_SMOKE_ENV_FILE` 覆盖。 - 使用 `EXPECT_BASE_URL`、`EXPECT_TEST_ADMIN_USERNAME`、`EXPECT_TEST_ADMIN_PASSWORD` 等本机环境变量登录本地前端代理 `/admin-api/system/auth/login`。 - 自动复用或启动本地 Vite dev server。 - 访问 `/operatingCharges/counterCheckout` 与 `/operatingCharges/redReversalRecord`,检查页面标题/关键文案、登录状态、not-found 状态,并输出截图。 - 对登录不可达、认证被拒等数据/环境问题输出 `BLOCKED`,退出码 `2`。 - 修复两个 runner 稳定性问题:`SmokeBlockedError` TDZ、业务流水号包含 `404` 时误判为 404 页。 - `tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs` 覆盖 env 解析、默认配置、页面清单、BLOCKED 输出、404 误判和超时 helper。 ### 执行命令 ```bash cd /Volumes/Dpan/github/water-workspace/water-frontend node --test tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs pnpm test:revenue:smoke node --test tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs tests/revenue-bugs/revenueBugfixClearScope.contract.test.mjs node --test tests/expect/runExpectRunnerArgs.test.mjs tests/expect/revenueBugfixAcceptanceScenarios.test.mjs tests/expect/revenueAccountingClosureScenarios.test.mjs pnpm exec eslint tools/revenue/run-local-smoke.mjs tests/revenue-bugs/revenueLocalSmokeRunner.test.mjs pnpm build:dev ``` ### 结果 - 本地 smoke runner 单测:通过,9 项通过、0 项失败。 - 本地页面 smoke:通过。 - `/operatingCharges/counterCheckout`:登录用户 `admin`,页面显示 `未结账`、`已结账`、`收费员`;截图为 `water-frontend/test-results/counter-checkout-local-smoke.png`。 - `/operatingCharges/redReversalRecord`:页面显示 `红冲记录`、`红冲时间`、`收费员`;截图为 `water-frontend/test-results/red-reversal-record-local-smoke.png`。 - 营收缺陷契约测试 + 本地 runner 单测:通过,14 项通过、0 项失败。 - Expect runner/场景测试:通过,23 项通过、0 项失败。 - focused ESLint:通过。 - `pnpm build:dev`:通过,输出 `Build successful. Please see dist directory`。构建期间仍存在既有 Vite CJS deprecation warning、SVG symbolId warning、Rollup PURE annotation warning。 ### 结论 本地前端页面链路现在可以通过 `pnpm test:revenue:smoke` 在无 ACP 的机器上执行。该入口证明登录、动态菜单路由、页面基础渲染和截图可用;它不替代 `expect-cli` 严格黑盒验收,也不验证 #50 收费员 A/B 业务数据筛选结果。严格业务验收仍需 ACP、其他可用 agent,或人工按正式验收计划执行。