mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 18:16:08 +00:00
- Move ux-integration-test.sh to tests/integration/ directory - Consolidate tests/fixtures/ into tests/shared/fixtures/ - Fix import paths in cli.test.js and postinstall.test.js - Remove src/ccs.ts.backup file (958 lines) - Remove empty src/scripts/ directory - Remove non-existent test:edge-cases script from package.json - Update tests/README.md with accurate structure - Update CONTRIBUTING.md with correct test commands - Update docs/system-architecture.md with correct test paths
594 lines
17 KiB
Bash
Executable File
594 lines
17 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# CLI UX Integration Test Suite
|
|
# Tests all 6 phases of CLI UX improvements
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
RESET='\033[0m'
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
# Test counters
|
|
TOTAL_TESTS=0
|
|
PASSED_TESTS=0
|
|
FAILED_TESTS=0
|
|
SKIPPED_TESTS=0
|
|
|
|
# Current test tracking
|
|
CURRENT_TEST_HAS_FAILURE=0
|
|
|
|
# Test results
|
|
RESULTS=()
|
|
|
|
# Helper functions
|
|
log_info() {
|
|
echo -e "${CYAN}[INFO]${RESET} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[PASS]${RESET} $1"
|
|
}
|
|
|
|
log_fail() {
|
|
echo -e "${RED}[FAIL]${RESET} $1"
|
|
CURRENT_TEST_HAS_FAILURE=1
|
|
}
|
|
|
|
log_skip() {
|
|
echo -e "${YELLOW}[SKIP]${RESET} $1"
|
|
CURRENT_TEST_HAS_FAILURE=-1 # Mark as skipped
|
|
}
|
|
|
|
test_start() {
|
|
# Finalize previous test if any
|
|
if [[ $TOTAL_TESTS -gt 0 ]]; then
|
|
test_end
|
|
fi
|
|
|
|
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
|
CURRENT_TEST_HAS_FAILURE=0
|
|
echo ""
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
echo -e "${CYAN}Test $TOTAL_TESTS: $1${RESET}"
|
|
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
|
|
}
|
|
|
|
test_end() {
|
|
# Count this test as passed, failed, or skipped
|
|
if [[ $CURRENT_TEST_HAS_FAILURE -eq -1 ]]; then
|
|
SKIPPED_TESTS=$((SKIPPED_TESTS + 1))
|
|
elif [[ $CURRENT_TEST_HAS_FAILURE -eq 0 ]]; then
|
|
PASSED_TESTS=$((PASSED_TESTS + 1))
|
|
else
|
|
FAILED_TESTS=$((FAILED_TESTS + 1))
|
|
fi
|
|
}
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
log_info "Checking prerequisites..."
|
|
|
|
if ! command -v node &>/dev/null; then
|
|
echo "ERROR: Node.js not found. Please install Node.js 14+"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v jq &>/dev/null; then
|
|
echo "ERROR: jq not found. Please install jq"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$PROJECT_ROOT/bin/ccs.js" ]]; then
|
|
echo "ERROR: bin/ccs.js not found. Run from project root."
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Prerequisites OK"
|
|
}
|
|
|
|
# Setup test environment
|
|
setup_test_env() {
|
|
log_info "Setting up test environment..."
|
|
|
|
# Backup existing CCS data
|
|
if [[ -d ~/.ccs ]]; then
|
|
local backup_dir=~/.ccs.backup.$(date +%s)
|
|
mv ~/.ccs "$backup_dir"
|
|
log_info "Backed up existing ~/.ccs to $backup_dir"
|
|
fi
|
|
|
|
# Create fresh test environment
|
|
mkdir -p ~/.ccs/instances/test-work/session-env
|
|
mkdir -p ~/.ccs/instances/test-personal/session-env
|
|
|
|
# Create test profiles
|
|
cat > ~/.ccs/profiles.json <<'EOF'
|
|
{
|
|
"profiles": {
|
|
"test-work": {
|
|
"type": "account",
|
|
"created": "2025-11-14T00:00:00.000Z"
|
|
},
|
|
"test-personal": {
|
|
"type": "account",
|
|
"created": "2025-11-14T00:00:00.000Z"
|
|
}
|
|
},
|
|
"default": "test-work"
|
|
}
|
|
EOF
|
|
|
|
# Create dummy session files
|
|
echo '{}' > ~/.ccs/instances/test-work/session-env/session1.json
|
|
echo '{}' > ~/.ccs/instances/test-work/session-env/session2.json
|
|
echo '{}' > ~/.ccs/instances/test-personal/session-env/session3.json
|
|
|
|
# Create config.json with settings-based profiles (for fuzzy matching tests)
|
|
cat > ~/.ccs/config.json <<'EOF'
|
|
{
|
|
"profiles": {
|
|
"glm": "~/.ccs/glm.settings.json",
|
|
"kimi": "~/.ccs/kimi.settings.json",
|
|
"default": "~/.claude/settings.json"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
log_success "Test environment ready"
|
|
}
|
|
|
|
# Cleanup test environment
|
|
cleanup_test_env() {
|
|
log_info "Cleaning up test environment..."
|
|
|
|
rm -rf ~/.ccs
|
|
|
|
# Restore backup if exists
|
|
local latest_backup=$(ls -td ~/.ccs.backup.* 2>/dev/null | head -1 || true)
|
|
if [[ -n "$latest_backup" ]]; then
|
|
mv "$latest_backup" ~/.ccs
|
|
log_info "Restored backup from $latest_backup"
|
|
fi
|
|
|
|
log_success "Cleanup complete"
|
|
}
|
|
|
|
#############################
|
|
# Phase 1: Error Messaging
|
|
#############################
|
|
|
|
test_error_codes() {
|
|
test_start "Phase 1.1 - Error codes display"
|
|
|
|
# Node.js version
|
|
local node_output=$(node "$PROJECT_ROOT/bin/ccs.js" nonexistent-profile "test" 2>&1)
|
|
if echo "$node_output" | grep -q "E[0-9]\{3\}"; then
|
|
log_success "Node.js: Error code displayed"
|
|
else
|
|
log_fail "Node.js: Error code NOT displayed"
|
|
echo " Debug: Output was:" >&2
|
|
echo "$node_output" | tail -3 >&2
|
|
fi
|
|
|
|
# Bash version
|
|
local bash_output=$("$PROJECT_ROOT/lib/ccs" nonexistent-profile "test" 2>&1)
|
|
if echo "$bash_output" | grep -q "E[0-9]\{3\}"; then
|
|
log_success "Bash: Error code displayed"
|
|
else
|
|
log_fail "Bash: Error code NOT displayed"
|
|
echo " Debug: Output was:" >&2
|
|
echo "$bash_output" | tail -3 >&2
|
|
fi
|
|
}
|
|
|
|
test_fuzzy_matching() {
|
|
test_start "Phase 1.2 - Fuzzy matching 'Did you mean?'"
|
|
|
|
# Node.js version (typo: glmm instead of glm)
|
|
local node_output=$(node "$PROJECT_ROOT/bin/ccs.js" glmm "test" 2>&1)
|
|
if echo "$node_output" | grep -qi "did you mean"; then
|
|
log_success "Node.js: Fuzzy matching works"
|
|
else
|
|
log_fail "Node.js: Fuzzy matching NOT working"
|
|
echo " Debug: Looking for 'did you mean' in output:" >&2
|
|
echo "$node_output" | grep -i "mean\|glm\|profile" | head -5 >&2
|
|
fi
|
|
|
|
# Bash version
|
|
local bash_output=$("$PROJECT_ROOT/lib/ccs" glmm "test" 2>&1)
|
|
if echo "$bash_output" | grep -qi "did you mean"; then
|
|
log_success "Bash: Fuzzy matching works"
|
|
else
|
|
log_fail "Bash: Fuzzy matching NOT working"
|
|
echo " Debug: Looking for 'did you mean' in output:" >&2
|
|
echo "$bash_output" | grep -i "mean\|glm\|profile" | head -5 >&2
|
|
fi
|
|
|
|
# Additional test with account profiles (if they exist)
|
|
if [[ -f ~/.ccs/profiles.json ]] && grep -q "test-work" ~/.ccs/profiles.json; then
|
|
local node_acct_output=$(node "$PROJECT_ROOT/bin/ccs.js" test-wrk "test" 2>&1)
|
|
if echo "$node_acct_output" | grep -qi "did you mean"; then
|
|
log_success "Node.js: Fuzzy matching works for account profiles"
|
|
else
|
|
log_fail "Node.js: Fuzzy matching NOT working for account profiles"
|
|
echo " Debug: test-wrk output:" >&2
|
|
echo "$node_acct_output" | grep -i "mean\|test\|profile" | head -5 >&2
|
|
fi
|
|
|
|
local bash_acct_output=$("$PROJECT_ROOT/lib/ccs" test-wrk "test" 2>&1)
|
|
if echo "$bash_acct_output" | grep -qi "did you mean"; then
|
|
log_success "Bash: Fuzzy matching works for account profiles"
|
|
else
|
|
log_fail "Bash: Fuzzy matching NOT working for account profiles"
|
|
echo " Debug: test-wrk output:" >&2
|
|
echo "$bash_acct_output" | grep -i "mean\|test\|profile" | head -5 >&2
|
|
fi
|
|
fi
|
|
}
|
|
|
|
test_examples_section() {
|
|
test_start "Phase 1.3 - EXAMPLES section in help"
|
|
|
|
# Node.js version
|
|
if node "$PROJECT_ROOT/bin/ccs.js" --help 2>&1 | grep -qi "examples:"; then
|
|
log_success "Node.js: EXAMPLES section present"
|
|
else
|
|
log_fail "Node.js: EXAMPLES section missing"
|
|
fi
|
|
|
|
# Bash version
|
|
if "$PROJECT_ROOT/lib/ccs" --help 2>&1 | grep -qi "examples:"; then
|
|
log_success "Bash: EXAMPLES section present"
|
|
else
|
|
log_fail "Bash: EXAMPLES section missing"
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Phase 2: Progress Indicators
|
|
#############################
|
|
|
|
test_doctor_progress() {
|
|
test_start "Phase 2.1 - Doctor command progress"
|
|
|
|
# Node.js version
|
|
if timeout 5s node "$PROJECT_ROOT/bin/ccs.js" doctor 2>&1 | grep -q "Checking"; then
|
|
log_success "Node.js: Doctor progress displayed"
|
|
else
|
|
log_skip "Node.js: Doctor command (may need Claude CLI installed)"
|
|
fi
|
|
|
|
# Bash version
|
|
if timeout 5s "$PROJECT_ROOT/lib/ccs" doctor 2>&1 | grep -E "\[[0-9]+/[0-9]+\]" > /dev/null; then
|
|
log_success "Bash: Doctor progress counter displayed"
|
|
else
|
|
log_skip "Bash: Doctor command (may need Claude CLI installed)"
|
|
fi
|
|
}
|
|
|
|
test_tty_detection() {
|
|
test_start "Phase 2.2 - TTY detection (NO_COLOR)"
|
|
|
|
# Test that NO_COLOR disables colors
|
|
if NO_COLOR=1 node "$PROJECT_ROOT/bin/ccs.js" --help 2>&1 | grep -q $'\033\['; then
|
|
log_fail "Node.js: Colors shown despite NO_COLOR"
|
|
else
|
|
log_success "Node.js: NO_COLOR respected"
|
|
fi
|
|
|
|
if NO_COLOR=1 "$PROJECT_ROOT/lib/ccs" --help 2>&1 | grep -q $'\033\['; then
|
|
log_fail "Bash: Colors shown despite NO_COLOR"
|
|
else
|
|
log_success "Bash: NO_COLOR respected"
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Phase 3: Interactive Prompts
|
|
#############################
|
|
|
|
test_confirmation_prompt() {
|
|
test_start "Phase 3.1 - Auth remove confirmation"
|
|
|
|
# Node.js version (send 'n' to cancel)
|
|
if echo "n" | node "$PROJECT_ROOT/bin/ccs.js" auth remove test-personal 2>&1 | grep -q "Cancelled"; then
|
|
log_success "Node.js: Confirmation prompt works (cancelled)"
|
|
else
|
|
log_fail "Node.js: Confirmation prompt NOT working"
|
|
fi
|
|
|
|
# Bash version
|
|
if echo "n" | "$PROJECT_ROOT/lib/ccs" auth remove test-personal 2>&1 | grep -q "Cancelled"; then
|
|
log_success "Bash: Confirmation prompt works (cancelled)"
|
|
else
|
|
log_fail "Bash: Confirmation prompt NOT working"
|
|
fi
|
|
}
|
|
|
|
test_yes_flag() {
|
|
test_start "Phase 3.2 - --yes flag auto-confirm"
|
|
|
|
# Node.js version (should NOT prompt)
|
|
local output=$(node "$PROJECT_ROOT/bin/ccs.js" auth remove test-personal --yes 2>&1 || true)
|
|
if echo "$output" | grep -q "Profile removed successfully"; then
|
|
log_success "Node.js: --yes flag works"
|
|
|
|
# Recreate profile for bash test
|
|
cat > ~/.ccs/profiles.json <<'EOF'
|
|
{
|
|
"profiles": {
|
|
"test-work": {
|
|
"type": "account",
|
|
"created": "2025-11-14T00:00:00.000Z"
|
|
},
|
|
"test-personal": {
|
|
"type": "account",
|
|
"created": "2025-11-14T00:00:00.000Z"
|
|
}
|
|
},
|
|
"default": "test-work"
|
|
}
|
|
EOF
|
|
else
|
|
log_fail "Node.js: --yes flag NOT working"
|
|
fi
|
|
|
|
# Bash version
|
|
if "$PROJECT_ROOT/lib/ccs" auth remove test-personal --yes 2>&1 | grep -q "Profile removed successfully"; then
|
|
log_success "Bash: --yes flag works"
|
|
else
|
|
log_fail "Bash: --yes flag NOT working"
|
|
fi
|
|
}
|
|
|
|
test_impact_display() {
|
|
test_start "Phase 3.3 - Impact display (sessions, paths)"
|
|
|
|
# Recreate profile if needed
|
|
if ! grep -q "test-work" ~/.ccs/profiles.json 2>/dev/null; then
|
|
cat > ~/.ccs/profiles.json <<'EOF'
|
|
{
|
|
"profiles": {
|
|
"test-work": {
|
|
"type": "account",
|
|
"created": "2025-11-14T00:00:00.000Z"
|
|
}
|
|
},
|
|
"default": "test-work"
|
|
}
|
|
EOF
|
|
fi
|
|
|
|
# Node.js version
|
|
if echo "n" | node "$PROJECT_ROOT/bin/ccs.js" auth remove test-work 2>&1 | grep -E "Sessions:|Instance path:" | wc -l | grep -q "2"; then
|
|
log_success "Node.js: Impact display shown"
|
|
else
|
|
log_fail "Node.js: Impact display NOT shown"
|
|
fi
|
|
|
|
# Bash version
|
|
if echo "n" | "$PROJECT_ROOT/lib/ccs" auth remove test-work 2>&1 | grep -E "Sessions:|Instance path:" | wc -l | grep -q "2"; then
|
|
log_success "Bash: Impact display shown"
|
|
else
|
|
log_fail "Bash: Impact display NOT shown"
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Phase 4: JSON Output
|
|
#############################
|
|
|
|
test_json_output() {
|
|
test_start "Phase 4.1 - JSON output (auth list)"
|
|
|
|
# Node.js version
|
|
if node "$PROJECT_ROOT/bin/ccs.js" auth list --json 2>/dev/null | jq . > /dev/null 2>&1; then
|
|
log_success "Node.js: Valid JSON output"
|
|
else
|
|
log_fail "Node.js: Invalid JSON output"
|
|
fi
|
|
|
|
# Bash version
|
|
if "$PROJECT_ROOT/lib/ccs" auth list --json 2>/dev/null | jq . > /dev/null 2>&1; then
|
|
log_success "Bash: Valid JSON output"
|
|
else
|
|
log_fail "Bash: Invalid JSON output"
|
|
fi
|
|
}
|
|
|
|
test_json_version() {
|
|
test_start "Phase 4.2 - JSON uses CCS version (not '1.0')"
|
|
|
|
# Node.js version
|
|
local version=$(node "$PROJECT_ROOT/bin/ccs.js" auth list --json 2>/dev/null | jq -r '.version')
|
|
if [[ "$version" != "1.0" ]] && [[ -n "$version" ]]; then
|
|
log_success "Node.js: JSON version is '$version' (not '1.0')"
|
|
else
|
|
log_fail "Node.js: JSON version is '1.0' (should be CCS version)"
|
|
fi
|
|
|
|
# Bash version
|
|
local version=$(lib/ccs auth list --json 2>/dev/null | jq -r '.version')
|
|
if [[ "$version" != "1.0" ]] && [[ -n "$version" ]]; then
|
|
log_success "Bash: JSON version is '$version' (not '1.0')"
|
|
else
|
|
log_fail "Bash: JSON version is '1.0' (should be CCS version)"
|
|
fi
|
|
}
|
|
|
|
test_session_count() {
|
|
test_start "Phase 4.3 - session_count in JSON output"
|
|
|
|
# Node.js version
|
|
if node "$PROJECT_ROOT/bin/ccs.js" auth show test-work --json 2>/dev/null | jq -e '.session_count' > /dev/null; then
|
|
log_success "Node.js: session_count present in JSON"
|
|
else
|
|
log_fail "Node.js: session_count missing in JSON"
|
|
fi
|
|
|
|
# Bash version
|
|
if "$PROJECT_ROOT/lib/ccs" auth show test-work --json 2>/dev/null | jq -e '.session_count' > /dev/null; then
|
|
log_success "Bash: session_count present in JSON"
|
|
else
|
|
log_fail "Bash: session_count missing in JSON"
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Phase 5: Cross-Platform Consistency
|
|
#############################
|
|
|
|
test_ascii_error_boxes() {
|
|
test_start "Phase 5.1 - ASCII error boxes (no Unicode)"
|
|
|
|
# Bash version (should use ===== not ╔═╗)
|
|
if "$PROJECT_ROOT/lib/ccs" nonexistent 2>&1 | grep -q "╔\|═\|╗\|║\|╚\|╝"; then
|
|
log_fail "Bash: Unicode box characters found (should be ASCII)"
|
|
else
|
|
log_success "Bash: ASCII-only error boxes"
|
|
fi
|
|
}
|
|
|
|
test_help_consistency() {
|
|
test_start "Phase 5.2 - Help text structure consistency"
|
|
|
|
# Get section headers from both versions (use LC_ALL=C for consistent sorting)
|
|
local node_sections=$(node "$PROJECT_ROOT/bin/ccs.js" --help 2>&1 | grep -E "^[A-Z][a-z]+:" | LC_ALL=C sort)
|
|
local bash_sections=$("$PROJECT_ROOT/lib/ccs" --help 2>&1 | grep -E "^[A-Z][a-z]+:" | LC_ALL=C sort)
|
|
|
|
if [[ "$node_sections" == "$bash_sections" ]]; then
|
|
log_success "Help text structure consistent"
|
|
else
|
|
log_fail "Help text structure differs between Node.js and bash"
|
|
# Debug output
|
|
echo " Node.js sections:" >&2
|
|
echo "$node_sections" | sed 's/^/ /' >&2
|
|
echo " Bash sections:" >&2
|
|
echo "$bash_sections" | sed 's/^/ /' >&2
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Phase 6: Shell Completion
|
|
#############################
|
|
|
|
test_bash_completion() {
|
|
test_start "Phase 6.1 - Bash completion loading"
|
|
|
|
# Source completion script
|
|
if source "$PROJECT_ROOT/scripts/completion/ccs.bash" 2>/dev/null; then
|
|
# Check if completion is registered
|
|
if complete -p ccs 2>/dev/null | grep -q "_ccs_completion"; then
|
|
log_success "Bash completion loaded successfully"
|
|
else
|
|
log_fail "Bash completion NOT registered"
|
|
fi
|
|
else
|
|
log_fail "Bash completion script failed to load"
|
|
fi
|
|
}
|
|
|
|
test_fish_completion() {
|
|
test_start "Phase 6.2 - Fish completion (if available)"
|
|
|
|
if command -v fish &>/dev/null; then
|
|
# Copy completion file
|
|
mkdir -p ~/.config/fish/completions
|
|
cp "$PROJECT_ROOT/scripts/completion/ccs.fish" ~/.config/fish/completions/
|
|
|
|
# Test if Fish can load it
|
|
if fish -c "complete -C'ccs '" 2>/dev/null | grep -q "auth\|doctor"; then
|
|
log_success "Fish completion works"
|
|
else
|
|
log_fail "Fish completion NOT working"
|
|
fi
|
|
else
|
|
log_skip "Fish not installed"
|
|
fi
|
|
}
|
|
|
|
#############################
|
|
# Main Test Runner
|
|
#############################
|
|
|
|
main() {
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " CLI UX Integration Test Suite"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
|
|
check_prerequisites
|
|
setup_test_env
|
|
|
|
# Phase 1 Tests
|
|
test_error_codes
|
|
test_fuzzy_matching
|
|
test_examples_section
|
|
|
|
# Phase 2 Tests
|
|
test_doctor_progress
|
|
test_tty_detection
|
|
|
|
# Phase 3 Tests
|
|
test_confirmation_prompt
|
|
test_yes_flag
|
|
test_impact_display
|
|
|
|
# Phase 4 Tests
|
|
test_json_output
|
|
test_json_version
|
|
test_session_count
|
|
|
|
# Phase 5 Tests
|
|
test_ascii_error_boxes
|
|
test_help_consistency
|
|
|
|
# Phase 6 Tests
|
|
test_bash_completion
|
|
test_fish_completion
|
|
|
|
# Finalize last test
|
|
test_end
|
|
|
|
cleanup_test_env
|
|
|
|
# Print summary
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo " Test Summary"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "Total Tests: $TOTAL_TESTS"
|
|
echo -e "${GREEN}Passed: $PASSED_TESTS${RESET}"
|
|
echo -e "${RED}Failed: $FAILED_TESTS${RESET}"
|
|
echo -e "${YELLOW}Skipped: $SKIPPED_TESTS${RESET}"
|
|
echo ""
|
|
|
|
# Calculate pass rate based on non-skipped tests
|
|
local tests_run=$((TOTAL_TESTS - SKIPPED_TESTS))
|
|
local pass_rate=0
|
|
if [[ $tests_run -gt 0 ]]; then
|
|
pass_rate=$((PASSED_TESTS * 100 / tests_run))
|
|
fi
|
|
echo "Pass Rate: $pass_rate% ($PASSED_TESTS/$tests_run non-skipped tests)"
|
|
echo ""
|
|
|
|
if [[ $pass_rate -ge 90 ]]; then
|
|
echo -e "${GREEN}✓ SUCCESS: Pass rate >= 90%${RESET}"
|
|
exit 0
|
|
else
|
|
echo -e "${RED}✗ FAILURE: Pass rate < 90%${RESET}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Run tests
|
|
main "$@"
|