#!/bin/bash set -e cd "$(dirname "$0")/.." # E2E tests use separate databases and ports per worker for parallel execution E2E_PORT_START=${E2E_PORT_START:-8001} NUM_WORKERS=${NUM_WORKERS:-8} # Default to 8 workers, can be overridden # Cleanup function to kill background processes cleanup() { for pid in "${BACKEND_PIDS[@]}"; do kill $pid 2>/dev/null || true done } # Ensure cleanup runs on exit (normal, error, or interrupt) trap cleanup EXIT # Load environment variables if .env exists if [ -f .env ]; then set -a source .env set +a fi # Kill any existing e2e backends echo "Cleaning up existing e2e backends..." for i in $(seq 0 $((NUM_WORKERS - 1))); do PORT=$((E2E_PORT_START + i)) pkill -f "uvicorn main:app --port $PORT" 2>/dev/null || true done sleep 1 # Seed all worker databases echo "Seeding worker databases..." cd backend BACKEND_PIDS=() for i in $(seq 0 $((NUM_WORKERS - 1))); do DATABASE_URL="postgresql+asyncpg://postgres:postgres@localhost:5432/arbret_e2e_worker$i" echo " Seeding database arbret_e2e_worker$i..." DATABASE_URL="$DATABASE_URL" E2E_MODE=1 uv run python seed.py & done wait cd .. # Start backends for each worker echo "Starting $NUM_WORKERS backend instances..." cd backend for i in $(seq 0 $((NUM_WORKERS - 1))); do PORT=$((E2E_PORT_START + i)) DATABASE_URL="postgresql+asyncpg://postgres:postgres@localhost:5432/arbret_e2e_worker$i" echo " Starting backend on port $PORT for worker $i..." DATABASE_URL="$DATABASE_URL" E2E_MODE=1 uv run uvicorn main:app --port $PORT --log-level warning & BACKEND_PIDS+=($!) done cd .. # Wait for all backends to be ready echo "Waiting for backends to be ready..." for i in $(seq 0 $((NUM_WORKERS - 1))); do PORT=$((E2E_PORT_START + i)) MAX_ATTEMPTS=30 ATTEMPT=0 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do if curl -s "http://localhost:$PORT/docs" > /dev/null 2>&1; then echo " Backend on port $PORT is ready" break fi ATTEMPT=$((ATTEMPT + 1)) sleep 0.5 done if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then echo " ERROR: Backend on port $PORT failed to start" exit 1 fi done # Generate API types from first e2e backend (they should all have same schema) echo "Generating API types from e2e backend..." cd frontend npx openapi-typescript "http://localhost:$E2E_PORT_START/openapi.json" -o app/generated/api.ts cd .. # Run tests with e2e-specific backend URL # Tests will determine which backend to use based on worker index cd frontend export NEXT_PUBLIC_API_URL="http://localhost:$E2E_PORT_START" # Default, tests override per worker export E2E_PORT_START=$E2E_PORT_START export NUM_WORKERS=$NUM_WORKERS if [ -n "$1" ]; then NODE_NO_WARNINGS=1 npx playwright test --workers=$NUM_WORKERS "$1" else NODE_NO_WARNINGS=1 npx playwright test --workers=$NUM_WORKERS fi EXIT_CODE=$? # Cleanup is handled by trap EXIT exit $EXIT_CODE