#!/bin/bash # Comprehensive release testing script for Pulse # Tests actual deployments, not just unit tests set -e VERSION=${1:-$(cat VERSION)} PULSE_URL=${PULSE_URL:-http://localhost:7655} API_TOKEN=${API_TOKEN:-""} RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' echo "================================================" echo "Pulse Release Test Suite v${VERSION}" echo "================================================" # Track test results FAILED_TESTS=() PASSED_TESTS=() # Test function run_test() { local test_name="$1" local test_command="$2" echo -n "Testing: $test_name... " if eval "$test_command" > /dev/null 2>&1; then echo -e "${GREEN}✓${NC}" PASSED_TESTS+=("$test_name") else echo -e "${RED}✗${NC}" FAILED_TESTS+=("$test_name") fi } # Test function with output run_test_verbose() { local test_name="$1" local test_command="$2" echo "Testing: $test_name..." if eval "$test_command"; then echo -e "${GREEN}✓ $test_name passed${NC}" PASSED_TESTS+=("$test_name") else echo -e "${RED}✗ $test_name failed${NC}" FAILED_TESTS+=("$test_name") fi } echo "" echo "1. HTTP/ROUTING TESTS" echo "====================" # Critical: Test root without trailing slash (catches issue #334) run_test "Root path without trailing slash (no redirect)" \ "curl -s -I ${PULSE_URL} | grep -q 'HTTP/1.1 200'" run_test "Root path with trailing slash" \ "curl -s -I ${PULSE_URL}/ | grep -q 'HTTP/1.1 200'" # Check for unwanted redirects run_test "No relative path redirects" \ "! curl -s -I ${PULSE_URL} | grep -q 'Location: ./'" # Test static assets (get actual filenames from index.html) JS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.js' | head -1) CSS_FILE=$(curl -s ${PULSE_URL}/ | grep -o '/assets/index-[^"]*\.css' | head -1) if [ -n "$JS_FILE" ]; then run_test "JavaScript assets load" \ "curl -s -I ${PULSE_URL}${JS_FILE} | grep -q 'Content-Type: application/javascript'" else echo -e "${RED}✗ Could not find JS file${NC}" FAILED_TESTS+=("JavaScript assets load") fi if [ -n "$CSS_FILE" ]; then run_test "CSS assets load" \ "curl -s -I ${PULSE_URL}${CSS_FILE} | grep -q 'Content-Type: text/css'" else echo -e "${RED}✗ Could not find CSS file${NC}" FAILED_TESTS+=("CSS assets load") fi # Test various access patterns run_test "Empty path handling" \ "curl -s -o /dev/null -w '%{http_code}' ${PULSE_URL} | grep -q '200'" run_test "SPA routes require authentication" \ "curl -s ${PULSE_URL}/settings | grep -q 'Authentication required'" echo "" echo "2. API ENDPOINT TESTS" echo "====================" # Public endpoints (should work without auth) run_test "API health endpoint" \ "curl -s ${PULSE_URL}/api/health | grep -q 'healthy'" run_test "API version endpoint" \ "curl -s ${PULSE_URL}/api/version | grep -q 'version'" # If API token provided, test protected endpoints if [ -n "$API_TOKEN" ]; then echo "Testing with API token..." run_test "API state with token" \ "curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/state | grep -q 'nodes'" run_test "API config/nodes with token" \ "curl -s -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/nodes | jq -e '. | type == \"array\"'" run_test "API export requires passphrase" \ "curl -s -X POST -H 'X-API-Token: $API_TOKEN' ${PULSE_URL}/api/config/export -d '{}' | grep -q 'Passphrase is required'" else echo -e "${YELLOW}Skipping auth tests (no API_TOKEN provided)${NC}" fi echo "" echo "3. WEBSOCKET TESTS" echo "==================" # Test WebSocket endpoint availability run_test "WebSocket endpoint responds" \ "curl -s -I -H 'Upgrade: websocket' ${PULSE_URL}/ws | grep -q 'HTTP/1.1'" echo "" echo "4. REVERSE PROXY SIMULATION" echo "===========================" # Simulate reverse proxy headers run_test "Handles X-Forwarded headers" \ "curl -s -H 'X-Forwarded-For: 10.0.0.1' -H 'X-Forwarded-Proto: https' ${PULSE_URL}/api/health | grep -q 'healthy'" run_test "Handles proxy without trailing slash" \ "curl -s -H 'X-Forwarded-Host: proxy.example.com' ${PULSE_URL} | grep -q '