Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
167 lines
6.2 KiB
TypeScript
167 lines
6.2 KiB
TypeScript
/**
|
|
* Global setup for Playwright tests in EE server
|
|
* This runs once before all tests and handles global initialization
|
|
*/
|
|
import dotenv from 'dotenv';
|
|
import path from 'path';
|
|
import { execSync } from 'child_process';
|
|
import fs from 'node:fs';
|
|
import { applyPlaywrightDatabaseEnv, PLAYWRIGHT_DB_CONFIG } from './src/__tests__/integration/utils/playwrightDatabaseConfig';
|
|
import os from 'node:os';
|
|
|
|
async function waitForHttpOk(url: string, timeoutMs: number): Promise<void> {
|
|
const deadline = Date.now() + timeoutMs;
|
|
let lastError: unknown;
|
|
|
|
while (Date.now() < deadline) {
|
|
try {
|
|
const response = await fetch(url, { method: 'GET' });
|
|
if (response.ok) return;
|
|
lastError = new Error(`HTTP ${response.status}`);
|
|
} catch (error) {
|
|
lastError = error;
|
|
}
|
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
}
|
|
|
|
throw new Error(`Timed out waiting for ${url}: ${String((lastError as any)?.message ?? lastError ?? 'unknown error')}`);
|
|
}
|
|
|
|
const MINIO_CONTAINER_NAME = 'alga-psa-minio-test';
|
|
const MINIO_OWNERSHIP_MARKER = path.resolve(__dirname, '.playwright', 'minio-owned');
|
|
|
|
function ensurePlaywrightStateDir() {
|
|
const dir = path.dirname(MINIO_OWNERSHIP_MARKER);
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
|
|
function containerExists(name: string): boolean {
|
|
try {
|
|
execSync(`docker inspect ${name}`, { stdio: 'ignore' });
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function containerRunning(name: string): boolean {
|
|
try {
|
|
const out = execSync(`docker inspect -f "{{.State.Running}}" ${name}`, { encoding: 'utf-8' }).trim();
|
|
return out === 'true';
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function globalSetup() {
|
|
console.log('🚀 Starting Playwright global setup...');
|
|
|
|
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
|
|
applyPlaywrightDatabaseEnv();
|
|
|
|
process.env.NODE_ENV = process.env.NODE_ENV || 'test';
|
|
process.env.NEXT_PUBLIC_DISABLE_FEATURE_FLAGS = process.env.NEXT_PUBLIC_DISABLE_FEATURE_FLAGS ?? 'true';
|
|
process.env.ALGA_AUTH_KEY = process.env.ALGA_AUTH_KEY || '17e412b643525944dc1db02871c1b5dc93972f3c2147b9a9446e104b7495272b';
|
|
|
|
// Set MinIO/S3 environment variables for test helpers
|
|
process.env.STORAGE_DEFAULT_PROVIDER = 's3'; // Use S3/MinIO for tests instead of local storage
|
|
process.env.STORAGE_S3_ENDPOINT = process.env.STORAGE_S3_ENDPOINT || 'http://localhost:9002';
|
|
process.env.STORAGE_S3_ACCESS_KEY = process.env.STORAGE_S3_ACCESS_KEY || 'minioadmin';
|
|
process.env.STORAGE_S3_SECRET_KEY = process.env.STORAGE_S3_SECRET_KEY || 'minioadmin';
|
|
process.env.STORAGE_S3_BUCKET = process.env.STORAGE_S3_BUCKET || 'alga-test';
|
|
process.env.STORAGE_S3_REGION = process.env.STORAGE_S3_REGION || 'us-east-1';
|
|
process.env.STORAGE_S3_FORCE_PATH_STYLE = process.env.STORAGE_S3_FORCE_PATH_STYLE || 'true';
|
|
|
|
if (!process.env.TEST_DATABASE_URL) {
|
|
process.env.TEST_DATABASE_URL = `postgresql://${PLAYWRIGHT_DB_CONFIG.appUser}:${PLAYWRIGHT_DB_CONFIG.appPassword}@${PLAYWRIGHT_DB_CONFIG.host}:${PLAYWRIGHT_DB_CONFIG.port}/${PLAYWRIGHT_DB_CONFIG.database}`;
|
|
}
|
|
|
|
// DB reset is handled by webServer.command (bootstrap script) once per session.
|
|
|
|
// Start test MinIO container (on port 9002, separate from Payload MinIO on 9000)
|
|
console.log('🗄️ Starting test MinIO container on port 9002...');
|
|
try {
|
|
const projectRoot = path.resolve(__dirname, '../..');
|
|
ensurePlaywrightStateDir();
|
|
|
|
const existed = containerExists(MINIO_CONTAINER_NAME);
|
|
if (!existed) {
|
|
try {
|
|
execSync('docker compose -f docker-compose.playwright.yml up -d', {
|
|
cwd: projectRoot,
|
|
stdio: 'inherit',
|
|
});
|
|
fs.writeFileSync(MINIO_OWNERSHIP_MARKER, 'owned\n', { encoding: 'utf-8' });
|
|
} catch (e) {
|
|
// Race-safe: another process may have created the shared container after our check.
|
|
if (containerExists(MINIO_CONTAINER_NAME)) {
|
|
try {
|
|
fs.unlinkSync(MINIO_OWNERSHIP_MARKER);
|
|
} catch {
|
|
// ignore
|
|
}
|
|
if (!containerRunning(MINIO_CONTAINER_NAME)) {
|
|
execSync(`docker start ${MINIO_CONTAINER_NAME}`, { stdio: 'inherit' });
|
|
}
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
} else {
|
|
// If another worktree already created the shared MinIO container, reuse it.
|
|
// Avoid docker compose here because docker-compose.playwright.yml uses fixed container_name.
|
|
if (!containerRunning(MINIO_CONTAINER_NAME)) {
|
|
execSync(`docker start ${MINIO_CONTAINER_NAME}`, { stdio: 'inherit' });
|
|
}
|
|
try {
|
|
fs.unlinkSync(MINIO_OWNERSHIP_MARKER);
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
// Wait for MinIO to be ready (host-published port 9002)
|
|
console.log('⏳ Waiting for MinIO to be ready...');
|
|
await waitForHttpOk('http://localhost:9002/minio/health/ready', 60_000);
|
|
|
|
// Create test bucket
|
|
// Use the dedicated mc image (minio/minio does not reliably ship mc).
|
|
// Note: minio/mc does not include a shell; its entrypoint is `mc`.
|
|
// Also: alias config does not persist across containers unless we share the config dir.
|
|
const mcConfigDir = fs.mkdtempSync(path.join(os.tmpdir(), 'alga-playwright-mc-'));
|
|
execSync(
|
|
[
|
|
'docker run --rm',
|
|
'--network alga-psa-playwright-test',
|
|
`-v "${mcConfigDir}:/root/.mc"`,
|
|
'minio/mc:latest',
|
|
'alias set local http://minio-test:9000 minioadmin minioadmin',
|
|
].join(' '),
|
|
{ cwd: projectRoot, stdio: 'inherit' }
|
|
);
|
|
execSync(
|
|
[
|
|
'docker run --rm',
|
|
'--network alga-psa-playwright-test',
|
|
`-v "${mcConfigDir}:/root/.mc"`,
|
|
'minio/mc:latest',
|
|
'mb local/alga-test --ignore-existing',
|
|
].join(' '),
|
|
{ cwd: projectRoot, stdio: 'inherit' }
|
|
);
|
|
|
|
console.log('✅ MinIO test container ready on port 9002');
|
|
} catch (error) {
|
|
console.error('❌ Failed to start MinIO container:', error);
|
|
throw error;
|
|
}
|
|
|
|
console.log('✅ Playwright test environment configured');
|
|
console.log(` - Database: ${PLAYWRIGHT_DB_CONFIG.host}:${PLAYWRIGHT_DB_CONFIG.port}/${PLAYWRIGHT_DB_CONFIG.database}`);
|
|
console.log(` - User: ${PLAYWRIGHT_DB_CONFIG.appUser}`);
|
|
console.log(` - MinIO: http://localhost:9002 (test instance, separate from Payload)`);
|
|
}
|
|
|
|
export default globalSetup;
|