#!/usr/bin/env bash # Joue une partie complète par l'interface dans Chromium et Firefox sans # écran (tests/browser/play.mjs), sur le site servi par l'image de production # construite en local, comme tests/test_site.sh. Les captures d'écran vont # dans build/browser-shots/. Puis l'accueil, le tutoriel, l'aide, # l'installation et la mise à jour (tests/browser/accueil.mjs), avec leurs # captures dans build/browser-shots/accueil-tutoriel/. Enfin l'écran « Nouvelle # partie » et un match en 3 points joué jusqu'au bout (tests/browser/match.mjs), # captures dans build/browser-shots/match/. # # Le conseil du maître (tests/browser/maitre.mjs), captures dans # build/browser-shots/maitre/. Le bilan de fin de partie et l'écran # d'analyse (tests/browser/bilan.mjs), captures dans # build/browser-shots/bilan/. « Nouvelle partie » après une partie finie et # son bilan, par chaque entrée (tests/browser/nouvelle-partie.mjs), captures # dans build/browser-shots/nouvelle-partie/. # # BROWSERS=chromium et SCRIPTS=accueil (ou play, match, maitre, bilan, # nouvelle-partie) # restreignent le test. # # Outils : l'image de Playwright (navigateurs) et le paquet playwright, # installé une fois par npm dans build/browser-tools/ (réseau nécessaire la # première fois). Lent (plusieurs minutes) : lancé par make test-browser, # pas par make test. set -euo pipefail cd "$(dirname "$0")/.." image="${PLAYWRIGHT_IMAGE:?lancer via make test-browser}" browsers="${BROWSERS:-chromium firefox}" # Les scripts à lancer (tests/browser/.mjs), tous par défaut. scripts="${SCRIPTS:-play accueil match maitre bilan nouvelle-partie}" unset MAKEFLAGS MFLAGS MAKELEVEL make -s package >/dev/null # Image de production lancée, étiquette propre à ce dépôt : site_image, # container, port. # shellcheck source=tests/site-image.sh . tests/site-image.sh # Le paquet playwright, à la version des navigateurs de l'image. tools=build/browser-tools version="${image##*:v}" version="${version%%-*}" if [ ! -f "$tools/node_modules/playwright/package.json" ]; then mkdir -p "$tools" docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD/$tools:/tools" -w /tools \ "$image" npm install --no-audit --no-fund --save-exact "playwright@$version" >/dev/null fi # Pour la mise à jour de l'application (tests/browser/accueil.mjs) : une # copie du site, servie par la même image mais depuis un dossier que le test # modifie, pour publier une deuxième version sur la même adresse. updates=build/browser-site rm -rf "$updates" cp -r build/site "$updates" update_container="$(docker run -d --rm -p 127.0.0.1::80 -v "$PWD/$updates:/srv:ro" "$site_image")" # shellcheck disable=SC2317 # appelée par trap, à la sortie update_cleanup() { docker rm -f "$update_container" >/dev/null 2>&1 || true site_cleanup } trap update_cleanup EXIT update_port="$(docker port "$update_container" 80/tcp | head -n1 | sed 's/.*://')" rm -rf build/browser-shots mkdir -p build/browser-shots cp tests/browser/play.mjs tests/browser/accueil.mjs tests/browser/match.mjs tests/browser/recette.mjs \ tests/browser/maitre.mjs tests/browser/bilan.mjs tests/browser/nouvelle-partie.mjs "$tools/" status=0 for browser in $browsers; do # Réseau de l'hôte : le site est sur 127.0.0.1. Le service worker # demande un contexte sûr, ce qu'est localhost. if [[ " $scripts " == *" play "* ]]; then docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -e TRACE -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -w /tools "$image" \ node play.mjs "http://localhost:$port/" "$browser" /shots || status=1 fi if [[ " $scripts " == *" accueil "* ]]; then # Accueil, tutoriel, aide, installation et mise à jour ; captures de # la recette dans build/browser-shots/accueil-tutoriel/. docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -v "$PWD/$updates:/site" \ -w /tools "$image" \ node accueil.mjs "http://localhost:$port/" "$browser" /shots \ "http://localhost:$update_port/" /site || status=1 fi if [[ " $scripts " == *" match "* ]]; then # Écran « Nouvelle partie » et match en 3 points ; captures de la # recette dans build/browser-shots/match/. docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -w /tools "$image" \ node match.mjs "http://localhost:$port/" "$browser" /shots || status=1 fi if [[ " $scripts " == *" maitre "* ]]; then # Conseil du maître : ligne, feuille d'explication, videau, réglage ; # captures de la recette dans build/browser-shots/maitre/. docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -w /tools "$image" \ node maitre.mjs "http://localhost:$port/" "$browser" /shots || status=1 fi if [[ " $scripts " == *" bilan "* ]]; then # Bilan de fin de partie et écran d'analyse ; captures de la recette # dans build/browser-shots/bilan/. docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -w /tools "$image" \ node bilan.mjs "http://localhost:$port/" "$browser" /shots || status=1 fi if [[ " $scripts " == *" nouvelle-partie "* ]]; then # « Nouvelle partie » après une partie finie et son bilan : la # nouvelle partie tout de suite ; captures dans # build/browser-shots/nouvelle-partie/. docker run --rm --init --ipc=host --network host --user "$(id -u):$(id -g)" -e HOME=/tmp \ -v "$PWD/$tools:/tools" -v "$PWD/build/browser-shots:/shots" -w /tools "$image" \ node nouvelle-partie.mjs "http://localhost:$port/" "$browser" /shots || status=1 fi done exit "$status"