98 lines
3.9 KiB
TypeScript
98 lines
3.9 KiB
TypeScript
|
|
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<string, EnvName> = {
|
||
|
|
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<EnvName, string> = {
|
||
|
|
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<EnvName, { username: string; password: string }> = {
|
||
|
|
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,
|
||
|
|
};
|
||
|
|
}
|