Preuve vidéo navigateur pour PRs
Enregistrer une courte vidéo navigateur lisible qui prouve un correctif UI, l'attacher à la description de la PR, et vérifier le corps en direct. Ne pas modifier le code de l'application pour l'enregistrement sauf si l'utilisateur le demande explicitement.
Référence : PR #723 (/automations scroll long étendu).
Prérequis
ghauthentifié avec accès push au dépôt cible- Bun + dépendances du dépôt installées dans l'arbre de travail (
bun install) - Google Chrome (ou Chromium) sur l'hôte
ffmpegdans le PATH (pour webm → H.264 MP4)- Playwright dans un répertoire isolé sous
/tmp(ne pas l'ajouter au dépôt) :
mkdir -p /tmp/<run>/playwright
cd /tmp/<run>/playwright
npm i playwright
npx playwright install ffmpeg
Processus
1. Isolation avec un git worktree
Garder le checkout principal propre.
cd "$(git rev-parse --show-toplevel)"
git fetch origin main
git worktree add -b <branch> .worktrees/<slug> origin/main # ou attacher à la branche de correction
cd .worktrees/<slug>
Travailler uniquement dans ce worktree pour les serveurs et l'enregistrement.
2. Inspecter les fixtures et l'interface d'abord
Avant d'inventer des données :
- Lire la page testée (libellés, contrôles d'expansion, conteneurs de scroll).
- Vérifier les fixtures/factories de test existantes pour la même fonctionnalité.
- Préférer le seed via l'API HTTP publique. Utiliser une insertion SQLite ponctuelle dans un
NAKAMA_CONFIG_DIRisolé uniquement si aucune API ne peut créer la ligne nécessaire (ex. une exécution d'automatisation terminée avec unoutputénorme).
3. Seeder du contenu long déterministe
Pour les preuves de scroll/débordement, la fixture doit être plus haute que le panneau.
- Placer un marqueur supérieur unique près du début :
SCROLL_PROOF_MARKER_TOP - Placer un marqueur inférieur unique à la fin :
SCROLL_PROOF_MARKER_BOTTOM - Utiliser suffisamment de texte pour que
scrollHeight - clientHeightsoit grand (des milliers de pixels)
Exemple de forme pour la sortie d'exécution :
# SCROLL_PROOF_MARKER_TOP — sortie longue d'exécution d'automatisation
## Section 1
...
## Section 80
...
# SCROLL_PROOF_MARKER_BOTTOM — fin du contenu long
Ne jamais seeder dans les données réelles ~/.nakama de l'opérateur. Toujours utiliser un NAKAMA_CONFIG_DIR frais sous /tmp/<run>/.
4. Démarrer des serveurs locaux isolés
Choisir des ports libres. Ne pas prendre la pile par défaut si quelque chose écoute déjà sur 4310 / 3000 / 3003.
RUN=/tmp/<run>
API_PORT=4330
WEB_PORT=3014
mkdir -p "$RUN/nakama-data" "$RUN/logs"
# Garder les processus en vie après la sortie du shell (simple nohup ... & meurt ici)
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 &
Attendre que curl -sf http://127.0.0.1:$API_PORT/health réussisse et que l'origine web réponde. Configuration initiale : POST /v1/auth/setup, puis créer fournisseur / profil / automatisation (ou réutiliser des fixtures) avec Cookie + X-CSRF-Token + X-Org-Id.
5. Enregistrer avec Playwright (H.264 MP4)
Créer l'enregistreur sous /tmp/<run>/ uniquement. Ne jamais le committer.
const browser = await chromium.launch({
channel: "chrome", // si Chrome est installé
headless: false,
args: ["--disable-gpu"],
});
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
recordVideo: { dir: rawDir, size: { width: 1440, height: 900 } },
});
Règles :
- Conduire le chemin UI réel testé (localisateurs role/texte).
- Rendre le mouvement visible — molette de souris ou scroll pas à pas, pas un seul saut invisible.
- Vérifier que le scroll a bougé (delta
scrollTop) et que le marqueur inférieur devient atteignable. - Capturer
page.video()?.path()avantcontext.close(). - Convertir :
ffmpeg -y -i in.webm -c:v libx264 -pix_fmt yuv420p out.mp4 - Écrire
results.json+ captures d'écran avant/après sousartifacts/e2e-<id>/.
WebM seul ne suffit pas pour la lecture GitHub. Livrer H.264 + yuv420p.
6. Valider la vidéo avant de revendiquer quoi que ce soit
ffprobe -v error -show_entries stream=codec_name,width,height \
-show_entries format=duration -of json out.mp4
# Extraire les trames tôt/tard et les examiner
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
Passer seulement si :
- le codec est
h264 - la durée est assez longue pour voir l'interaction
- la trame précoce montre l'état de départ (ex. marqueur supérieur / panneau étendu)
- la trame tardive montre la progression du scroll (marqueur inférieur ou sections avancées)
results.jsonrapporte un deltascrollTopréel (ou métrique de preuve équivalente)
7. Uploader vers GitHub user-attachments
Non documenté mais l'authentification par token fonctionne pour les images/vidéos lorsque vous avez un accès push :
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>
Sauvegarder l'URL. Confirmer qu'un HEAD/GET sur la ressource renvoie un type de contenu vidéo.
8. Mettre à jour la description de la PR
Ajouter une courte section Preuve navigateur avec les étapes montrées et l'URL https://github.com/user-attachments/assets/... nue sur sa propre ligne (GitHub intègre le lecteur). Préférer écrire le corps via un fichier :
gh api repos/<owner>/<repo>/pulls/<n> --method PATCH --input body.json
# ou : gh pr edit <n> --body-file /tmp/pr-body.md
Suivre .agents/skills/adhd-pr-description/SKILL.md pour le reste du corps.
9. Vérifier le corps en direct de la PR
gh api repos/<owner>/<repo>/pulls/<n> --jq .body | rg 'user-attachments/assets/<uuid>|Preuve navigateur'
Ne pas signaler le succès avant que cette vérification passe.
Exemple : Scroll d'exécution étendue d'automatisation
- Worktree sur la branche de correction (ou branche docs-only pour ce skill).
- API isolée
4330+ web3014,NAKAMA_CONFIG_DIRfrais. POST /v1/auth/setup→ fournisseur → créer automatisation Digesteur de sortie longue.- Insérer/terminer une exécution dont le
outputest le long markdown avecSCROLL_PROOF_MARKER_TOP/SCROLL_PROOF_MARKER_BOTTOM. - Playwright : ouvrir
/automations→ sélectionner l'automatisation → Étendre l'exécution → molette de scroll dans le panneau de détails jusqu'à ce que le marqueur inférieur soit visible. - Convertir en H.264 MP4, inspecter les trames, uploader, patcher le corps de la PR, vérifier.
Nettoyage
- Tuer les écouteurs API/web isolés sur les ports que vous avez choisis.
- Laisser
/tmp/<run>/et le profilartifacts/e2e-<id>/comme preuve locale (ne pas committer les vidéos ou scripts d'enregistrement). - Supprimer le worktree lorsque la branche est fusionnée ou abandonnée :
git worktree remove .worktrees/<slug>
Règles d'honnêteté
- Ne jamais prétendre avoir une preuve navigateur sans regarder les trames ou
ffprobe+ captures d'écran. - Ne jamais coller une URL
user-attachmentsque vous n'avez pas uploadée et récupérée depuis le corps en direct de la PR. - Ne jamais traiter un test unitaire vert comme un substitut à la vidéo lorsque la demande était une preuve visuelle.
- Si le scroll n'a pas bougé, les marqueurs sont erronés, ou le MP4 est vide/corrompu — dire que ça a échoué. Ne pas adoucir.
- Ne pas modifier le code de l'application "pour faciliter la vidéo" sauf si l'utilisateur a demandé un correctif produit.
- Ne pas toucher le répertoire de configuration Nakama réel de l'opérateur.