import * as fs from 'fs'; import * as path from 'path'; // Loads KEY=VALUE pairs from a local .env-style file into process.env, // without overwriting anything already set (real env vars / CI secrets // always win over the file). No external dependency needed for this - the // format is simple enough to parse directly. function loadLocalEnvFile(filePath: string): void { if (!fs.existsSync(filePath)) return; const content = fs.readFileSync(filePath, 'utf-8'); for (const rawLine of content.split('\n')) { const line = rawLine.trim(); if (!line || line.startsWith('#')) continue; const eqIdx = line.indexOf('='); if (eqIdx === -1) continue; const key = line.slice(0, eqIdx).trim(); let value = line.slice(eqIdx + 1).trim(); if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { value = value.slice(1, -1); } if (key && process.env[key] === undefined) { process.env[key] = value; } } } // .env.test.local is git-ignored (matches the existing `*.local` gitignore // pattern) - it holds real local credentials and is never required in CI, // where GitHub Secrets populate the same variable names directly. // Resolved from process.cwd() (not __dirname/import.meta.url) since this // project runs as an ES module, where __dirname isn't available - Playwright // and its config are always invoked from the project root anyway. loadLocalEnvFile(path.resolve(process.cwd(), '.env.test.local')); export type EnvName = 'dev' | 'staging' | 'production'; // Accepts both branch names (develop/staging/main - what CI sets ENV to, // since e2e-tests.yml derives it from github.ref_name) and semantic names // (dev/staging/production), so the same ENV value works whether it came // from a branch push or a manual `ENV=production npm run test:e2e:prod`. const ENV_ALIASES: Record = { develop: 'dev', dev: 'dev', development: 'dev', devpro: 'dev', local: 'dev', localenv: 'dev', staging: 'staging', stage: 'staging', main: 'production', production: 'production', prod: 'production', }; export function resolveEnvName(): EnvName { const raw = (process.env.ENV || 'develop').toLowerCase(); return ENV_ALIASES[raw] || 'dev'; } export interface EnvironmentConfig { envName: EnvName; baseURL: string; username: string; password: string; } export function getEnvironmentConfig(): EnvironmentConfig { const envName = resolveEnvName(); // dev and staging are genuinely separate deployments/branches - dev has // its own DEV_URL now (falls back to the old shared stagingenv URL if // DEV_URL isn't set, e.g. for local runs that haven't configured it yet). const baseURLs: Record = { dev: process.env.DEV_URL || 'https://stagingenv.babinnovations.com', staging: 'https://stagingenv.babinnovations.com', production: 'https://www.babinnovations.com/neopaas/portal', }; // dev prefers its own DEV_USERNAME/PASSWORD, falling back to the older // shared TEST_USERNAME/PASSWORD pair for compatibility with existing local // .env.test.local setups. Staging falls back to that same shared pair // unless STAGING_TEST_* is explicitly set. Production always requires its // own PROD_TEST_* pair. const credentials: Record = { dev: { username: process.env.DEV_USERNAME || process.env.TEST_USERNAME || '', password: process.env.DEV_PASSWORD || process.env.TEST_PASSWORD || '', }, staging: { username: process.env.STAGING_TEST_USERNAME || process.env.TEST_USERNAME || '', password: process.env.STAGING_TEST_PASSWORD || process.env.TEST_PASSWORD || '', }, production: { username: process.env.PROD_TEST_USERNAME || '', password: process.env.PROD_TEST_PASSWORD || '', }, }; return { envName, baseURL: process.env.BASE_URL || baseURLs[envName], username: credentials[envName].username, password: credentials[envName].password, }; }