xo-umbrella2/xo-websock/example/introspect/test/run.sh
Roland Conybeare f4965945be
Some checks failed
cmake-docker / cmake-build (clang, clang++) (push) Failing after 42m55s
cmake-docker / cmake-build (gcc, g++) (push) Successful in 49m1s
CI / smoke-test (push) Has been cancelled
xo-websock: introspect .js relies entirely on _members_ [REFACTOR]
2026-10-11 14:48:01 -04:00

155 lines
4.3 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# xo-websock/example/introspect/test/run.sh
#
# Runs the introspect page's browser tests: each drives the real page in
# headless chrome over the Chrome DevTools Protocol, against a fresh
# websock_ex_introspect server. See .xo-backlog/xo-websock/issues/14.
#
# usage: run.sh SERVER [TEST..]
# SERVER path to the built websock_ex_introspect
# TEST test names (e.g. rows anchor); default: all
#
# needs: node (>= 22: global WebSocket and fetch), curl, and chrome --
# $CHROME if set, else google-chrome, chromium, or /opt/google/chrome/chrome
#
# Screenshots go to a temporary directory, printed at the end. Exit status:
# 0 iff every test passed.
set -u
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# source links (rows, receiver) resolve against the repo root
src_tree="$(cd "${here}/../../../.." && pwd)"
if [[ $# -lt 1 ]]; then
echo "usage: $0 SERVER [TEST..]" >&2
exit 2
fi
server="$1"
shift
all_tests=(rows visibility noticker anchor transitions sink receiver nested
sender_expand endpoint_expand sesstable_expand urlrouter_expand
sub_expand router_expand session_expand cdp_menu expand edge_kinds
header refs_resolve members_only)
if [[ $# -gt 0 ]]; then
tests=("$@")
else
tests=("${all_tests[@]}")
fi
if [[ ! -x "${server}" ]]; then
echo "$0: server not executable: ${server}" >&2
exit 2
fi
for tool in node curl; do
if ! command -v "${tool}" >/dev/null; then
echo "$0: ${tool} not found" >&2
exit 2
fi
done
chrome="${CHROME:-}"
if [[ -z "${chrome}" ]]; then
for c in google-chrome chromium /opt/google/chrome/chrome; do
if command -v "${c}" >/dev/null; then
chrome="${c}"
break
fi
done
fi
if [[ -z "${chrome}" ]]; then
echo "$0: no chrome found: set CHROME" >&2
exit 2
fi
# a port the kernel says is free now
free_port() {
node -e 'const s = require("net").createServer().listen(0, () => { console.log(s.address().port); s.close(); })'
}
# true once URL $1 answers, within ~10s
wait_for() {
for _ in $(seq 100); do
curl -s -o /dev/null "$1" && return 0
sleep 0.1
done
return 1
}
work="$(mktemp -d -t introspect-test.XXXXXX)"
chrome_pid=""
server_pid=""
cleanup() {
[[ -n "${server_pid}" ]] && kill "${server_pid}" 2>/dev/null
[[ -n "${chrome_pid}" ]] && kill "${chrome_pid}" 2>/dev/null
wait 2>/dev/null
}
trap cleanup EXIT
cdp_port="$(free_port)"
"${chrome}" --headless=new --remote-debugging-port="${cdp_port}" \
--user-data-dir="${work}/chrome-profile" \
--noerrdialogs --no-first-run --ozone-platform=headless \
>"${work}/chrome.log" 2>&1 &
chrome_pid=$!
if ! wait_for "http://localhost:${cdp_port}/json/version"; then
echo "$0: chrome did not start: see ${work}/chrome.log" >&2
exit 2
fi
n_pass=0
failed=()
for t in "${tests[@]}"; do
script="${here}/${t}.mjs"
if [[ ! -f "${script}" ]]; then
echo "${t}: no such test (${script})"
failed+=("${t}")
continue
fi
port="$(free_port)"
extra=()
case "${t}" in
rows|receiver) extra=(--src-tree="${src_tree}") ;;
esac
"${server}" "${port}" "${extra[@]}" >"${work}/${t}.server.log" 2>&1 &
server_pid=$!
if ! wait_for "http://localhost:${port}/"; then
echo "${t}: FAIL (server did not start: ${work}/${t}.server.log)"
failed+=("${t}")
kill "${server_pid}" 2>/dev/null; wait "${server_pid}" 2>/dev/null; server_pid=""
continue
fi
# each test's own arguments
case "${t}" in
cdp_menu) args=("${cdp_port}" "http://localhost:${port}/") ;;
expand) args=("${cdp_port}" "${port}" "${work}/${t}-1.png" "${work}/${t}-2.png") ;;
refs_resolve) args=("${cdp_port}" "${port}") ;;
*) args=("${cdp_port}" "${port}" "${work}/${t}.png") ;;
esac
if timeout 180 node "${script}" "${args[@]}" >"${work}/${t}.log" 2>&1; then
echo "${t}: ok"
n_pass=$((n_pass + 1))
else
echo "${t}: FAIL"
grep -E '^FAIL|Error' "${work}/${t}.log" | head -5 | sed 's/^/ /'
failed+=("${t}")
fi
kill "${server_pid}" 2>/dev/null; wait "${server_pid}" 2>/dev/null; server_pid=""
done
echo "${n_pass} passed, ${#failed[@]} failed; logs and screenshots in ${work}"
[[ ${#failed[@]} -eq 0 ]]