PR向けブラウザ動画証明
UI修正を証明する短く再生可能なブラウザ動画を録画し、PR説明に添付して、本文を確認します。ユーザーが明示的に依頼しない限り、録画のためにアプリケーションコードを変更しないでください。
参考実行: PR #723(/automations expanded 長時間スクロール)。
前提条件
ghがターゲットリポジトリへのプッシュアクセスで認証済みであること- ワークツリーにBun + リポジトリの依存関係がインストールされていること(
bun install) - ホストに Google Chrome(または Chromium)がインストールされていること
- PATHに
ffmpegが通っていること(webm → H.264 MP4変換用) /tmp以下の隔離ディレクトリにPlaywrightがインストールされていること(リポジトリには追加しない):
mkdir -p /tmp/<run>/playwright
cd /tmp/<run>/playwright
npm i playwright
npx playwright install ffmpeg
プロセス
1. git worktreeで隔離する
メインチェックアウトをクリーンに保ちます。
cd "$(git rev-parse --show-toplevel)"
git fetch origin main
git worktree add -b <branch> .worktrees/<slug> origin/main # または修正ブランチにアタッチ
cd .worktrees/<slug>
サーバーと録画はそのワークツリー内だけで行います。
2. 最初にフィクスチャとUIを確認する
データを発明する前に:
- テスト対象のページ(ラベル、展開コントロール、スクロールコンテナ)を読む。
- 同じ機能の既存のテストフィクスチャ/ファクトリを確認する。
- 公開HTTP API経由でのシードを優先する。必要な行を作成できるAPIがない場合(例: 巨大な
outputを持つ完了した自動化実行)に限り、隔離されたNAKAMA_CONFIG_DIR内で単発のSQLite挿入にフォールバックする。
3. 決定論的な高さのコンテンツをシードする
スクロール/オーバーフローの証明には、フィクスチャがペインよりも高くなければなりません。
- 先頭付近にユニークなトップマーカーを配置:
SCROLL_PROOF_MARKER_TOP - 末尾にユニークなボトムマーカーを配置:
SCROLL_PROOF_MARKER_BOTTOM scrollHeight - clientHeightが大きくなるように(数千px)十分な本文テキストを使用する。
実行出力の例:
# SCROLL_PROOF_MARKER_TOP — 長い自動化実行の出力
## セクション 1
...
## セクション 80
...
# SCROLL_PROOF_MARKER_BOTTOM — 高コンテンツの終わり
オペレーターの実際の ~/.nakama データには決してシードしないでください。常に /tmp/<run>/ 以下の新しい NAKAMA_CONFIG_DIR を使用してください。
4. 隔離されたローカルサーバーを起動する
空きポートを選んでください。4310 / 3000 / 3003 に何かが既にリッスンしている場合はデフォルトのスタックを使用しないでください。
RUN=/tmp/<run>
API_PORT=4330
WEB_PORT=3014
mkdir -p "$RUN/nakama-data" "$RUN/logs"
# シェル終了後もプロセスを生かし続ける(通常の nohup ... & ではここで死にます)
setsid nohup env NAKAMA_CONFIG_DIR="$RUN/nakama-data" NAKAMA_PORT=$API_PORT \
bun run apps/server/src/index.ts \
>"$RUN/logs/server.log" 2>&1 < /dev/null &
setsid nohup env VITE_API_URL="http://127.0.0.1:${API_PORT}" \
bun run --cwd apps/web dev -- --host 127.0.0.1 --port $WEB_PORT \
>"$RUN/logs/web.log" 2>&1 < /dev/null &
curl -sf http://127.0.0.1:$API_PORT/health が成功し、Webオリジンが応答するまで待機します。新規セットアップ: POST /v1/auth/setup → プロバイダー作成 → プロファイル/自動化作成(またはフィクスチャを再利用)し、Cookie + X-CSRF-Token + X-Org-Id を使用します。
5. Playwrightで録画する(H.264 MP4)
レコーダーは /tmp/<run>/ 以下にのみ展開してください。決してコミットしないでください。
const browser = await chromium.launch({
channel: "chrome", // Chromeがインストールされている場合
headless: false,
args: ["--disable-gpu"],
});
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
recordVideo: { dir: rawDir, size: { width: 1440, height: 900 } },
});
ルール:
- テスト対象の実際のUIパスを操作する(role/text ロケーターを使用)。
- 動きを可視化する — マウスホイールまたはステップスクロールを使用し、単一の見えないジャンプだけにしない。
- スクロールが移動したこと(
scrollTopの差分)と、ボトムマーカーが到達可能になったことをアサートする。 context.close()の前にpage.video()?.path()を取得する。- 変換:
ffmpeg -y -i in.webm -c:v libx264 -pix_fmt yuv420p out.mp4 results.json+ 前後のスクリーンショットをartifacts/e2e-<id>/以下に書き込む。
WebMのみではGitHubでの再生に不十分です。H.264 + yuv420p を出力してください。
6. 動画を主張する前に検証する
ffprobe -v error -show_entries stream=codec_name,width,height \
-show_entries format=duration -of json out.mp4
# 初期フレームと後期フレームを抽出して確認
ffmpeg -y -ss 00:00:02 -i out.mp4 -vframes 1 frame-early.png
ffmpeg -y -ss 00:00:08 -i out.mp4 -vframes 1 frame-late.png
以下の条件をすべて満たす場合のみ合格:
- コーデックが
h264である - 継続時間がインタラクションを確認するのに十分な長さである
- 初期フレームが開始状態(例: トップマーカー/展開ペイン)を示している
- 後期フレームがスクロールの進行(ボトムマーカーまたは詳細セクション)を示している
results.jsonが実際のscrollTopの差分(または同等の証明メトリック)を報告している
7. GitHub user-attachmentsにアップロードする
ドキュメント化されていませんが、プッシュアクセスがある場合、画像/動画に対してトークン認証が機能します:
TOKEN=$(gh auth token)
REPO_ID=$(gh api repos/<owner>/<repo> --jq .id)
MP4=artifacts/e2e-<id>/<name>.mp4
UPLOAD_JSON=$(curl -sS -X POST \
"https://uploads.github.com/user-attachments/assets?name=$(basename "$MP4")&repository_id=${REPO_ID}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: video/mp4" \
-H "Accept: application/vnd.github+json" \
--data-binary @"${MP4}")
VIDEO_URL=$(printf '%s' "$UPLOAD_JSON" | bun -e 'console.log(JSON.parse(await Bun.stdin.text()).url)')
echo "$VIDEO_URL" # https://github.com/user-attachments/assets/<uuid>
URLを保存します。アセットへのHEAD/GETで動画コンテンツタイプが返ってくることを確認します。
8. PR説明を更新する
ブラウザ証明 セクションを短く追加し、示した手順と https://github.com/user-attachments/assets/... URLを単独行で記載します(GitHubがプレーヤーを埋め込みます)。ファイル経由で本文を書くことを推奨します:
gh api repos/<owner>/<repo>/pulls/<n> --method PATCH --input body.json
# または: gh pr edit <n> --body-file /tmp/pr-body.md
本文の残りは .agents/skills/adhd-pr-description/SKILL.md に従ってください。
9. ライブのPR本文を確認する
gh api repos/<owner>/<repo>/pulls/<n> --jq .body | rg 'user-attachments/assets/<uuid>|Browser proof'
このチェックが通るまで成功を報告しないでください。
例: automations expanded-run スクロール
- 修正ブランチ(またはこのスキル用のドキュメントのみのブランチ)にワークツリー。
- 隔離API
4330+ Web3014、新しいNAKAMA_CONFIG_DIR。 POST /v1/auth/setup→ プロバイダー → 自動化 Long output digester を作成。outputがSCROLL_PROOF_MARKER_TOP/SCROLL_PROOF_MARKER_BOTTOMを含む長いマークダウンである実行を1つ挿入/完了する。- Playwright:
/automationsを開く → 自動化を選択 → Expand run → 詳細ペインをホイールスクロールしてボトムマーカーが表示されるまで進める。 - H.264 MP4に変換、フレームを検査、アップロード、PR本文をパッチ、確認。
クリーンアップ
- 選択したポートで起動した隔離API/Webリスナーをkillする。
/tmp/<run>/とプロファイルartifacts/e2e-<id>/をローカルの証拠として残す(動画やレコーダースクリプトはコミットしない)。- ブランチがマージされるか破棄されたらワークツリーを削除する:
git worktree remove .worktrees/<slug>
誠実さルール
- フレームまたは
ffprobe+ スクリーンショットを確認せずにブラウザ証明を主張しない。 - アップロードしてライブのPR本文から再取得していない
user-attachmentsURLを貼らない。 - リクエストが視覚的な証拠であった場合に、緑のユニットテストを動画の代わりとして扱わない。
- スクロールが移動しなかった、マーカーが間違っている、またはMP4が空/破損している場合は、失敗したと報告する。緩和しない。
- ユーザーがプロダクト修正を依頼しない限り、「動画を撮りやすくするため」にアプリケーションコードを変更しない。
- オペレーターの実際のNakama設定ディレクトリに触れない。