diff --git a/HarborForge.Frontend.Test b/HarborForge.Frontend.Test index 7e4933e..db9fadd 160000 --- a/HarborForge.Frontend.Test +++ b/HarborForge.Frontend.Test @@ -1 +1 @@ -Subproject commit 7e4933ee2550c379138a5ffe8c7cdc9fdc81c0f4 +Subproject commit db9fadd13d1b1fee03d2c5a46967235d439d0ef0 diff --git a/cleanup-frontend.sh b/cleanup-frontend.sh new file mode 100755 index 0000000..1e5eac2 --- /dev/null +++ b/cleanup-frontend.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Cleanup script for HarborForge Frontend Test +# Usage: ./cleanup-frontend.sh [--expose-port {on|off}] +# Default: off + +set -e + +EXPOSE_PORT="off" +COMPOSE_FILE="docker-compose-frontend.yml" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --expose-port) + EXPOSE_PORT="$2" + shift 2 + ;; + --expose-port=*) + EXPOSE_PORT="${1#*=}" + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 [--expose-port {on|off}]" + 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 + +# Select compose file based on expose-port +if [[ "$EXPOSE_PORT" == "on" ]]; then + COMPOSE_FILE="docker-compose-frontend-expose.yml" + echo "๐Ÿ”Œ Port exposure: ON" +else + echo "๐Ÿ”Œ Port exposure: OFF" +fi + +echo "๐Ÿ“ฆ Using compose file: $COMPOSE_FILE" +echo "๐Ÿงน Cleaning up HarborForge Test containers..." + +# Stop and remove containers, networks (keep images) +docker compose -f "$COMPOSE_FILE" down + +# Also remove the wizard config volume +docker volume rm harborforgetest_wizard_config 2>/dev/null || true + +echo "โœ… Cleanup complete!" diff --git a/docker-compose-frontend-expose.yml b/docker-compose-frontend-expose.yml new file mode 100644 index 0000000..7e624ae --- /dev/null +++ b/docker-compose-frontend-expose.yml @@ -0,0 +1,99 @@ +services: + mysql: + image: mysql:8.0 + container_name: harborforge-test-mysql + restart: "no" + tmpfs: + - /var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-harborforge_root} + MYSQL_DATABASE: ${MYSQL_DATABASE:-harborforge} + MYSQL_USER: ${MYSQL_USER:-harborforge} + MYSQL_PASSWORD: ${MYSQL_PASSWORD:-harborforge_pass} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - test-network + + wizard: + build: + context: ../AbstractWizard + dockerfile: Dockerfile + image: harborforge-test-wizard:dev + container_name: harborforge-test-wizard + user: 0:0 + restart: "no" + volumes: + - wizard_config:/config + environment: + CONFIG_DIR: /config + LISTEN_ADDR: "0.0.0.0:8080" + MAX_BACKUPS: "5" + CORS_ORIGINS: http://localhost:18080 + ports: + - "18080:8080" + networks: + - test-network + + backend: + build: + context: ../HarborForge.Backend + dockerfile: Dockerfile + image: harborforge-test-backend:dev + container_name: harborforge-test-backend + restart: "no" + volumes: + - wizard_config:/config:ro + environment: + CONFIG_DIR: /config + CONFIG_FILE: harborforge.json + SECRET_KEY: ${SECRET_KEY:-change_me_in_production} + LOG_LEVEL: ${LOG_LEVEL:-INFO} + DATABASE_URL: mysql+pymysql://harborforge:harborforge_pass@mysql:3306/harborforge + ports: + - "8000:8000" + networks: + - test-network + + frontend: + build: + context: ../HarborForge.Frontend + dockerfile: Dockerfile + args: + VITE_WIZARD_PORT: 8080 + VITE_WIZARD_HOST: wizard + image: harborforge-test-frontend:dev + container_name: harborforge-test-frontend + restart: "no" + environment: + VITE_API_BASE_URL: http://localhost:8000 + ports: + - "3000:3000" + networks: + - test-network + + test: + build: + context: ./HarborForge.Frontend.Test + dockerfile: Dockerfile + image: harborforge-test-runner:dev + container_name: harborforge-test-runner + restart: "no" + environment: + BASE_URL: http://localhost:3000 + WEB_SERVER_URL: http://localhost:3000 + WIZARD_URL: http://localhost:18080/wizard + WIZARD_API_URL: http://localhost:18080 + CHROME_DEBUGGING_PORT: 9222 + networks: + - test-network + +volumes: + wizard_config: + +networks: + test-network: + driver: bridge diff --git a/docker-compose-frontend.yml b/docker-compose-frontend.yml index 0cee06f..019d5ad 100644 --- a/docker-compose-frontend.yml +++ b/docker-compose-frontend.yml @@ -53,11 +53,6 @@ services: SECRET_KEY: ${SECRET_KEY:-change_me_in_production} LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: mysql+pymysql://harborforge:harborforge_pass@mysql:3306/harborforge - ports: - - "${MAP_BACKEND_PORT:- }:8000" - depends_on: - mysql: - condition: service_healthy networks: - test-network @@ -73,11 +68,6 @@ services: restart: "no" environment: VITE_API_BASE_URL: http://backend:8000 - ports: - - "${MAP_FRONTEND_PORT:- }:3000" - depends_on: - - wizard - - backend networks: - test-network diff --git a/run-test-frontend.sh b/run-test-frontend.sh new file mode 100755 index 0000000..885a988 --- /dev/null +++ b/run-test-frontend.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# Run frontend test with optional port exposure +# Usage: ./run-test-frontend.sh [--expose-port {on|off}] +# Default: off (no ports exposed to host) + +set -e + +EXPOSE_PORT="off" +COMPOSE_FILE="docker-compose-frontend.yml" + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --expose-port) + EXPOSE_PORT="$2" + shift 2 + ;; + --expose-port=*) + EXPOSE_PORT="${1#*=}" + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 [--expose-port {on|off}]" + 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 + +# Select compose file based on expose-port +if [[ "$EXPOSE_PORT" == "on" ]]; then + COMPOSE_FILE="docker-compose-frontend-expose.yml" + echo "๐Ÿ”Œ Port exposure: ON" +else + echo "๐Ÿ”Œ Port exposure: OFF" +fi + +echo "๐Ÿ“ฆ Using compose file: $COMPOSE_FILE" +echo "๐Ÿš€ Running HarborForge Frontend Test..." + +# Clean any previous containers first +docker compose -f "$COMPOSE_FILE" down 2>/dev/null || true + +# Start services +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 +docker compose -f "$COMPOSE_FILE" run --rm test +TEST_EXIT_CODE=$? + +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 + +exit $TEST_EXIT_CODE