#!/usr/bin/env bash # Run Porchlight end-to-end browser tests. # # Usage: # ./run.sh # run all test_*.js files # ./run.sh test_login.js # run a specific test # # Prerequisites: # npm install && npm run setup (once, to install playwright + chromium) # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" PORT="${E2E_PORT:-8099}" # Use "localhost" (not 127.0.0.1) so that the WebAuthn RP ID is a valid # domain — the spec forbids IP addresses as RP IDs. export TARGET_URL="http://localhost:${PORT}" # --- Temp directory for e2e state --- E2E_TMPDIR="$(mktemp -d)" export OIDC_OP_SQLITE_PATH="${E2E_TMPDIR}/e2e_test.db" export OIDC_OP_SIGNING_KEY_PATH="${E2E_TMPDIR}/keys" # --- Start the app --- echo "Starting Porchlight on port ${PORT}..." echo " DB: ${OIDC_OP_SQLITE_PATH}" OIDC_OP_ISSUER="${TARGET_URL}" \ OIDC_OP_DEBUG=true \ uv run --directory "$PROJECT_ROOT" \ uvicorn porchlight.app:create_app \ --factory --host 127.0.0.1 --port "$PORT" \ --log-level warning & SERVER_PID=$! cleanup() { echo "Stopping server (pid ${SERVER_PID})..." kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true rm -rf "$E2E_TMPDIR" } trap cleanup EXIT # --- Wait for healthy --- echo "Waiting for server..." for i in $(seq 1 30); do if curl -sf "${TARGET_URL}/health" >/dev/null 2>&1; then echo "Server ready." break fi if [ "$i" -eq 30 ]; then echo "Server failed to start within 30 seconds." >&2 exit 1 fi sleep 1 done # --- Seed test data --- echo "Seeding test data..." E2E_FIXTURES=$(uv run --directory "$PROJECT_ROOT" python tests/e2e/setup_db.py) export E2E_FIXTURES echo "Test fixtures: ${E2E_FIXTURES}" # --- Run tests --- echo "" echo "=== Running Playwright tests ===" cd "$SCRIPT_DIR" if [ $# -gt 0 ]; then npx playwright test "$@" else npx playwright test fi EXIT_CODE=$? exit "$EXIT_CODE"