94 lines
2.9 KiB
Bash
94 lines
2.9 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
#
|
||
|
|
# End-to-end check of the shared styling contract and the two shipped controls.
|
||
|
|
#
|
||
|
|
# The unit tests cover the store and the components in isolation. This covers the
|
||
|
|
# things only a browser can answer:
|
||
|
|
#
|
||
|
|
# - Does the rendered contract CSS actually resolve to the right computed values?
|
||
|
|
# - Does the legacy alias layer reach a host page that never mentions --bn-*?
|
||
|
|
# - Does Shadow DOM isolate the controls in both directions against a hostile rule?
|
||
|
|
# - Do the controls, driven by a real click, move the attributes on <html>?
|
||
|
|
#
|
||
|
|
# The page verifies itself and writes a verdict into the DOM, so this needs only a
|
||
|
|
# headless Chromium and no driver library.
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
|
|
WORK="$(mktemp -d)"
|
||
|
|
PORT="${PORT:-8399}"
|
||
|
|
CHROME="${CHROME:-$(command -v chromium || command -v chromium-browser || command -v google-chrome || true)}"
|
||
|
|
|
||
|
|
cleanup() {
|
||
|
|
if [[ -n "${SERVER_PID:-}" ]]; then kill "$SERVER_PID" 2>/dev/null || true; fi
|
||
|
|
rm -rf "$WORK"
|
||
|
|
}
|
||
|
|
trap cleanup EXIT
|
||
|
|
|
||
|
|
if [[ -z "$CHROME" ]]; then
|
||
|
|
echo "no chromium found; set CHROME to a headless browser binary" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> building the server and the SDK"
|
||
|
|
(cd "$ROOT" && go build -o "$WORK/go-bananas" ./cmd/go-bananas)
|
||
|
|
(cd "$ROOT/sdk" && npm run build >/dev/null)
|
||
|
|
|
||
|
|
# The check page is served from the SDK directory, so it is same-origin with the
|
||
|
|
# service. A cross-origin run would additionally need its origin in
|
||
|
|
# CORS_ALLOWED_ORIGINS, which is a deployment concern and not a property of the
|
||
|
|
# contract.
|
||
|
|
cp "$ROOT"/sdk/dist/*.js "$WORK/"
|
||
|
|
cp "$ROOT/hack/integration-check.html" "$ROOT/hack/contract-check.js" "$WORK/"
|
||
|
|
|
||
|
|
echo "==> starting the service on :$PORT"
|
||
|
|
DATABASE_PATH="$WORK/check.db" \
|
||
|
|
BANANAS_ENVIRONMENT=development \
|
||
|
|
BANANAS_AUTH_MODE=dev \
|
||
|
|
BANANAS_PUBLIC_BASE_URL="http://localhost:$PORT" \
|
||
|
|
BANANAS_HTTP_ADDR=":$PORT" \
|
||
|
|
BANANAS_SDK_DIR="$WORK" \
|
||
|
|
"$WORK/go-bananas" >"$WORK/server.log" 2>&1 &
|
||
|
|
SERVER_PID=$!
|
||
|
|
|
||
|
|
for _ in $(seq 1 40); do
|
||
|
|
if curl -fsS -m 2 "http://localhost:$PORT/healthz" >/dev/null 2>&1; then break; fi
|
||
|
|
sleep 0.25
|
||
|
|
done
|
||
|
|
if ! curl -fsS -m 2 "http://localhost:$PORT/healthz" >/dev/null 2>&1; then
|
||
|
|
echo "the service did not become healthy:" >&2
|
||
|
|
cat "$WORK/server.log" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "==> driving the page"
|
||
|
|
"$CHROME" \
|
||
|
|
--headless \
|
||
|
|
--no-sandbox \
|
||
|
|
--disable-gpu \
|
||
|
|
--virtual-time-budget=10000 \
|
||
|
|
--dump-dom "http://localhost:$PORT/rt/v1/integration-check.html" \
|
||
|
|
>"$WORK/dom.html" 2>/dev/null
|
||
|
|
|
||
|
|
verdict="$(python3 - "$WORK/dom.html" <<'PY'
|
||
|
|
import re, sys
|
||
|
|
dom = open(sys.argv[1]).read()
|
||
|
|
m = re.search(r'id="verdict"[^>]*>(.*?)</div>', dom, re.S)
|
||
|
|
print(m.group(1).strip() if m else "")
|
||
|
|
PY
|
||
|
|
)"
|
||
|
|
|
||
|
|
if [[ -z "$verdict" ]]; then
|
||
|
|
echo "the page produced no verdict, so the check did not run." >&2
|
||
|
|
echo "the script most likely threw; the server log follows." >&2
|
||
|
|
cat "$WORK/server.log" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo
|
||
|
|
echo "$verdict"
|
||
|
|
|
||
|
|
if [[ "$verdict" != ALL\ PASS* ]]; then
|
||
|
|
exit 1
|
||
|
|
fi
|