Skip to main content
Glama
vitest.global-setup.ts4.98 kB
import { spawn, ChildProcess } from 'child_process'; import { writeFileSync, unlinkSync, existsSync } from 'fs'; import path from 'path'; const TEST_APP_PATH = path.resolve(process.cwd(), '../test-app'), TEST_APP_PORT_FILE = path.resolve(process.cwd(), '.test-app-port'); // Detect GitHub CI environment and use longer timeout // eslint-disable-next-line no-process-env const IS_CI = Boolean(process.env.CI || process.env.GITHUB_ACTIONS); const STARTUP_TIMEOUT_MS = IS_CI ? 480000 : 30000; // 4 minutes in CI, 30 seconds locally let tauriProcess: ChildProcess | null = null, isShuttingDown = false, testAppPort: number | null = null; async function startGlobalTestApp(): Promise<void> { return new Promise((resolve, reject) => { console.log('🚀 Starting Tauri app globally (once for all tests)...'); tauriProcess = spawn('npm', [ 'run', 'tauri', 'dev' ], { cwd: TEST_APP_PATH, stdio: 'pipe', shell: true, detached: process.platform !== 'win32', // eslint-disable-next-line no-process-env env: { ...process.env, WEBKIT_DISABLE_COMPOSITING_MODE: '1' }, }); if (!tauriProcess.stdout || !tauriProcess.stderr) { reject(new Error('Failed to spawn Tauri process')); return; } let appReady = false, pluginReady = false; const checkReady = (): void => { if (appReady && pluginReady) { console.log('✅ Global test environment ready!'); resolve(); } }; tauriProcess.stdout.on('data', (data) => { const output = data.toString(); // Only log important messages if (output.includes('Local:') || output.includes('MCP Bridge') || output.includes('WebSocket server')) { console.log('[App]:', output.trim()); } if (!appReady && (output.includes('Local:') || output.includes('http://localhost:1420'))) { appReady = true; console.log('✓ Vite server ready'); checkReady(); } if (!pluginReady && output.includes('WebSocket server listening on:')) { // Extract the port from the log message (e.g., "0.0.0.0:9301") const portMatch = output.match(/WebSocket server listening on:.*:(\d+)/); if (portMatch) { testAppPort = parseInt(portMatch[1], 10); console.log(`✓ MCP Bridge plugin ready on port ${testAppPort}`); } else { console.log('✓ MCP Bridge plugin ready'); } pluginReady = true; checkReady(); } }); tauriProcess.stderr.on('data', (data) => { // Don't log anything during shutdown if (isShuttingDown) { return; } const err = data.toString(), noisePatterns = [ 'Compiling', 'Building', 'Finished', 'Info', 'Running', 'npm warn' ], isNoise = noisePatterns.some((p) => { return err.includes(p); }); if (!isNoise) { console.error('[App Error]:', err.trim()); } }); tauriProcess.on('error', (error) => { // Don't log anything during shutdown if (isShuttingDown) { return; } console.error('Failed to start Tauri process:', error); reject(error); }); // Timeout for app startup setTimeout(() => { if (!appReady || !pluginReady) { reject(new Error(`Tauri app failed to start within ${STARTUP_TIMEOUT_MS / 1000}s timeout`)); } }, STARTUP_TIMEOUT_MS); }); } function stopGlobalTestApp(): void { if (tauriProcess) { console.log('🛑 Stopping global Tauri app...'); isShuttingDown = true; try { if (process.platform === 'win32') { const pid = tauriProcess.pid; if (pid) { spawn('taskkill', [ '/pid', pid.toString(), '/f', '/t' ]); } } else { // Kill the entire process group const pid = tauriProcess.pid; if (pid) { process.kill(-pid, 'SIGTERM'); } } } catch(error: unknown) { console.error('Error stopping Tauri app:', error); } tauriProcess = null; } } export async function setup(): Promise<void> { await startGlobalTestApp(); // Write port to file so tests can read it (global vars don't work across processes) if (testAppPort) { writeFileSync(TEST_APP_PORT_FILE, String(testAppPort), 'utf-8'); } // Store the process reference globally (global as Record<string, unknown>).__TAURI_APP_STARTED = true; } export async function teardown(): Promise<void> { stopGlobalTestApp(); // Clean up the port file if (existsSync(TEST_APP_PORT_FILE)) { unlinkSync(TEST_APP_PORT_FILE); } (global as Record<string, unknown>).__TAURI_APP_STARTED = false; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hypothesi/mcp-server-tauri'

If you have feedback or need assistance with the MCP directory API, please join our Discord server