Files
explorer-monorepo/scripts/e2e-test-explorer.sh

374 lines
12 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# End-to-End Test for explorer.d-bis.org
# Comprehensive testing of all explorer functionality
set -uo pipefail
EXPLORER_URL="https://explorer.d-bis.org"
BASE_URL="http://192.168.11.140"
TEST_RESULTS=()
PASSED=0
FAILED=0
WARNINGS=0
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_test() {
local status=$1
local message=$2
if [ "$status" = "PASS" ]; then
echo -e "${GREEN}✅ PASS${NC}: $message"
((PASSED++))
TEST_RESULTS+=("PASS: $message")
elif [ "$status" = "FAIL" ]; then
echo -e "${RED}❌ FAIL${NC}: $message"
((FAILED++))
TEST_RESULTS+=("FAIL: $message")
elif [ "$status" = "WARN" ]; then
echo -e "${YELLOW}⚠️ WARN${NC}: $message"
((WARNINGS++))
TEST_RESULTS+=("WARN: $message")
else
echo -e "${BLUE} INFO${NC}: $message"
fi
}
test_http_response() {
local url=$1
local expected_code=$2
local description=$3
local response_code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "000")
if [ "$response_code" = "$expected_code" ]; then
log_test "PASS" "$description (HTTP $response_code)"
return 0
elif [ "$response_code" = "000" ]; then
log_test "FAIL" "$description (Connection failed/timeout)"
return 1
else
log_test "FAIL" "$description (Expected HTTP $expected_code, got $response_code)"
return 1
fi
}
test_content() {
local url=$1
local search_term=$2
local description=$3
local content=$(curl -s -L --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "")
if [ -z "$content" ]; then
log_test "FAIL" "$description (Empty response)"
return 1
elif echo "$content" | grep -qi "$search_term"; then
log_test "PASS" "$description (Found: $search_term)"
return 0
else
# Show first 100 chars for debugging
PREVIEW=$(echo "$content" | head -c 100 | tr -d '\n')
log_test "FAIL" "$description (Not found: $search_term, got: $PREVIEW...)"
return 1
fi
}
test_json_response() {
local url=$1
local description=$2
local response=$(curl -s -L --connect-timeout 10 --max-time 30 "$url" 2>/dev/null || echo "")
if echo "$response" | jq . >/dev/null 2>&1; then
log_test "PASS" "$description (Valid JSON)"
return 0
else
log_test "FAIL" "$description (Invalid JSON or empty response)"
return 1
fi
}
echo "=========================================="
echo "End-to-End Test: explorer.d-bis.org"
echo "=========================================="
echo "Test URL: $EXPLORER_URL"
echo "Base URL: $BASE_URL"
echo "Date: $(date)"
echo "=========================================="
echo ""
# ============================================
# 1. Basic Connectivity Tests
# ============================================
echo "=== 1. Basic Connectivity Tests ==="
# Test HTTPS accessibility (may fail if Cloudflare tunnel not running)
HTTPS_CODE=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 10 "$EXPLORER_URL" 2>/dev/null || echo "000")
if [ "$HTTPS_CODE" = "200" ] || [ "$HTTPS_CODE" = "301" ] || [ "$HTTPS_CODE" = "302" ]; then
log_test "PASS" "HTTPS homepage accessibility (HTTP $HTTPS_CODE)"
elif [ "$HTTPS_CODE" = "000" ]; then
log_test "WARN" "HTTPS homepage not accessible externally (Cloudflare tunnel may be down - testing internal access instead)"
else
log_test "WARN" "HTTPS homepage returned HTTP $HTTPS_CODE"
fi
# Test HTTP redirect
test_http_response "http://explorer.d-bis.org" "301\|302" "HTTP to HTTPS redirect"
# Test direct IP access (internal)
test_http_response "$BASE_URL:80/" "200" "Direct IP access (port 80)"
echo ""
# ============================================
# 2. Frontend Content Tests
# ============================================
echo "=== 2. Frontend Content Tests ==="
# Use internal URL for content tests since HTTPS may not be accessible
CONTENT_URL="$BASE_URL:80"
# Test homepage content
test_content "$CONTENT_URL" "SolaceScanScout" "Homepage contains SolaceScanScout title"
# Test explorer branding
test_content "$CONTENT_URL" "Explorer" "Homepage contains explorer branding"
# Test HTML structure
test_content "$CONTENT_URL" "<!DOCTYPE html" "Valid HTML document structure"
# Test JavaScript loading
test_content "$CONTENT_URL" "ethers" "JavaScript libraries present"
echo ""
# ============================================
# 3. API Endpoint Tests
# ============================================
echo "=== 3. API Endpoint Tests ==="
# Test Blockscout API stats (via internal nginx)
test_json_response "$BASE_URL:80/api/v2/stats" "Blockscout API /api/v2/stats endpoint (via nginx)"
# Test Blockscout API blocks (via internal nginx)
test_json_response "$BASE_URL:80/api/v2/blocks" "Blockscout API /api/v2/blocks endpoint (via nginx)"
# Test Blockscout API transactions (via internal nginx)
test_json_response "$BASE_URL:80/api/v2/transactions" "Blockscout API /api/v2/transactions endpoint (via nginx)"
# Test direct API access (internal)
test_json_response "$BASE_URL:4000/api/v2/stats" "Direct Blockscout API access (port 4000)"
echo ""
# ============================================
# 4. Security & Headers Tests
# ============================================
echo "=== 4. Security & Headers Tests ==="
# Test headers from internal nginx
HEADERS=$(curl -s -I -L --connect-timeout 10 --max-time 30 "$BASE_URL:80/" 2>/dev/null || echo "")
if echo "$HEADERS" | grep -qi "strict-transport-security\|HSTS"; then
log_test "PASS" "HSTS header present"
else
log_test "WARN" "HSTS header not found"
fi
if echo "$HEADERS" | grep -qi "x-frame-options"; then
log_test "PASS" "X-Frame-Options header present"
else
log_test "WARN" "X-Frame-Options header not found"
fi
if echo "$HEADERS" | grep -qi "x-content-type-options"; then
log_test "PASS" "X-Content-Type-Options header present"
else
log_test "WARN" "X-Content-Type-Options header not found"
fi
echo ""
# ============================================
# 5. Performance Tests
# ============================================
echo "=== 5. Performance Tests ==="
# Test performance on internal URL
START_TIME=$(date +%s%N)
curl -s -o /dev/null -w '%{time_total}' --connect-timeout 10 --max-time 30 "$BASE_URL:80/" >/dev/null 2>&1
END_TIME=$(date +%s%N)
RESPONSE_TIME=$(echo "scale=3; ($END_TIME - $START_TIME) / 1000000000" | bc 2>/dev/null || echo "N/A")
if [ "$RESPONSE_TIME" != "N/A" ]; then
if (( $(echo "$RESPONSE_TIME < 3.0" | bc -l 2>/dev/null || echo 0) )); then
log_test "PASS" "Response time acceptable (${RESPONSE_TIME}s)"
else
log_test "WARN" "Response time slow (${RESPONSE_TIME}s)"
fi
else
log_test "WARN" "Could not measure response time"
fi
echo ""
# ============================================
# 6. Service Status Tests
# ============================================
echo "=== 6. Service Status Tests ==="
# Test nginx on VMID 5000
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- systemctl is-active nginx 2>/dev/null'" 2>/dev/null | grep -q "active"; then
log_test "PASS" "Nginx service running on VMID 5000"
else
log_test "FAIL" "Nginx service not running on VMID 5000"
fi
# Test Blockscout service
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- systemctl is-active blockscout 2>/dev/null || pct exec 5000 -- docker ps | grep -q blockscout'" 2>/dev/null | grep -qE "active|blockscout"; then
log_test "PASS" "Blockscout service running on VMID 5000"
else
log_test "WARN" "Blockscout service status unknown"
fi
# Test port 80 listening
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- ss -tlnp | grep -q :80'" 2>/dev/null; then
log_test "PASS" "Port 80 listening on VMID 5000"
else
log_test "FAIL" "Port 80 not listening on VMID 5000"
fi
# Test port 4000 listening
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- ss -tlnp | grep -q :4000'" 2>/dev/null; then
log_test "PASS" "Port 4000 listening on VMID 5000"
else
log_test "WARN" "Port 4000 not listening on VMID 5000"
fi
echo ""
# ============================================
# 7. Frontend Functionality Tests
# ============================================
echo "=== 7. Frontend Functionality Tests ==="
# Check if frontend file exists
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- test -f /var/www/html/index.html'" 2>/dev/null; then
log_test "PASS" "Frontend HTML file exists"
else
log_test "FAIL" "Frontend HTML file not found"
fi
# Check frontend file size (should be substantial)
FRONTEND_SIZE=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-02 'pct exec 5000 -- stat -c%s /var/www/html/index.html 2>/dev/null'" 2>/dev/null || echo "0")
if [ "$FRONTEND_SIZE" -gt 10000 ]; then
log_test "PASS" "Frontend file size reasonable (${FRONTEND_SIZE} bytes)"
else
log_test "WARN" "Frontend file size suspiciously small (${FRONTEND_SIZE} bytes)"
fi
echo ""
# ============================================
# 8. Network Routing Tests
# ============================================
echo "=== 8. Network Routing Tests ==="
# Test NPMplus routing (may fail if Cloudflare tunnel down)
NPMPLUS_CHECK=$(curl -s -I --connect-timeout 5 --max-time 10 "https://explorer.d-bis.org" 2>/dev/null | head -1 || echo "")
if echo "$NPMPLUS_CHECK" | grep -qE "200|301|302"; then
log_test "PASS" "NPMplus routing working"
elif echo "$NPMPLUS_CHECK" | grep -qE "000|timeout"; then
log_test "WARN" "NPMplus routing timeout (Cloudflare tunnel may be down)"
else
log_test "WARN" "NPMplus routing returned: $NPMPLUS_CHECK"
fi
# Test DNS resolution
if host explorer.d-bis.org 2>/dev/null | grep -q "has address"; then
log_test "PASS" "DNS resolution working"
else
log_test "WARN" "DNS resolution check failed (may be local DNS issue)"
fi
echo ""
# ============================================
# 9. API Data Validation
# ============================================
echo "=== 9. API Data Validation ==="
# Get stats and validate structure (use internal URL)
STATS_JSON=$(curl -s -L --connect-timeout 10 --max-time 30 "$BASE_URL:80/api/v2/stats" 2>/dev/null || echo "{}")
if echo "$STATS_JSON" | jq -e '.total_blocks' >/dev/null 2>&1; then
TOTAL_BLOCKS=$(echo "$STATS_JSON" | jq -r '.total_blocks // 0')
if [ "$TOTAL_BLOCKS" -gt 0 ]; then
log_test "PASS" "API returns valid block count ($TOTAL_BLOCKS blocks)"
else
log_test "WARN" "API returns zero blocks (may be indexing)"
fi
else
log_test "FAIL" "API stats structure invalid"
fi
# Check for chain ID
if echo "$STATS_JSON" | jq -e '.chain_id' >/dev/null 2>&1; then
CHAIN_ID=$(echo "$STATS_JSON" | jq -r '.chain_id // "unknown"')
log_test "PASS" "API returns chain ID ($CHAIN_ID)"
else
log_test "WARN" "API does not return chain ID"
fi
echo ""
# ============================================
# 10. Error Handling Tests
# ============================================
echo "=== 10. Error Handling Tests ==="
# Test 404 handling (use internal URL)
test_http_response "$BASE_URL:80/nonexistent-page" "404" "404 error handling"
# Test API error handling (use internal URL)
API_ERROR=$(curl -s -L --connect-timeout 10 --max-time 30 "$BASE_URL:80/api/v2/invalid-endpoint" 2>/dev/null || echo "")
if echo "$API_ERROR" | grep -qiE "error|404|not found"; then
log_test "PASS" "API error handling works"
else
log_test "WARN" "API error handling unclear"
fi
echo ""
# ============================================
# Summary
# ============================================
echo "=========================================="
echo "Test Summary"
echo "=========================================="
echo -e "${GREEN}Passed: $PASSED${NC}"
echo -e "${RED}Failed: $FAILED${NC}"
echo -e "${YELLOW}Warnings: $WARNINGS${NC}"
echo ""
TOTAL=$((PASSED + FAILED + WARNINGS))
if [ $TOTAL -gt 0 ]; then
PASS_PERCENT=$(echo "scale=1; $PASSED * 100 / $TOTAL" | bc 2>/dev/null || echo "0")
echo "Pass Rate: ${PASS_PERCENT}%"
fi
echo ""
if [ $FAILED -eq 0 ]; then
echo -e "${GREEN}✅ All critical tests passed!${NC}"
exit 0
else
echo -e "${RED}❌ Some tests failed. Review results above.${NC}"
exit 1
fi