放宽两处负载敏感的E2E超时预算 [09-06-release-gate-integrity]

750a184b 两轮 verify-candidate 在 2 核主机/4 worker 下均因同两处超时失败:
- 报销付款批次主链路:全部阶段在 305s/303s 完成,超出 300s(单跑 145s)→ 420s
- 项目级视觉 pc:admin:15 页在 180s 内完成 14 页 → 每组 240s(用例级覆盖)

所有断言、worker 数、重试及 Playwright 项目默认 180s(回执校验项)不变;
规约同步视觉分组预算。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
2026-09-26 14:42:49 +08:00
共同撰写人 Claude Opus 5.5
父节点 750a184b8a
当前提交 34675e1a98
共修改 3 个文件,包含 5 行新增和 2 行删除
+1 -1
查看文件
@@ -22,7 +22,7 @@
- After a successfully owned local server start, `run-web-gates.sh` recalculates `PLAYWRIGHT_OCR_MOCK` from that startup's `OCR_PROVIDER=mock` and `JOBS_ENABLED=true`; a caller's flag cannot enable unsupported capability. Each startup appends non-secret provider/job facts to `server-capabilities.jsonl` in the run report. Actual missing-field correction still has to pass; configuration alone is not behavior evidence.
- R108 uses an active synthetic reimbursement submitted through formal APIs, with a valid PDF and explicit item binding. Initialization fails the test rather than skipping it. Preserve the employee approval refusal, current approve/return and no-reject contract, offline upload queue, 390/414 layouts, and independent output paths. An incomplete visual report is not PASS just because findings is empty.
- The existing project visual matrix explicitly lists all 14 current system routes. Unknown wildcards/parameters and unowned system routes fail route-plan preparation. AP uses finance, system/audit uses admin, approval uses manager, and login uses an anonymous context. Require exact target URL plus a page-specific title or workspace anchor; 403/404/login fallback and same-origin API 403/404 are failures, not target page coverage. Mock response controls must declare UTF-8 so Chinese error headings exercise the intended guard.
- Per-route arrival and full audit completion are separate: record completion only after the screenshot and all DOM checks. The approved matrix is 25 PC + 8 mobile pages, grouped into seven role/viewport tests with 180 seconds each and one timed synthetic preparation. Preserve all assertions, screenshots, configured workers and zero retries; only this file's groups remain serial as before. Compare exact planned/completed route-role-viewport identities, reject missing/duplicate/unexpected pages and wrong arrivals, and require all seven actual test statuses passed. Failed or skipped serial successors must leave the report incomplete; unrelated guard tests cannot overwrite it. Matrix coverage does not mean every product page. Live/frozen obligations remain in full discovery; focused passes do not change ordinary eligibility.
- Per-route arrival and full audit completion are separate: record completion only after the screenshot and all DOM checks. The approved matrix is 25 PC + 8 mobile pages, grouped into seven role/viewport tests with 240 seconds each (per-test override; the Playwright project default stays 180 seconds and remains a receipt check) and one timed synthetic preparation. Preserve all assertions, screenshots, configured workers and zero retries; only this file's groups remain serial as before. Compare exact planned/completed route-role-viewport identities, reject missing/duplicate/unexpected pages and wrong arrivals, and require all seven actual test statuses passed. Failed or skipped serial successors must leave the report incomplete; unrelated guard tests cannot overwrite it. Matrix coverage does not mean every product page. Live/frozen obligations remain in full discovery; focused passes do not change ordinary eligibility.
## Public OA Boundary
@@ -606,6 +606,8 @@ test.describe.serial("项目级全页面视觉巡检", () => {
for (const group of groups) {
test(group.id, async ({ browser }) => {
// Admin audits 15 pages in one group; 180s ran out on a loaded 2-core host.
test.setTimeout(240_000);
const groupPlans = plans.filter(plan => plan.viewport === group.viewport && plan.role === group.role);
await auditPlans(browser, groupPlans, group.viewport);
expect(findings.filter(finding => finding.severity === "P1"), `项目级视觉巡检失败,报告:${reportPath()}`).toEqual([]);
@@ -2,6 +2,7 @@ import { test } from "@playwright/test";
import { reimbursementPaymentFlow } from "./helpers/reimbursementPaymentFlow";
test("E2E 报销付款批次主链路:提交 -> 审批 -> 创建批次 -> 复核 -> 执行 -> 下游收口", async ({ page }) => {
test.setTimeout(300_000);
// Every stage finished at ~305s under 4 workers on a 2-core host (~145s alone).
test.setTimeout(420_000);
await reimbursementPaymentFlow(page);
});