#!/usr/bin/env node // scripts/test-all.ts // // ICC Interac Manager — Master Test Runner // Run: npx tsx scripts/test-all.ts // // Runs all test suites in the correct order: // 1. Unit tests (no server needed) // 2. Health check (validates environment) // 3. API tests (requires server running) // 4. WebSocket tests (requires server running) // 5. AI parsing tests (requires API keys) import 'dotenv/config'; import { execSync } from 'child_process'; import path from 'path'; import { fileURLToPath } from 'url'; const BOLD = '\x1b[1m'; const RESET = '\x1b[0m'; const GREEN = '\x1b[32m'; const RED = '\x1b[31m'; const YELLOW = '\x1b[33m'; const CYAN = '\x1b[36m'; const scriptsDir = path.dirname(fileURLToPath(import.meta.url)); interface TestSuite { name: string; file: string; requiresServer: boolean; requiresAI: boolean; } const suites: TestSuite[] = [ { name: '1. Unit Tests', file: 'test-units.ts', requiresServer: false, requiresAI: false }, { name: '2. Health Check', file: 'healthcheck.ts', requiresServer: false, requiresAI: false }, { name: '3. API Endpoint Tests', file: 'test-api.ts', requiresServer: true, requiresAI: false }, { name: '4. WebSocket Tests', file: 'test-websocket.ts', requiresServer: true, requiresAI: false }, { name: '5. AI Parsing Tests', file: 'test-ai-parsing.ts', requiresServer: false, requiresAI: true }, ]; async function main() { console.log(`\n${BOLD}╔══════════════════════════════════════════╗${RESET}`); console.log(`${BOLD}║ ICC Interac Manager — Test Runner ║${RESET}`); console.log(`${BOLD}╚══════════════════════════════════════════╝${RESET}\n`); let totalPassed = 0; let totalFailed = 0; const results: { name: string; status: 'pass' | 'fail' | 'skip' }[] = []; // Check if server is running let serverRunning = false; try { const port = process.env.PORT || '3001'; const res = await fetch(`http://localhost:${port}/api/health`, { signal: AbortSignal.timeout(2000) }); serverRunning = res.ok; } catch {} if (!serverRunning) { console.log(`${YELLOW}⚠️ Server not running on port ${process.env.PORT || '3001'}${RESET}`); console.log(` Some tests will be skipped. Start server with:`); console.log(` ${CYAN}npx tsx packages/server/src/index.ts${RESET}\n`); } for (const suite of suites) { console.log(`${BOLD}━━━ ${suite.name} ━━━${RESET}`); // Skip conditions if (suite.requiresServer && !serverRunning) { console.log(` ${YELLOW}⏭️ Skipped (server not running)${RESET}\n`); results.push({ name: suite.name, status: 'skip' }); continue; } if (suite.requiresAI && !process.env.GROQ_API_KEY && !process.env.MISTRAL_API_KEY) { console.log(` ${YELLOW}⏭️ Skipped (no AI API keys)${RESET}\n`); results.push({ name: suite.name, status: 'skip' }); continue; } try { const filePath = path.join(scriptsDir, suite.file); execSync(`npx tsx "${filePath}"`, { stdio: 'inherit', env: { ...process.env }, cwd: process.cwd(), }); results.push({ name: suite.name, status: 'pass' }); totalPassed++; } catch (error: any) { results.push({ name: suite.name, status: 'fail' }); totalFailed++; } console.log(''); } // ═══ FINAL SUMMARY ═══ console.log(`${BOLD}╔══════════════════════════════════════════╗${RESET}`); console.log(`${BOLD}║ Final Results ║${RESET}`); console.log(`${BOLD}╠══════════════════════════════════════════╣${RESET}`); for (const r of results) { const icon = r.status === 'pass' ? `${GREEN}✅` : r.status === 'fail' ? `${RED}❌` : `${YELLOW}⏭️ `; console.log(`${BOLD}║${RESET} ${icon} ${r.name}${RESET}`); } console.log(`${BOLD}╠══════════════════════════════════════════╣${RESET}`); const skipped = results.filter((r) => r.status === 'skip').length; console.log(`${BOLD}║${RESET} Suites: ${GREEN}${totalPassed} passed${RESET}, ${RED}${totalFailed} failed${RESET}, ${YELLOW}${skipped} skipped${RESET}`); console.log(`${BOLD}╚══════════════════════════════════════════╝${RESET}\n`); if (totalFailed === 0 && skipped === 0) { console.log(`${GREEN}🎉 All tests passed! Your ICC app is ready.${RESET}\n`); } else if (totalFailed === 0) { console.log(`${YELLOW}⚠️ Some tests skipped. Run the server and add API keys to test everything.${RESET}\n`); } else { console.log(`${RED}🔧 Fix the failing tests above, then re-run.${RESET}\n`); } process.exit(totalFailed > 0 ? 1 : 0); } main().catch(console.error);