Files
tutortool/frontend/tests/global-setup.ts
s0wlz (Matthias Puchstein) 6cb5968b7b fix: resolve Docker build failure and E2E authentication race conditions
- Dockerfile: Update binary name from attendance to tutortool to fix the release build pipeline failure.
- Backend: Expose test_mode in AppState to conditionally disable the secure flag on auth cookies during local E2E testing over HTTP.
- Backend: Enable tower-http trace feature and attach TraceLayer for improved request logging.
- Frontend: Refactor auth.svelte.ts to a plain reactive object to resolve initialization race conditions during tests.
- Frontend: Append cache-busting timestamp to /api/auth/me to prevent stale session states.
- Frontend: Update Playwright locator in superadmin.spec.ts for greater resilience.
- Makefile: Inject required environment variables (STATIC_DIR, JWT_SECRET) into the test-up target.
2026-05-02 05:25:04 +02:00

61 lines
2.1 KiB
TypeScript

import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
async function globalSetup() {
// Read env vars written by scripts/test-env.sh (make test-up calls it first)
const envFile = path.resolve(__dirname, '../../data/test/.env');
if (!fs.existsSync(envFile)) {
throw new Error('data/test/.env not found — run "make test-up" first');
}
for (const line of fs.readFileSync(envFile, 'utf-8').split('\n')) {
const eq = line.indexOf('=');
if (eq > 0) process.env[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
}
const baseURL = process.env.TT_BASE_URL!;
// Obtain admin JWT via the login API
const res = await fetch(`${baseURL}/api/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'admin@tutortool.com', password: 'admin' }),
});
if (!res.ok) throw new Error(`Login failed: ${res.status} ${await res.text()}`);
// Extract token from Set-Cookie header
const setCookie = res.headers.get('set-cookie');
const tokenMatch = setCookie?.match(/token=([^;]+)/);
const token = tokenMatch ? tokenMatch[1] : '';
const { is_superadmin } = await res.json() as { is_superadmin: boolean };
// Write Playwright storage state with cookies pre-populated
const authDir = path.resolve(__dirname, '.auth');
fs.mkdirSync(authDir, { recursive: true });
const storageState = {
cookies: [
{
name: 'token',
value: token,
domain: new URL(baseURL).hostname,
path: '/',
httpOnly: true,
secure: baseURL.startsWith('https'),
sameSite: 'Strict' as const,
}
],
origins: [
{
origin: baseURL,
localStorage: [],
},
],
};
fs.writeFileSync(path.join(authDir, 'admin.json'), JSON.stringify(storageState, null, 2));
}
export default globalSetup;