Files
flyer-crawler.projectium.com/src/tests/setup/integration-global-setup.ts
Torben Sorensen 3a0e5124b3
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m30s
prod broken
2025-11-22 20:25:24 -08:00

80 lines
2.9 KiB
TypeScript

import { exec, ChildProcess } from 'child_process';
import { setup as globalSetup } from './global-setup';
import { pingBackend } from '../../services/apiClient';
import { logger } from '../../services/logger';
import { getPool } from '../../services/db/connection'; // Import getPool
let serverProcess: ChildProcess;
export async function setup() {
console.log('\n--- Running Integration Test Setup ---');
await globalSetup();
console.log('Starting backend server for integration tests...');
// Use the dedicated test server script, which correctly uses the .env.test file.
serverProcess = exec('npm run start:test');
// --- NEW LOGGING START ---
// Listen for premature exit to debug crashes immediately
serverProcess.on('exit', (code, signal) => {
if (code !== null && code !== 0) {
console.error(`\n[SERVER EXIT]: Backend server process exited prematurely with code ${code} and signal ${signal}`);
console.error('Check [SERVER STDERR] logs above for details.\n');
}
});
// --- NEW LOGGING END ---
serverProcess.stdout?.on('data', (data) => {
console.log(`[SERVER STDOUT]: ${data}`);
});
serverProcess.stderr?.on('data', (data) => {
console.error(`[SERVER STDERR]: ${data}`);
});
const maxRetries = 10;
const retryDelay = 1000;
for (let i = 0; i < maxRetries; i++) {
try {
// If the process has already died, stop waiting
if (serverProcess.exitCode !== null) {
throw new Error(`Server process exited with code ${serverProcess.exitCode}`);
}
if (await pingBackend()) {
console.log('✅ Backend server is running and responsive.');
return;
}
} catch (e) {
// Only log debug if we are still waiting, otherwise throw
if (serverProcess.exitCode !== null) throw e;
logger.debug('Ping failed while waiting for server, this is expected.', { error: e });
}
console.log(`Waiting for backend server... (attempt ${i + 1}/${maxRetries})`);
await new Promise(resolve => setTimeout(resolve, retryDelay));
}
console.error('🔴 Backend server did not start in time. Integration tests will likely fail.');
serverProcess.kill();
throw new Error('Backend server failed to start.');
}
export async function teardown() {
console.log('--- Integration Test Teardown ---');
// Close the database connection pool after all integration tests have run.
// This is the correct place to ensure all connections are closed gracefully.
const pool = getPool();
if (serverProcess) {
serverProcess.kill();
console.log('✅ Backend server process terminated.');
}
if (pool) {
// Check if the pool has any clients (total, idle, or waiting) before ending it.
// This is a safer, type-approved way to see if the pool was used, avoiding `any`.
if (pool.totalCount > 0 || pool.idleCount > 0 || pool.waitingCount > 0) {
await pool.end();
}
console.log('✅ Global database pool teardown complete.');
}
}