fix test docker

This commit is contained in:
fuomag9
2026-03-07 02:08:21 +01:00
parent 3572b482e8
commit 77e9a7d2f1
2 changed files with 38 additions and 21 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
services:
web:
environment:
SESSION_SECRET: "test-session-secret-32chars!xxx"
SESSION_SECRET: "test-session-secret-32chars!xxxY"
ADMIN_USERNAME: testadmin
ADMIN_PASSWORD: "TestPassword2026!"
BASE_URL: http://localhost:3000
+37 -20
View File
@@ -1,4 +1,4 @@
import { execFileSync } from 'node:child_process';
import { execFileSync, execFileSync as runCmd } from 'node:child_process';
import { mkdirSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
@@ -10,41 +10,53 @@ const COMPOSE_ARGS = [
const HEALTH_URL = 'http://localhost:3000/api/health';
const AUTH_DIR = resolve(process.cwd(), 'tests/.auth');
const AUTH_FILE = resolve(AUTH_DIR, 'admin.json');
const MAX_WAIT_MS = 120_000;
const POLL_INTERVAL_MS = 2_000;
const MAX_WAIT_MS = 180_000;
const POLL_INTERVAL_MS = 3_000;
async function waitForHealth(): Promise<void> {
const start = Date.now();
let attempt = 0;
while (Date.now() - start < MAX_WAIT_MS) {
attempt++;
try {
const res = await fetch(HEALTH_URL);
if (res.status === 200) {
console.log('[global-setup] App is healthy');
console.log(`[global-setup] App is healthy (attempt ${attempt})`);
return;
}
} catch {
// not ready yet
console.log(`[global-setup] Health check attempt ${attempt}: HTTP ${res.status}, retrying...`);
} catch (err: unknown) {
const msg = err instanceof Error ? err.message : String(err);
console.log(`[global-setup] Health check attempt ${attempt}: ${msg}, retrying in ${POLL_INTERVAL_MS / 1000}s...`);
}
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
}
// Dump container logs to help diagnose the failure
console.error('[global-setup] Health check timed out. Container logs:');
try {
execFileSync('docker', [...COMPOSE_ARGS, 'logs', '--tail=50'], { stdio: 'inherit', cwd: process.cwd() });
} catch { /* ignore */ }
throw new Error(`App did not become healthy within ${MAX_WAIT_MS}ms`);
}
async function seedAuthState(): Promise<void> {
// Navigate via the web login form to get a real session cookie.
// The app uses credentials-based NextAuth signin.
// We POST to the credentials callback directly.
const callbackUrl = 'http://localhost:3000';
console.log('[global-setup] Seeding auth state...');
// First, get CSRF token from NextAuth
// Get CSRF token from NextAuth
const csrfRes = await fetch('http://localhost:3000/api/auth/csrf');
if (!csrfRes.ok) {
throw new Error(`CSRF request failed: ${csrfRes.status}`);
}
const csrfData = await csrfRes.json() as { csrfToken: string };
console.log('[global-setup] Got CSRF token');
const params = new URLSearchParams({
csrfToken: csrfData.csrfToken,
username: 'testadmin',
password: 'TestPassword2026!',
callbackUrl,
password: 'TestPassword2026!', // matches ADMIN_PASSWORD in docker-compose.test.yml
callbackUrl: 'http://localhost:3000',
json: 'true',
});
@@ -58,7 +70,9 @@ async function seedAuthState(): Promise<void> {
redirect: 'manual',
});
// Collect all cookies from both responses
console.log(`[global-setup] Sign-in response: HTTP ${signinRes.status}`);
// Collect cookies from both responses
const allCookieHeaders: string[] = [];
for (const [k, v] of csrfRes.headers.entries()) {
if (k === 'set-cookie') allCookieHeaders.push(v);
@@ -94,23 +108,26 @@ async function seedAuthState(): Promise<void> {
}).filter(Boolean)
);
const storageState = {
cookies,
origins: [],
};
console.log(`[global-setup] Collected ${cookies.length} cookies`);
const storageState = { cookies, origins: [] };
mkdirSync(AUTH_DIR, { recursive: true });
writeFileSync(AUTH_FILE, JSON.stringify(storageState, null, 2));
console.log('[global-setup] Auth state seeded at', AUTH_FILE);
console.log('[global-setup] Auth state saved to', AUTH_FILE);
}
export default async function globalSetup() {
console.log('[global-setup] Starting Docker Compose test stack...');
execFileSync('docker', [...COMPOSE_ARGS, 'up', '-d', '--build'], {
execFileSync('docker', [
...COMPOSE_ARGS,
'up', '-d', '--build',
'--wait', '--wait-timeout', '120',
], {
stdio: 'inherit',
cwd: process.cwd(),
});
console.log('[global-setup] Containers up. Waiting for /api/health...');
await waitForHealth();
await seedAuthState();