mirror of
https://github.com/kevinveenbirkenbach/homepage.veen.world.git
synced 2026-08-24 05:04:33 +00:00
test-e2e drove Cypress through act, which fails to start where it cannot resolve a host address for its artifact server. It now starts Flask and Cypress in one shell via scripts/run-e2e.sh, so both share a network namespace; the act path stays available as test-e2e-act. The script guards the cases that made the old target lie: it aborts when something already serves the port instead of testing that server, checks that its own Flask is alive before trusting a response, pins Cypress to the same origin Flask binds, and drops ELECTRON_RUN_AS_NODE, which VS Code exports and which makes Cypress' bundled Electron reject its own flags. 30 YAML and 18 JavaScript files had no linter. yamllint runs correctness rules only, because the repository predates it and its cosmetic findings would be noise; key-duplicates is the one that earns its keep, since PyYAML keeps the last of two identical keys without complaining. eslint runs the recommended set and already found a dead getBoundingClientRect() call in navigation.js. Both get a CI job so make lint and the workflows stop diverging. flask>=3.1 because app.config["TRUSTED_HOSTS"] arrived in 3.1 and an older Flask accepts the key and ignores it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
74 lines
2.7 KiB
Bash
Executable File
74 lines
2.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# Run the Cypress suite against a Flask app started by this script.
|
|
#
|
|
# Server and browser share one shell, so this works where act cannot reach the
|
|
# host network. ELECTRON_RUN_AS_NODE is dropped before invoking Cypress because
|
|
# VS Code exports it to child processes, which makes Cypress' bundled Electron
|
|
# behave as Node and reject its own launch flags.
|
|
#
|
|
# Env:
|
|
# PORT required, the port Flask binds and Cypress targets
|
|
# PYTHON interpreter to run app.py with (default: python3)
|
|
# E2E_LOG where Flask's output goes (default: /tmp/portfolio-e2e-flask.log)
|
|
set -u
|
|
|
|
PORT="${PORT:?PORT must be set (see env.example)}"
|
|
PYTHON="${PYTHON:-python3}"
|
|
E2E_LOG="${E2E_LOG:-/tmp/portfolio-e2e-flask.log}"
|
|
FLASK_HOST=127.0.0.1
|
|
export PORT FLASK_HOST
|
|
|
|
APP_DIR="$(CDPATH='' cd -- "$(dirname -- "$0")/../app" && pwd)"
|
|
BASE_URL="http://127.0.0.1:$PORT/"
|
|
|
|
# cypress.config.js defaults to localhost, which resolves to ::1 first on a
|
|
# dual-stack host — a different listener from the 127.0.0.1 one Flask binds and
|
|
# this script probes. Pin all three to the same origin.
|
|
export CYPRESS_baseUrl="$BASE_URL"
|
|
|
|
# A foreign listener would be tested instead of the working tree. The predicate
|
|
# is "something answers", deliberately without curl's -f: a foreign server that
|
|
# is still returning 5xx right now would otherwise pass the guard and then be
|
|
# picked up by the readiness probe once it recovers. --noproxy is what keeps
|
|
# that same looser predicate from matching an HTTP proxy instead of the port.
|
|
if curl -s --noproxy '*' --connect-timeout 2 --max-time 10 -o /dev/null "$BASE_URL"; then
|
|
echo "ERROR: something already serves port $PORT — Cypress would test that"
|
|
echo " instead of your working tree. Stop it first ('make down' for"
|
|
echo " the container, otherwise a stray 'python app.py')."
|
|
exit 1
|
|
fi
|
|
|
|
cd "$APP_DIR" || exit 1
|
|
$PYTHON app.py > "$E2E_LOG" 2>&1 &
|
|
flask_pid=$!
|
|
trap 'kill "$flask_pid" 2>/dev/null || true' EXIT INT TERM
|
|
|
|
echo "Waiting for $BASE_URL — follow with: tail -f $E2E_LOG"
|
|
attempt=0
|
|
while [ "$attempt" -lt 120 ]; do
|
|
# Liveness first: a server answering while ours is dead means we are about
|
|
# to hand Cypress somebody else's app.
|
|
if ! kill -0 "$flask_pid" 2>/dev/null; then
|
|
echo "ERROR: Flask exited during startup"
|
|
cat "$E2E_LOG"
|
|
exit 1
|
|
fi
|
|
if curl -sf --noproxy '*' --connect-timeout 2 --max-time 10 -o /dev/null "$BASE_URL"; then
|
|
break
|
|
fi
|
|
attempt=$((attempt + 1))
|
|
sleep 1
|
|
done
|
|
|
|
if ! curl -sf --noproxy '*' --connect-timeout 2 --max-time 10 -o /dev/null "$BASE_URL"; then
|
|
echo "ERROR: app never became ready"
|
|
cat "$E2E_LOG"
|
|
exit 1
|
|
fi
|
|
|
|
env -u ELECTRON_RUN_AS_NODE npx cypress run
|
|
status=$?
|
|
|
|
kill "$flask_pid" 2>/dev/null || true
|
|
exit "$status"
|