6.5 KiB
6.5 KiB
执行证据:生产构建 runner 会话回落
环境与原样基线
- 候选:
5518e974a2e85f0036b8f7bbf71f86de0370b6cb;Nodev22.22.2;Playwright1.58.2。 - runner:
http://127.0.0.1:3000,单 worker、零 retry。本地 Vite dev 两份目标 spec 为15 passed,历史 8 个标题重复 3 次为24 passed;该结果不等价于历史SERVE_CLIENT_DIST=true的生产构建 runner。 - 对当前
dist使用 Vite preview 复现生产构建/PWA 行为,两份目标 spec 为11 passed / 4 failed。其中 3 条是历史会话回落标题,另 1 条是资产长表单 toast 遮挡点击,属于本任务外的新失败,不计入 8 条会话分类。
历史 8 条逐项映射(原样生产构建 runner)
| 历史标题 | 当前结果 | 说明 |
|---|---|---|
| 七个主要业务台账标题区保持一主操作加至多一个更多,列表工具不常驻 | FAIL | 后续完整导航时停在“正在加载会话...” |
| 采购页使用安全格式上传并通过认证 Blob 下载 | PASS | 本轮未复现历史回落 |
| 采购与资产列表、详情各自只请求职责内数据并恢复 URL 筛选 | PASS | 本轮未复现历史回落 |
| 采购与资产长表单详情对 403/404 使用同一安全错误态 | PASS | 本轮未复现历史回落 |
| 采购长表单切回记录列表时支持取消保持与确认放弃 | PASS | 本轮未复现历史回落 |
| 共享未保存保护覆盖浏览器返回取消、确认与刷新拦截 | FAIL | 接受 reload 后停在“正在加载会话...” |
| /projects /assets /reimbursements 在中等宽度下操作列可达且页面不横溢 | FAIL | 后续完整导航时停在“正在加载会话...” |
| E2E 全局搜索:采购与资产忽略旧 href 并使用实体 canonical 路径 | PASS | 第二次回到 portal 的历史回落本轮未复现 |
聚焦 trace 安全账本
聚焦复跑“七个主要业务台账标题区”仍失败。原始 trace 只保留在 gitignored 测试输出中;下列账本仅从中提取白名单字段:
- browser origin:loopback
http://127.0.0.1:3000;contextserviceWorkers=allow。 - 导航序列:
/login→/purchase-requests→/contracts-registry→/projects→/assets→/payment-batches。 - login:
POST /api/auth/login -> 200;随后GET /api/me -> 200。 - 前四次完整业务导航均发出
POST /api/auth/refresh -> 200,并各自完成GET /api/me -> 200。 - 最后一次完整导航仍发出
POST /api/auth/refresh -> 200,但其后的GET /api/me未完成;页面保持“正在加载会话...”,业务标题断言超时。 - 因每次完整导航都触发 refresh,
has_session缺失假设被本 witness 反证;当前控制变量应转向生产构建才启用的 PWA Service Worker,而不是重复安装 session hint。
下一控制变量
两份目标 spec 当前允许 Service Worker,而仓库现有认证、权限、合同和关键流程 E2E 普遍显式使用 serviceWorkers: "block"。下一步仅在 test context 增加该设置,保持 mock、业务断言、导航次数和产品认证代码不变;若同一生产构建 runner 消除历史回落,再结合独立前端 bootstrap 与后端 rotation 对照完成分类。
单变量控制结果
- 仅为两份目标 spec 增加
test.use({ serviceWorkers: "block" });未改 mock 响应、业务断言、完整导航、retry、PWA 产品实现或认证产品代码。 - 同一 production-built preview、单 worker、零 retry 下,历史 8 个标题由原样基线的 3 FAIL / 5 PASS 变为
8 passed。 - 该设置与这些 spec 的测试边界一致:用例以
page.route合成认证和业务 API;PWA Service Worker 属于被测页面之外的网络代理,会让 mock 拦截在构建产物下随安装/接管时机变化。阻断它不是弱化会话语义,而是让 API mock 成为该测试唯一网络事实源。
独立认证对照
- 真实前端 bootstrap:
login-portal-ux.spec.ts的“Portal bootstrap refresh 首次瞬时失败后重试成功仍保留登录态”在同一 preview runner 下1 passed。该用例显式安装 session hint,第一次 refresh 返回瞬时 500、后续重试成功,最终保持/portal。 - 后端 focused route:
auth.login.test.js为30 passed,包含登录建立 session、refresh 前锁定并重查账号、密码变更/重置撤销 session 等合同。 - 真实本地 PostgreSQL/HTTP:
run-web-gates.sh auth-security-local的 target gate 强制 loopback API、loopback PostgreSQL 与hyb_oa_auth_*临时库;实际自动避开已占用端口,应用 65 条迁移、写入合成种子并完成9/9认证安全回归,含 refresh/reset race,最终AUTH-REGRESSION PASS FULL。cleanup 后同前缀临时数据库计数为 0。 - 全过程未连接生产、未使用生产凭据、未部署。
分类检查点(先于永久修法)
唯一分类:FIXTURE。
支持证据:
- 原样 production-built/PWA runner 可重复复现同类会话 bootstrap 卡住;Vite dev 不复现,说明 runner 差异是必要条件。
- trace 反证 session hint 缺失:失败前每次完整导航都发出 refresh;最后一次 refresh 仍为 200,卡点是其后
/api/me未完成。 - 单一 test-context 变量
serviceWorkers: "block"在保持 8 条业务断言与完整导航不变时消除全部历史回落。 - 真实前端 bootstrap、后端 route 合同和 loopback 真实 PostgreSQL/HTTP 认证回归均通过,未出现同一会话回落根因。
反证与边界:
- 本轮没有证据支持 PRODUCT:认证产品代码未修改,真实后端 refresh/reset 竞争通过。
- 本轮没有证据支持 MIXED:fixture 控制消除历史 8 条失败,独立产品对照均通过。
- 资产长表单 toast 遮挡是本轮新观察的非会话失败,不改变本分类,也不在本任务顺手修复。
基于该检查点,允许把两处 serviceWorkers: "block" 保留为最小 test-only 修复;不得删除断言、完整导航或增加 retry。
修法后的完整目标回归
- 同一 production-built preview、单 worker、零 retry 完整运行两份目标 spec:
15 passed / 0 failed / 0 skipped。 - 历史 8 条全部包含在该结果中;两份文件测试总数仍为 15,关键完整导航未减少。
- 原样基线出现过的资产长表单 toast 遮挡在完整复跑中通过,按一次性非会话观察保留在基线说明中,不新登记本任务 residual。
- 聚焦诊断 raw trace 已从本地 HTML report 数据目录删除;任务只保留本文件中的白名单账本。