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
460 lines
20 KiB
TypeScript
460 lines
20 KiB
TypeScript
import { defineConfig, devices } from '@playwright/test';
|
|
import dotenv from 'dotenv';
|
|
import { spawnSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import path from 'path';
|
|
import { applyPlaywrightDatabaseEnv } from './src/__tests__/integration/utils/playwrightDatabaseConfig';
|
|
|
|
function loadPlaywrightEnv(): string | null {
|
|
const candidates = ['.env', '.env.test', '.env.example']
|
|
.map((filename) => path.resolve(__dirname, filename))
|
|
.filter((candidate) => fs.existsSync(candidate));
|
|
|
|
const selected = candidates[0] ?? null;
|
|
if (!selected) {
|
|
console.warn(`[Playwright] couldn't find env file: ${path.resolve(__dirname, '.env')}`);
|
|
return null;
|
|
}
|
|
|
|
dotenv.config({ path: selected });
|
|
return selected;
|
|
}
|
|
|
|
loadPlaywrightEnv();
|
|
const dockerComposeEnvFile = fs.existsSync(path.resolve(__dirname, '.env'))
|
|
? 'ee/server/.env'
|
|
: 'ee/server/.env.test';
|
|
|
|
// Playwright runs should be self-contained and must not depend on developer filesystem secrets.
|
|
// Playwright runs should be self-contained. Use an isolated filesystem-backed tenant secret store
|
|
// (env provider is read-only and cannot persist per-tenant configuration like integrations).
|
|
process.env.SECRET_READ_CHAIN = process.env.SECRET_READ_CHAIN || 'filesystem,env';
|
|
process.env.SECRET_WRITE_PROVIDER = process.env.SECRET_WRITE_PROVIDER || 'filesystem';
|
|
process.env.SECRET_FS_BASE_PATH = process.env.SECRET_FS_BASE_PATH || 'secrets-playwright';
|
|
process.env.PLAYWRIGHT_FAKE_GOOGLE_OAUTH = process.env.PLAYWRIGHT_FAKE_GOOGLE_OAUTH || 'true';
|
|
process.env.NEXT_PUBLIC_PLAYWRIGHT_FAKE_GOOGLE_OAUTH =
|
|
process.env.NEXT_PUBLIC_PLAYWRIGHT_FAKE_GOOGLE_OAUTH || 'true';
|
|
process.env.GOOGLE_OAUTH_CLIENT_ID = process.env.GOOGLE_OAUTH_CLIENT_ID || 'playwright-google-client-id';
|
|
process.env.GOOGLE_OAUTH_CLIENT_SECRET = process.env.GOOGLE_OAUTH_CLIENT_SECRET || 'playwright-google-client-secret';
|
|
|
|
// Don't set STORAGE_LOCAL_BASE_PATH - we want to use MinIO for tests
|
|
// const storageBasePath = path.resolve(__dirname, 'playwright-storage');
|
|
// if (!fs.existsSync(storageBasePath)) {
|
|
// fs.mkdirSync(storageBasePath, { recursive: true });
|
|
// }
|
|
// process.env.STORAGE_LOCAL_BASE_PATH = process.env.STORAGE_LOCAL_BASE_PATH || storageBasePath;
|
|
|
|
// If Postgres runs in Docker and is published to a different host/port,
|
|
// override the Playwright DB connection to hit the direct Postgres port instead
|
|
// of PgBouncer.
|
|
//
|
|
// IMPORTANT: Do not fall back to DB_HOST/DB_PORT from `ee/server/.env` here.
|
|
// That file is a developer runtime env and may use non-default ports; Playwright
|
|
// should be self-contained and only deviate from defaults when explicitly configured.
|
|
const directDbHost =
|
|
process.env.DB_DIRECT_HOST ||
|
|
process.env.PLAYWRIGHT_DB_HOST ||
|
|
process.env.EXPOSE_DB_HOST ||
|
|
'localhost';
|
|
const directDbPort =
|
|
process.env.DB_DIRECT_PORT ||
|
|
process.env.PLAYWRIGHT_DB_PORT ||
|
|
process.env.EXPOSE_DB_PORT ||
|
|
'5432';
|
|
|
|
process.env.DB_DIRECT_HOST = process.env.DB_DIRECT_HOST || directDbHost;
|
|
process.env.DB_DIRECT_PORT = process.env.DB_DIRECT_PORT || directDbPort;
|
|
|
|
process.env.PLAYWRIGHT_DB_HOST = process.env.PLAYWRIGHT_DB_HOST || directDbHost;
|
|
process.env.PLAYWRIGHT_DB_PORT = process.env.PLAYWRIGHT_DB_PORT || directDbPort;
|
|
|
|
// Playwright runs should be deterministic and not inherit a developer's NODE_ENV,
|
|
// since it affects auth cookie naming and other runtime branches.
|
|
process.env.NODE_ENV = 'test';
|
|
|
|
function runPortProbe(start: number, span: number, strict: boolean): { success: boolean; port?: number; error?: string } {
|
|
const script = `const net = require('net');
|
|
const start = Number(process.argv[1]);
|
|
const attempts = Number(process.argv[2]);
|
|
const strictMode = process.argv[3] === 'strict';
|
|
if (!Number.isFinite(start)) {
|
|
console.error('invalid-port');
|
|
process.exit(2);
|
|
}
|
|
function tryPort(port, attemptsLeft) {
|
|
const server = net.createServer();
|
|
server.unref();
|
|
server.once('error', (err) => {
|
|
if (strictMode || attemptsLeft <= 0) {
|
|
console.error(err && err.code ? err.code : 'EADDRINUSE');
|
|
process.exit(1);
|
|
}
|
|
tryPort(port + 1, attemptsLeft - 1);
|
|
});
|
|
server.listen(port, () => {
|
|
server.close(() => {
|
|
process.stdout.write(String(port));
|
|
process.exit(0);
|
|
});
|
|
});
|
|
}
|
|
tryPort(start, attempts);
|
|
`;
|
|
|
|
const result = spawnSync(process.execPath, ['--input-type=commonjs', '-e', script, String(start), String(span), strict ? 'strict' : 'flex'], {
|
|
encoding: 'utf-8',
|
|
});
|
|
|
|
if (result.status === 0 && result.stdout) {
|
|
return { success: true, port: Number(result.stdout.trim()) };
|
|
}
|
|
|
|
const error = (result.stderr || result.error?.message || '').trim();
|
|
return { success: false, error: error || 'port-probe-failed' };
|
|
}
|
|
|
|
function isPortProbePermissionError(error?: string): boolean {
|
|
if (!error) return false;
|
|
const normalized = error.trim().toUpperCase();
|
|
// Some sandboxed environments forbid binding/listening, causing EPERM/EACCES.
|
|
return normalized.includes('EPERM') || normalized.includes('EACCES');
|
|
}
|
|
|
|
function resolveWebPortSync(): number {
|
|
const preferred = Number(process.env.PLAYWRIGHT_APP_PORT || process.env.APP_PORT || 3300);
|
|
if (process.env.PLAYWRIGHT_APP_PORT_LOCKED === 'true' && process.env.PLAYWRIGHT_APP_PORT) {
|
|
if (!Number.isFinite(preferred)) {
|
|
throw new Error(`Invalid PLAYWRIGHT_APP_PORT value: ${process.env.PLAYWRIGHT_APP_PORT}`);
|
|
}
|
|
return preferred;
|
|
}
|
|
if (process.env.PLAYWRIGHT_APP_PORT) {
|
|
if (!Number.isFinite(preferred)) {
|
|
throw new Error(`Invalid PLAYWRIGHT_APP_PORT value: ${process.env.PLAYWRIGHT_APP_PORT}`);
|
|
}
|
|
const check = runPortProbe(preferred, 0, true);
|
|
if (!check.success || typeof check.port !== 'number') {
|
|
if (isPortProbePermissionError(check.error)) {
|
|
console.warn(`[Playwright] Port probe blocked (${check.error}); using PLAYWRIGHT_APP_PORT=${preferred} without validation.`);
|
|
return preferred;
|
|
}
|
|
// Even if a preferred port is provided, fall back to scanning for a nearby
|
|
// available port to avoid spurious failures when developers have multiple
|
|
// environments running locally.
|
|
const fallback = runPortProbe(preferred, 25, false);
|
|
if (!fallback.success || typeof fallback.port !== 'number') {
|
|
throw new Error(`PLAYWRIGHT_APP_PORT=${preferred} is unavailable (${check.error || 'unknown error'}).`);
|
|
}
|
|
return fallback.port;
|
|
}
|
|
return check.port;
|
|
}
|
|
|
|
const probe = runPortProbe(preferred, 25, false);
|
|
if (!probe.success || typeof probe.port !== 'number') {
|
|
if (isPortProbePermissionError(probe.error)) {
|
|
console.warn(`[Playwright] Port probe blocked (${probe.error}); defaulting to port ${preferred}.`);
|
|
return preferred;
|
|
}
|
|
throw new Error(`Unable to find an available port for the Playwright dev server (${probe.error || 'probe failed'}).`);
|
|
}
|
|
return probe.port;
|
|
}
|
|
|
|
function resolveServicePortSync(envVarName: string, fallbackPort: number): number {
|
|
const preferred = Number(process.env[envVarName] || fallbackPort);
|
|
if (!Number.isFinite(preferred)) {
|
|
throw new Error(`Invalid ${envVarName} value: ${process.env[envVarName]}`);
|
|
}
|
|
|
|
const lockedVarName = `${envVarName}_LOCKED`;
|
|
if (process.env[lockedVarName] === 'true') {
|
|
return preferred;
|
|
}
|
|
|
|
// If the preferred port is taken, scan forward for an available one (up to 25).
|
|
const probe = runPortProbe(preferred, 25, false);
|
|
if (!probe.success || typeof probe.port !== 'number') {
|
|
if (isPortProbePermissionError(probe.error)) {
|
|
console.warn(`[Playwright] Port probe blocked (${probe.error}); using ${envVarName}=${preferred} without validation.`);
|
|
return preferred;
|
|
}
|
|
throw new Error(`Unable to find an available port for ${envVarName} starting at ${preferred} (${probe.error || 'probe failed'}).`);
|
|
}
|
|
|
|
return probe.port;
|
|
}
|
|
|
|
const PORT_CACHE_KEY = Symbol.for('__ALGA_PLAYWRIGHT_PORT__');
|
|
|
|
function getCachedWebPort(): number {
|
|
const cached = globalThis[PORT_CACHE_KEY];
|
|
if (typeof cached === 'number' && Number.isFinite(cached)) {
|
|
return cached;
|
|
}
|
|
console.log('[Playwright] env before port detection', {
|
|
PLAYWRIGHT_APP_PORT: process.env.PLAYWRIGHT_APP_PORT,
|
|
APP_PORT: process.env.APP_PORT,
|
|
PORT: process.env.PORT,
|
|
});
|
|
const resolved = resolveWebPortSync();
|
|
globalThis[PORT_CACHE_KEY] = resolved;
|
|
console.log(`[Playwright] using dev server port ${resolved}`);
|
|
return resolved;
|
|
}
|
|
|
|
const resolvedWebPort = getCachedWebPort();
|
|
const webHost = process.env.PLAYWRIGHT_APP_HOST || 'localhost';
|
|
const resolvedBaseUrl = process.env.PLAYWRIGHT_BASE_URL || `http://${webHost}:${resolvedWebPort}`;
|
|
|
|
const resolvedHostForEnv = (() => {
|
|
try {
|
|
return new URL(resolvedBaseUrl).host;
|
|
} catch {
|
|
return `${webHost}:${resolvedWebPort}`;
|
|
}
|
|
})();
|
|
|
|
process.env.PLAYWRIGHT_APP_PORT = String(resolvedWebPort);
|
|
process.env.PLAYWRIGHT_APP_PORT_LOCKED = 'true';
|
|
process.env.HOST = process.env.HOST || resolvedHostForEnv;
|
|
process.env.APP_PORT = process.env.APP_PORT || String(resolvedWebPort);
|
|
process.env.EXPOSE_SERVER_PORT = process.env.EXPOSE_SERVER_PORT || String(resolvedWebPort);
|
|
process.env.PORT = process.env.PORT || String(resolvedWebPort);
|
|
|
|
// Reserve ports for dockerized Playwright deps (postgres/redis/worker).
|
|
const resolvedPlaywrightDbPort = resolveServicePortSync('PLAYWRIGHT_DB_PORT', Number(directDbPort || 5439));
|
|
process.env.PLAYWRIGHT_DB_PORT = String(resolvedPlaywrightDbPort);
|
|
process.env.PLAYWRIGHT_DB_PORT_LOCKED = 'true';
|
|
process.env.DB_DIRECT_PORT = String(resolvedPlaywrightDbPort);
|
|
process.env.PLAYWRIGHT_DB_PORT = String(resolvedPlaywrightDbPort);
|
|
|
|
const resolvedPlaywrightRedisPort = resolveServicePortSync('REDIS_PORT', Number(process.env.REDIS_PORT || 16379));
|
|
process.env.REDIS_PORT = String(resolvedPlaywrightRedisPort);
|
|
process.env.REDIS_PORT_LOCKED = 'true';
|
|
|
|
const resolvedPlaywrightHocuspocusPort = resolveServicePortSync(
|
|
'PLAYWRIGHT_HOCUSPOCUS_PORT',
|
|
Number(process.env.PLAYWRIGHT_HOCUSPOCUS_PORT || process.env.EXPOSE_HOCUSPOCUS_PORT || 1234)
|
|
);
|
|
process.env.PLAYWRIGHT_HOCUSPOCUS_PORT = String(resolvedPlaywrightHocuspocusPort);
|
|
process.env.PLAYWRIGHT_HOCUSPOCUS_PORT_LOCKED = 'true';
|
|
process.env.EXPOSE_HOCUSPOCUS_PORT = String(resolvedPlaywrightHocuspocusPort);
|
|
process.env.NEXT_PUBLIC_HOCUSPOCUS_URL =
|
|
process.env.NEXT_PUBLIC_HOCUSPOCUS_URL || `ws://localhost:${resolvedPlaywrightHocuspocusPort}`;
|
|
process.env.HOCUSPOCUS_JWT_SECRET =
|
|
process.env.HOCUSPOCUS_JWT_SECRET || 'dev-hocuspocus-jwt-secret';
|
|
process.env.REDIS_PASSWORD = process.env.REDIS_PASSWORD || 'sebastian123';
|
|
|
|
const skipWorkflowWorker = parseTruthyEnv(process.env.PLAYWRIGHT_SKIP_WORKFLOW_WORKER);
|
|
|
|
// Apply Playwright-specific database configuration (after port resolution).
|
|
applyPlaywrightDatabaseEnv();
|
|
|
|
function parseTruthyEnv(value?: string): boolean {
|
|
if (!value) return false;
|
|
const normalized = value.trim().toLowerCase();
|
|
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'y' || normalized === 'on';
|
|
}
|
|
|
|
// Decide whether Playwright should manage starting the dev server.
|
|
// - In CI, some pipelines start the server externally and only want tests to connect.
|
|
// - However, if no explicit base URL is provided, disabling webServer causes hard-to-debug ECONNREFUSED.
|
|
const explicitBaseUrlProvided = Boolean(
|
|
process.env.PLAYWRIGHT_BASE_URL || process.env.EE_BASE_URL || process.env.NEXTAUTH_URL
|
|
);
|
|
const isCi = parseTruthyEnv(process.env.CI);
|
|
const shouldRunWebServer =
|
|
process.env.PW_WEBSERVER === 'true'
|
|
? true
|
|
: process.env.PW_WEBSERVER === 'false'
|
|
? false
|
|
: !(isCi && explicitBaseUrlProvided);
|
|
|
|
// If Playwright is managing the dev server, make the computed base URL authoritative.
|
|
// This avoids a mismatch where an env file sets EE_BASE_URL/NEXTAUTH_URL to a different port.
|
|
if (shouldRunWebServer && !process.env.PLAYWRIGHT_BASE_URL) {
|
|
process.env.EE_BASE_URL = resolvedBaseUrl;
|
|
process.env.NEXTAUTH_URL = resolvedBaseUrl;
|
|
} else {
|
|
process.env.EE_BASE_URL = process.env.EE_BASE_URL || resolvedBaseUrl;
|
|
process.env.NEXTAUTH_URL = process.env.NEXTAUTH_URL || resolvedBaseUrl;
|
|
}
|
|
|
|
console.log('[Playwright] webServer', {
|
|
CI: process.env.CI,
|
|
isCi,
|
|
explicitBaseUrlProvided,
|
|
shouldRunWebServer,
|
|
resolvedBaseUrl,
|
|
EE_BASE_URL: process.env.EE_BASE_URL,
|
|
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
|
|
});
|
|
|
|
/**
|
|
* Playwright configuration for EE server integration tests
|
|
* @see https://playwright.dev/docs/test-configuration
|
|
*/
|
|
export default defineConfig({
|
|
testDir: './src/__tests__/integration',
|
|
// Run all Playwright integration tests in this folder
|
|
testMatch: ['**/*.playwright.test.ts'],
|
|
|
|
/* Global setup file */
|
|
globalSetup: './playwright.global-setup.ts',
|
|
|
|
/* Global teardown file */
|
|
globalTeardown: './playwright.global-teardown.ts',
|
|
|
|
/* Run tests in files in parallel */
|
|
fullyParallel: false, // Disabled for database isolation
|
|
|
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
|
forbidOnly: !!process.env.CI,
|
|
|
|
/* Retry control: CI default 2, local default 0, override with PW_RETRIES */
|
|
retries: process.env.PW_RETRIES !== undefined
|
|
? Number(process.env.PW_RETRIES)
|
|
: (process.env.CI ? 2 : 0),
|
|
|
|
/* Opt out of parallel tests on CI. */
|
|
workers: process.env.CI ? 1 : 1, // Single worker for database isolation
|
|
|
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
reporter: [
|
|
['list'],
|
|
['json', { outputFile: 'playwright-report/results.json' }],
|
|
['html', { open: 'never' }]
|
|
],
|
|
|
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
use: {
|
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
|
baseURL: resolvedBaseUrl,
|
|
|
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
trace: 'on-first-retry',
|
|
|
|
/* Take screenshot on failure */
|
|
screenshot: 'only-on-failure',
|
|
|
|
/* Record video on failure */
|
|
video: 'retain-on-failure',
|
|
|
|
/* Global test timeout */
|
|
actionTimeout: 15000,
|
|
navigationTimeout: 30000,
|
|
},
|
|
|
|
/* Configure projects for major browsers */
|
|
projects: [
|
|
{
|
|
name: 'chromium',
|
|
use: {
|
|
...devices['Desktop Chrome'],
|
|
launchOptions: {
|
|
headless: false,
|
|
args: [
|
|
'--host-resolver-rules=MAP portal.acme.local 127.0.0.1,MAP canonical.localhost 127.0.0.1,MAP localhost 127.0.0.1'
|
|
],
|
|
},
|
|
},
|
|
},
|
|
|
|
// Uncomment for cross-browser testing
|
|
// {
|
|
// name: 'firefox',
|
|
// use: { ...devices['Desktop Firefox'] },
|
|
// },
|
|
|
|
// {
|
|
// name: 'webkit',
|
|
// use: { ...devices['Desktop Safari'] },
|
|
// },
|
|
|
|
/* Test against mobile viewports. */
|
|
// {
|
|
// name: 'Mobile Chrome',
|
|
// use: { ...devices['Pixel 5'] },
|
|
// },
|
|
// {
|
|
// name: 'Mobile Safari',
|
|
// use: { ...devices['iPhone 12'] },
|
|
// },
|
|
],
|
|
|
|
/* Run your local dev server before starting the tests */
|
|
webServer: shouldRunWebServer ? {
|
|
// Reset DB once per session before starting the dev server.
|
|
command:
|
|
'cd ../../' +
|
|
` && PLAYWRIGHT_DB_PORT=${resolvedPlaywrightDbPort} REDIS_PORT=${resolvedPlaywrightRedisPort} PLAYWRIGHT_HOCUSPOCUS_PORT=${resolvedPlaywrightHocuspocusPort} REDIS_PASSWORD=${process.env.REDIS_PASSWORD} HOCUSPOCUS_JWT_SECRET=${process.env.HOCUSPOCUS_JWT_SECRET} docker compose -f docker-compose.playwright-workflow-deps.yml -p alga-psa-playwright-workflow --env-file ${dockerComposeEnvFile} up -d --wait --wait-timeout 60 postgres-playwright redis-playwright` +
|
|
' && node --import tsx/esm scripts/bootstrap-playwright-db.ts' +
|
|
(skipWorkflowWorker
|
|
? ` && PLAYWRIGHT_DB_PORT=${resolvedPlaywrightDbPort} REDIS_PORT=${resolvedPlaywrightRedisPort} PLAYWRIGHT_HOCUSPOCUS_PORT=${resolvedPlaywrightHocuspocusPort} REDIS_PASSWORD=${process.env.REDIS_PASSWORD} HOCUSPOCUS_JWT_SECRET=${process.env.HOCUSPOCUS_JWT_SECRET} docker compose -f docker-compose.playwright-workflow-deps.yml -p alga-psa-playwright-workflow --env-file ${dockerComposeEnvFile} up -d --build --wait --wait-timeout 120 hocuspocus-playwright`
|
|
: ` && PLAYWRIGHT_DB_PORT=${resolvedPlaywrightDbPort} REDIS_PORT=${resolvedPlaywrightRedisPort} PLAYWRIGHT_HOCUSPOCUS_PORT=${resolvedPlaywrightHocuspocusPort} REDIS_PASSWORD=${process.env.REDIS_PASSWORD} HOCUSPOCUS_JWT_SECRET=${process.env.HOCUSPOCUS_JWT_SECRET} docker compose -f docker-compose.playwright-workflow-deps.yml -p alga-psa-playwright-workflow --env-file ${dockerComposeEnvFile} up -d --build --wait --wait-timeout 120 workflow-worker-playwright hocuspocus-playwright`) +
|
|
' && NEXT_PUBLIC_EDITION=enterprise npm run dev',
|
|
url: resolvedBaseUrl,
|
|
// Default to starting a fresh server (we also need to bring up dockerized deps + reset the DB).
|
|
// Opt-in reuse with PW_REUSE=true for local iteration.
|
|
reuseExistingServer: process.env.PW_REUSE === 'true',
|
|
timeout: 300000,
|
|
stdout: 'pipe',
|
|
stderr: 'pipe',
|
|
env: {
|
|
...process.env,
|
|
// Use a writable filesystem secret store for tenant secrets; keep app secrets in env.
|
|
SECRET_READ_CHAIN: process.env.SECRET_READ_CHAIN || 'filesystem,env',
|
|
SECRET_WRITE_PROVIDER: process.env.SECRET_WRITE_PROVIDER || 'filesystem',
|
|
SECRET_FS_BASE_PATH: process.env.SECRET_FS_BASE_PATH || 'secrets-playwright',
|
|
NEXT_PUBLIC_EDITION: 'enterprise',
|
|
E2E_AUTH_BYPASS: 'true',
|
|
EE_BASE_URL: resolvedBaseUrl,
|
|
NEXTAUTH_URL: resolvedBaseUrl,
|
|
HOST: resolvedHostForEnv,
|
|
HOSTNAME: webHost,
|
|
PORT: String(resolvedWebPort),
|
|
APP_PORT: String(resolvedWebPort),
|
|
EXPOSE_SERVER_PORT: String(resolvedWebPort),
|
|
NEXT_PUBLIC_APP_URL: resolvedBaseUrl,
|
|
NEXT_PUBLIC_SITE_URL: resolvedBaseUrl,
|
|
NEXT_PUBLIC_API_BASE_URL: resolvedBaseUrl,
|
|
NEXT_PUBLIC_EXTERNAL_APP_URL: resolvedBaseUrl,
|
|
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET || 'test-nextauth-secret',
|
|
NEXT_PUBLIC_DISABLE_FEATURE_FLAGS: process.env.NEXT_PUBLIC_DISABLE_FEATURE_FLAGS ?? 'true',
|
|
NEXT_PUBLIC_HOCUSPOCUS_URL:
|
|
process.env.NEXT_PUBLIC_HOCUSPOCUS_URL || `ws://localhost:${resolvedPlaywrightHocuspocusPort}`,
|
|
HOCUSPOCUS_JWT_SECRET: process.env.HOCUSPOCUS_JWT_SECRET || 'dev-hocuspocus-jwt-secret',
|
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD || 'sebastian123',
|
|
// Explicitly set DB config for Playwright - override server/.env settings
|
|
DB_HOST: process.env.PLAYWRIGHT_DB_HOST || process.env.DB_HOST || 'localhost',
|
|
DB_PORT: process.env.PLAYWRIGHT_DB_PORT || process.env.DB_PORT || '5439',
|
|
DB_NAME: process.env.PLAYWRIGHT_DB_NAME || process.env.DB_NAME || 'alga_contract_wizard_test',
|
|
DB_NAME_SERVER: process.env.PLAYWRIGHT_DB_NAME || process.env.DB_NAME_SERVER || 'alga_contract_wizard_test',
|
|
DB_USER: process.env.PLAYWRIGHT_DB_ADMIN_USER || process.env.DB_USER || 'postgres',
|
|
DB_PASSWORD: process.env.PLAYWRIGHT_DB_ADMIN_PASSWORD || process.env.DB_PASSWORD || '',
|
|
DB_USER_SERVER: process.env.PLAYWRIGHT_DB_ADMIN_USER || process.env.DB_USER_SERVER || 'postgres',
|
|
DB_PASSWORD_SERVER: process.env.PLAYWRIGHT_DB_ADMIN_PASSWORD || process.env.DB_PASSWORD_SERVER || '',
|
|
DB_PASSWORD_ADMIN: process.env.PLAYWRIGHT_DB_ADMIN_PASSWORD || process.env.DB_PASSWORD_ADMIN || '',
|
|
// Use S3/MinIO for file uploads (not local storage)
|
|
// MinIO test instance runs on port 9002 (separate from Payload MinIO on 9000)
|
|
STORAGE_DEFAULT_PROVIDER: 's3', // Use S3/MinIO instead of local storage
|
|
STORAGE_S3_ENDPOINT: process.env.STORAGE_S3_ENDPOINT || 'http://localhost:9002',
|
|
STORAGE_S3_ACCESS_KEY: process.env.STORAGE_S3_ACCESS_KEY || 'minioadmin',
|
|
STORAGE_S3_SECRET_KEY: process.env.STORAGE_S3_SECRET_KEY || 'minioadmin',
|
|
STORAGE_S3_BUCKET: process.env.STORAGE_S3_BUCKET || 'alga-test',
|
|
STORAGE_S3_REGION: process.env.STORAGE_S3_REGION || 'us-east-1',
|
|
STORAGE_S3_FORCE_PATH_STYLE: process.env.STORAGE_S3_FORCE_PATH_STYLE || 'true',
|
|
// Redis is required for the event bus; prefer a local instance for Playwright.
|
|
REDIS_HOST: process.env.REDIS_HOST || 'localhost',
|
|
REDIS_PORT: process.env.REDIS_PORT || '6379',
|
|
}
|
|
} : undefined,
|
|
|
|
/* Global test timeout */
|
|
timeout: 60000,
|
|
|
|
/* Test output directory */
|
|
outputDir: 'playwright-test-results/',
|
|
});
|