2026 OpenClaw 前端實戰:
遠端 Mac 聚合 JUnit、trace 索引與 stderr,單一 PR 門禁摘要 HowTo
對象:在遠端 Mac 跑 Playwright,想把 JUnit XML、trace 附件與 stderr 尾段收成一則可審計的 PR 門禁摘要的團隊。結論:Runner 只負責落盤與上傳;OpenClaw 網關讀機讀成果、套用閾值、套模板、處理重試,避免把敏感 URL 或整包 trace 直接貼進留言。與分片聚合報告、trace/HAR 最小複現摘要併讀時,可把「合併統計」與「可回放證據」分工清楚;需要與權杖階段欄位對齊時參考Token E2E 摘要。
01 報告路徑約定
門禁要穩,先讓每一台遠端 Mac Job 寫入同一套相對路徑,合併腳本才不猜檔名。建議以 ${GIT_SHA} 為根,底下按 shard 或專案分子目錄;每個葉節點至少含 junit.xml(或 Playwright 產生的 JUnit)、report.json、runner.stderr.log,以及 attachments/manifest.json 描述本輪 trace/截圖相對路徑。
- 禁止多矩陣共用同一檔名覆寫;目錄名必含 shard 索引或矩陣軸值。
- 合併輸出寫入
.../merged/e2e_gate.json與.../merged/pr_e2e_summary.md,網關只讀 merged,不回寫各子目錄。 - 與既有分片約定對齊時,可直接沿用分片報告中的
artifacts/e2e/結構,只在葉節點多放 manifest 與 stderr。
02 閾值策略
門禁不是「有紅字就擋」,而是把可接受的不穩定與資源上限寫成版本化設定(例如 thresholds/e2e.yaml),讓同一 PR 可重播判定理由。
| 維度 | 建議欄位 | 說明 |
|---|---|---|
| 失敗案例數 | max_failures、max_flaky_ratio |
與重試後 JUnit 對齊;flake 另計,不得與硬失敗混算 |
| 附件體積 | max_trace_listed、max_bytes_per_pr |
摘要只列前 N 筆 trace 索引,其餘以件數與總量表示 |
| 日誌片段 | stderr_tail_lines、redact_patterns |
尾段截斷並套用去敏規則,避免權杖進 PR |
若缺任一分片或 manifest 不完整,合併器應設 partial: true,門禁預設不給綠勾,並在摘要首行標示「資料不完整」。
03 網關側模板
OpenClaw 網關將 e2e_gate.json 對應到固定 Markdown 區塊,人讀一致、機讀可 diff。建議區塊順序:狀態列(pass/fail/partial)→ 計數表(總數、失敗、flake、耗時)→ 失敗案例清單(最多 K 行,路徑截斷)→ trace 索引表(檔名、stable_id、雜湊前綴)→ stderr 片段(摺疊程式碼欄)→ 後續動作(本機重播指令)。
HTML 註解中放冪等鍵,例如 <!-- openclaw:e2e:${GIT_SHA} -->,更新同一則 PR 留言而非洗版。內文不嵌入需登入的預覽網址;工件連結僅用 CI 公開規則可複製的路徑說明。延伸將 trace 敘事化時,可對照trace/HAR 摘要文的章節契約,避免捏造未出現在工件中的 URL。
04 失敗重試
網關對 Git 供應商 API 的錯誤要可觀測:429 與 5xx 使用指數退避加 jitter,上限例如五次;連續失敗時把摘要寫入 workflow 註解或內部 Webhook,避免「門禁靜默沒留言」。Playwright 側重試仍由 Runner 配置(retries、workers)負責,與 API 重試分層,才容易從 JUnit 看出「第幾次嘗試才綠」。
- 同一
Idempotency-Key綁定GIT_SHA+workflow 名稱,避免並發 job 互相覆蓋留言。 - 合併耗時超過 SLO 時,先回傳「部分摘要」標記 partial,再非同步補齊附件索引。
05 HowTo:可複現主線步驟
- 在 playwright.config 啟用
reporter: [['junit', { outputFile: '.../junit.xml' }], ['json', { outputFile: '.../report.json' }]],並將 stdout/stderr 導向約定檔案。 - 失敗或重試收尾時,將 trace.zip/截圖寫入
attachments/,用小型 Node 腳本掃描目錄產出manifest.json(含 stable_id 與相對路徑)。 - 下載各矩陣工件到同一
${GIT_SHA}樹下,執行合併:解析多份 JUnit、以 stable_id 去重、與 report.json 交叉檢查計數。 - 依
thresholds/e2e.yaml判定 pass/fail/partial,寫入e2e_gate.json;渲染pr_e2e_summary.md。 - 網關帶冪等鍵呼叫 PR 留言 API;若 API 失敗,依上一節退避重試,仍失敗則落到 workflow 摘要欄位。
06 可執行腳本思路
下列片段示意「合併+摘要」責任邊界,實際專案可改為單一 pnpm e2e:merge 任務由 OpenClaw 觸發。
# 1) 掃描附件目錄 → manifest.json(Node 偽碼)
# glob('attachments/**/*.zip'), 每檔 { path, size, headSha256 }
# 與 junit 內 testcase name 做 fuzzy 對應或沿用 report.json 的 testId
# 2) 合併 JUnit(示例:使用 junit-merge- 類工具或自寫 xml parser)
# npx ts-node scripts/merge-junit.ts "artifacts/e2e/$SHA/*/junit.xml" \
# --out "artifacts/e2e/$SHA/merged/junit.merged.xml"
# 3) stderr 尾段(避免整檔進 PR)
# tail -n 120 "artifacts/e2e/$SHA/shard-0/runner.stderr.log" | \
# rg -v 'SECRET|Bearer|sk-' > "artifacts/e2e/$SHA/merged/stderr.tail.txt"
# 4) 網關:讀 merged/* 與 thresholds,POST pr_e2e_summary.md
將上述步驟納入與分片報告流程相同的 GitHub Actions/自建 Runner 模板,即可在 M 系列遠端 Mac 上重播完整鏈路。
路徑約定讓合併可重播,閾值讓門禁可辯護,網關模板讓 PR 可讀且不洩漏敏感連結,重試讓 API 失敗不會變成「假綠」。要在與 CI 同構的 Apple Silicon 上長時跑 WebKit 與 Chromium、再把成果餵給 OpenClaw,建議直接租用雲端 Mac 節點:請至購買/租用頁選套餐,並可先免登入瀏覽首頁與定價比對算力與保留時數;細節操作見幫助中心。延伸索引:公開技術見解。