#!/bin/bash # Run frontend test with optional port exposure # Usage: ./run-test-frontend.sh [--expose-port {on|off}] [--test-real-plugin] # Default: # --expose-port off: Auto cleanup after test # --test-real-plugin: Run only real-plugin.spec.ts (requires vps.t1 plugin) set -e EXPOSE_PORT="off" TEST_REAL_PLUGIN="off" COMPOSE_FILE="docker-compose-frontend.yml" TEST_PATTERN="" # Load environment variables from .env.TEST if exists if [ -f ".env.TEST" ]; then echo "๐Ÿ“‹ Loading .env.TEST..." set -a source .env.TEST set +a fi # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --expose-port) EXPOSE_PORT="$2" shift 2 ;; --expose-port=*) EXPOSE_PORT="${1#*=}" shift ;; --test-real-plugin) TEST_REAL_PLUGIN="on" shift ;; *) echo "Unknown option: $1" echo "Usage: $0 [--expose-port {on|off}] [--test-real-plugin]" exit 1 ;; esac done # Validate expose-port value if [[ "$EXPOSE_PORT" != "on" && "$EXPOSE_PORT" != "off" ]]; then echo "Error: --expose-port must be 'on' or 'off'" exit 1 fi # Set test pattern for real plugin test if [[ "$TEST_REAL_PLUGIN" == "on" ]]; then TEST_PATTERN="real-plugin.spec.ts" echo "๐Ÿ”Œ Real Plugin Test Mode: ON" echo " Will run: tests/real-plugin.spec.ts" echo " Requires vps.t1 to have OpenClaw plugin installed" fi # Select compose file based on expose-port if [[ "$EXPOSE_PORT" == "on" ]]; then COMPOSE_FILE="docker-compose-frontend-expose.yml" echo "๐Ÿ”Œ Port exposure: ON (services will keep running)" else echo "๐Ÿ”Œ Port exposure: OFF (auto cleanup after test)" fi echo "๐Ÿ“ฆ Using compose file: $COMPOSE_FILE" run_quiet() { local label="$1" shift local log_file log_file=$(mktemp) if "$@" >"$log_file" 2>&1; then rm -f "$log_file" return 0 fi echo "โŒ ${label} failed" echo "--- ${label} log ---" tail -n 200 "$log_file" rm -f "$log_file" return 1 } # Clean any previous containers first echo "๐Ÿงน Cleaning up previous containers..." docker compose -f "$COMPOSE_FILE" down -v >/dev/null 2>&1 || true # Build frontend with correct API base URL (force no cache, remove image first) echo "๐Ÿ”จ Building frontend..." docker rmi harborforge-test-frontend:dev >/dev/null 2>&1 || true run_quiet "frontend build" docker compose -f "$COMPOSE_FILE" build --no-cache --build-arg VITE_API_BASE=http://backend:8000 frontend # Build backend (force no cache, remove image first) echo "๐Ÿ”จ Building backend..." docker rmi harborforge-test-backend:dev >/dev/null 2>&1 || true run_quiet "backend build" docker compose -f "$COMPOSE_FILE" build --no-cache backend # Build test runner (force no cache, remove image first) echo "๐Ÿ”จ Building test runner..." docker rmi harborforge-test-runner:dev >/dev/null 2>&1 || true run_quiet "test runner build" docker compose -f "$COMPOSE_FILE" build --no-cache test # Start services echo "๐Ÿ“ฆ Starting services..." run_quiet "service startup" docker compose -f "$COMPOSE_FILE" up -d # Wait for frontend to be ready echo "โณ Waiting for services..." MAX_RETRIES=30 RETRY_COUNT=0 until docker run --rm --network harborforgetest_test-network curlimages/curl -s -o /dev/null -w "%{http_code}" http://frontend:3000/ 2>/dev/null | grep -q "200" || [ $RETRY_COUNT -eq $MAX_RETRIES ]; do echo " Waiting for frontend... ($RETRY_COUNT/$MAX_RETRIES)" sleep 2 RETRY_COUNT=$((RETRY_COUNT+1)) done if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then echo "โŒ Frontend failed to start" docker compose -f "$COMPOSE_FILE" logs docker compose -f "$COMPOSE_FILE" down -v exit 1 fi echo "โœ… Services ready!" # Run test echo "๐Ÿงช Running test..." if [[ -n "$TEST_PATTERN" ]]; then # Run specific test for real plugin docker compose -f "$COMPOSE_FILE" run --rm -e WORKERS=1 test npx playwright test tests/real-plugin.spec.ts --reporter=list else # Run all tests docker compose -f "$COMPOSE_FILE" run --rm -e WORKERS=1 test fi TEST_EXIT_CODE=$? # Cleanup decision based on expose-port if [[ "$EXPOSE_PORT" == "on" ]]; then echo "" echo "๐Ÿ”Œ Port exposure is ON - keeping services running!" echo " Use './run-test-frontend.sh --expose-port on' to cleanup" echo " Or manually: docker compose -f $COMPOSE_FILE down -v" echo "" if [ $TEST_EXIT_CODE -eq 0 ]; then echo "โœ… Test passed!" else echo "โŒ Test failed with exit code: $TEST_EXIT_CODE" fi else echo "" echo "๐Ÿงน Cleaning up containers and volumes..." docker compose -f "$COMPOSE_FILE" down -v if [ $TEST_EXIT_CODE -eq 0 ]; then echo "โœ… Test passed!" else echo "โŒ Test failed with exit code: $TEST_EXIT_CODE" fi fi exit $TEST_EXIT_CODE