#!/usr/bin/env bash # ============================================================================ # tc-header.sh — fonctions partagées pour tous les scripts TC # Source: source "$(dirname "$0")/tc-header.sh" # ============================================================================ # Constants URL="${URL:-https://localhost:31000}" PASS="${PASS:-}" WORLD="${WORLD:-Reve de Dragon}" NAVIGATE="${1:-}" PASSED=0; FAILED=0 die() { echo " ✖ $*"; exit 1; } pass() { echo " ✔ $1"; PASSED=$((PASSED+1)); } fail() { echo " ✘ $1"; FAILED=$((FAILED+1)); } # Extract JSON value from evaluate_script output (```json\nVALUE\n```) jse_get() { chrome-devtools evaluate_script "() => { $1 }" 2>/dev/null \ | sed -n '/^```json$/{n;p;}' } jse_get_async() { chrome-devtools evaluate_script "async () => { $1 }" 2>/dev/null \ | sed -n '/^```json$/{n;p;}' } # Async polling: single evaluate_script call, no bash loop jse_wait_ready() { local timeout_s="${1:-60}" poll_ms="${2:-1000}" chrome-devtools evaluate_script "async () => { const limit = $timeout_s * 1000 / $poll_ms; for (let i = 0; i < limit; i++) { if (typeof game !== 'undefined' && game.ready) return 'ready'; await new Promise(r => setTimeout(r, $poll_ms)); } return 'timeout'; }" 2>/dev/null | sed -n '/^```json$/{n;p;}' | tr -d '"\n' } # Navigate + login if needed (--navigate flag) # Env: PASS (admin password), PASS_USER (user password, empty by default) PASS_USER="${PASS_USER:-}" tc_login() { [ -z "$PASS" ] && die "Admin password required: PASS=..." echo "→ Navigating to $URL ..." chrome-devtools new_page "$URL" --background false --timeout 15000 --isolatedContext "rdd-tests" >/dev/null 2>&1 sleep 3 local PW PW=$(jse_get "window.location.pathname" | tr -d '"\n') case "$PW" in */join) chrome-devtools evaluate_script "() => { const sel = document.querySelector('select[name=userid]'); if(sel) { const opts = Array.from(sel.options); const gm = opts.find(o => o.text === 'Gamemaster'); const pick = gm || opts.find(o => o.value && !o.disabled) || opts.find(o => o.value); if(pick) sel.value = pick.value; } const pw = document.querySelector('input[name=password]'); if(pw) pw.value = '$PASS_USER'; const btn = document.querySelector('button[name=join]'); if(btn) btn.click(); }" >/dev/null 2>&1 || true ;; */setup) chrome-devtools evaluate_script "() => { const links = document.querySelectorAll('[data-action=worldLaunch]'); for(const l of links){ const li = l.closest('li.package.world'); if(li && li.querySelector('.package-title')?.textContent === '$WORLD'){ l.click(); break; } } }" >/dev/null 2>&1 || true ;; */auth) chrome-devtools evaluate_script "() => { const inp = document.querySelector('input[type=password]'); if(inp) inp.value = '$PASS'; const btn = document.querySelector('form button, button[type=submit]'); if(btn) btn.click(); }" >/dev/null 2>&1 || true ;; esac echo "→ Waiting for game..." jse_wait_ready 60 2 } # Ensure game is ready, login if --navigate tc_ensure_ready() { local R R=$(jse_wait_ready 15 2) if [ "$R" != "ready" ] && [ "$NAVIGATE" = "--navigate" ]; then R=$(tc_login) fi [ "$R" != "ready" ] && die "Game not ready" echo " ✓ Game ready" echo "" } # Assert helpers assert_eq() { local t="$1" a="$2" e="$3" if [ "$a" = "$e" ]; then pass "$t"; else fail "$t (got '$a' expected '$e')"; fi } assert_gt() { local t="$1" a="$2" e="$3" if [ "$a" -gt "$e" ] 2>/dev/null; then pass "$t"; else fail "$t ($a <= $e)"; fi } assert_contains() { local t="$1" a="$2" e="$3" if echo "$a" | grep -q "$e"; then pass "$t"; else fail "$t (no '$e' in '$a')"; fi } # Extract field from JSON result eval_ok() { local json="$1" k="$2" echo "$json" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('$k',''))" 2>/dev/null } # Console error count tc_console_errors() { chrome-devtools list_console_messages --types error 2>/dev/null | grep -c '^msgid=' || true } # Print summary tc_summary() { local TOTAL=$((PASSED + FAILED)) echo "" echo "╔══════════════════════════════════════════════════════════════╗" printf "║ %2d / %2d passed, %2d failed ║\n" "$PASSED" "$TOTAL" "$FAILED" echo "╚══════════════════════════════════════════════════════════════╝" echo "" [ "$FAILED" -gt 0 ] && exit 1 || exit 0 }