OpenClaw · Playwright · JUnit · trace · удалённый Mac · 2026

2026: фронтенд на удалённом Mac —
агрегация JUnit XML, индекс вложений trace и stderr в одну сводку ворот PR через OpenClaw

06.05.2026 E2E и ворота PR ~9 мин

Задача: после прогона Playwright на удалённом Mac ревьюеру нужна одна проверяемая сводка ворот PR: объединённый JUnit XML, индекс trace (путь и размер, без заливки целого архива в текст) и фрагменты stderr, привязанные к упавшим кейсам. Ниже — HowTo с четырьмя блоками H2: соглашение о путях, пороги, шаблон на стороне шлюза и повтор при сбоях; плюс идея исполняемых скриптов. Оркестрацию шардов и merge-reports разбираем в статье про шарды; минимальные trace и HAR — в playbook по trace; токены смоука — в E2E и токены. Открытый блог, главная и страница покупки доступны без входа.

Три типичных боли

  1. Шум от нескольких XML. По файлу на шард — в PR не видно целостной картины passed/failed/skipped.
  2. Раздувание из trace. Вставка zip или base64 в вебхук ломает лимиты и раскрывает привычки путей.
  3. Потеря сигнала в stderr. Полный лог нечитабелен; нужны короткие куски рядом с именем теста из JUnit.

01 Соглашение о путях отчётов

Зафиксируйте одинаковые относительные пути в репозитории для CI и для удалённого Mac: например artifacts/e2e/junit/shard-{n}/results.xml, каталог artifacts/e2e/traces/ и агрегат artifacts/e2e/merged/summary.json рядом с merged/results.xml. Рядом положите run_meta.json с версией Playwright, коротким SHA и именем проекта — без секретов и токенов.

Если на арендованном томе работают несколько веток, добавьте к корню префикс с OPENCLAW_RUN_ID или CI_PIPELINE_ID, чтобы параллельные прогоны не перезаписали чужие results.xml. Тот же префикс прокиньте в заголовки вебхука — так проще отладить «пустой merge» на стороне шлюза.

HowTo: включите junit reporter в конфиге или CLI; каждый job/shard пишет в свой подкаталог; финальный шаг на агрегаторе читает всё дерево artifacts/e2e/junit/, мерджит XML, затем сканирует trace и пишет trace_index.json только с метаданными. Лог раннера сохраняйте в файл, чтобы вторым проходом вырезать stderr по таймстемпам или маркерам кейсов.

Проверка воспроизводимости

Имя npm-скрипта или цели Makefile для merge должно быть одним и тем же в README и runbook — иначе локальный запуск и раннер на Mac разъедутся уже на первом шаге.

02 Пороговая стратегия

В summary.json закрепите поля, которые читает ворота: failed (любое ненулевое — красный merge), доля skipped, бюджет flake относительно скользящей медианы, и опционально slow_top_n для жёлтых предупреждений без блокировки. Коэффициенты версионируйте в JSON — не оставляйте «договорённости в чате».

Поле Ориентир Действие ворот
failed строго 0 для зелёного таблица упавших тестов в PR
skipped < 2% от total жёлтый блок с объяснением
stderr на кейс до ~80 строк или 2–4 КБ UTF-8 обрезка с маркером «…»

Ретраи самих тестов Playwright остаются в конфиге фреймворка; отдельно считайте ретраи публикации сводки в API платформы (см. следующий раздел), чтобы не смешивать метрики «флейк продукта» и «флейк доставки».

Для команд с ночными прогонами полезно хранить в том же JSON ссылку на baseline ветки main: тогда ворота PR сравнивают не только абсолютные числа, но и дельту к последнему зелёному коммиту — меньше ложных «жёлтых» из-за шума инфраструктуры на общем Mac.

03 Шаблон на стороне шлюза

OpenClaw должен получать компактный Markdown: первая строка — статус и тройка счётчиков; далее сворачиваемый блок с таблицей падений, первыми тремя строками индекса trace и картой «тест → stderr». Имена плейсхолдеров в шаблоне совпадают с ключами summary.json, чтобы шлюз не ветвился по типам отчётов.

Храните шаблон в репозитории, например .openclaw/templates/pr_gate_e2e.md, и прогоняйте его тем же ревью, что и код ворот. В теле комментария добавьте HTML-комментарий-якорь вида <!-- openclaw-e2e:${GIT_SHA} --> для последующих upsert.

Если шлюз допускает лёгкую генерацию текста моделью, передавайте ей уже нормализованный JSON (счётчики, топ-N имён тестов, три строки индекса trace) — сырой JUnit и мегабайты логов оставьте вне контекста. Так вы держите стоимость и задержку предсказуемыми при каждом push.

# Идея исполняемых шагов (Node/Bash) на агрегаторе после шардов:
node scripts/merge-junit-xml.mjs \
  --inputs "artifacts/e2e/junit/shard-*/results.xml" \
  --out-xml artifacts/e2e/merged/results.xml \
  --out-json artifacts/e2e/merged/summary.json
node scripts/build-trace-index.mjs --traces artifacts/e2e/traces --out artifacts/e2e/merged/trace_index.json
node scripts/extract-stderr-snippets.mjs --log run.log --junit artifacts/e2e/merged/results.xml \
  --out artifacts/e2e/merged/stderr_snippets.json
node scripts/openclaw-post-pr-summary.mjs \
  --bundle artifacts/e2e/merged \
  --template .openclaw/templates/pr_gate_e2e.md \
  --idempotency "${GIT_SHA}:e2e-junit"
Граница ответственности

Раннер на Mac считает и режет данные; шлюз валидирует схему, режет полезную нагрузку и рендерит Markdown. Сырые архивы остаются в артефактах CI с подписанными URL, а не в теле запроса к модели или к API комментариев.

04 Повтор при ошибках и идемпотентность

При 429 или 5xx от API ограничьте серию, например, пятью попытками: базовая задержка 200 мс, удвоение до потолка 30 с и джиттер до 10 с. Логируйте каждую попытку одной структурированной строкой (attempt, HTTP-код, задержка). Если два раза подряд не удалось распарсить ответ шлюза, сохраните только локальные JSON и не спамьте PR.

  • Заголовок Idempotency-Key: пара GIT_SHA + идентификатор ворот (например e2e-junit).
  • Счётчик ретраев публикации добавьте в summary.json для недельных отчётов SRE.
  • Не смешивайте обновление комментария с повторным полным прогоном suite без необходимости — дорого на Apple Silicon под нагрузкой.
Итог и ориентир по покупке

Когда слияние JUnit, индекс trace и усечённый stderr оформлены как скрипты и стабильные пути, одна сводка PR становится повторяемой и на CI, и на удалённом Mac. Нужен постоянный узел под WebKit и тяжёлые ворота — откройте тарифы, оформите аренду на странице покупки, затем вернитесь к списку блога и связанным материалам по шардам и trace.

Удалённый Mac · Playwright · OpenClaw · без входа

Сводка ворот и аренда узла одной линией процесса

Блог, главная, покупка; детали тарифов — тарифы, вопросы — помощь.

Ещё материалы: каталог блога.

Купить / аренда Mac под JUnit-ворота