Skip to main content
Version: 2x

Environment Management

Most projects need to run tests against multiple environments — local, staging, and production — with different URLs, credentials, and browser settings. qavajs provides several complementary mechanisms to handle this.

Config Profiles

The simplest approach is to export multiple named profiles from one config file:

// config.ts
import App from './page_object';
import { DevMemory, StagingMemory, ProdMemory } from './memory';

export default {
// local development
paths: ['features/**/*.feature'],
require: ['node_modules/@qavajs/steps-playwright/index.js', 'step_definitions/**/*.ts'],
format: ['@qavajs/console-formatter'],
parallel: 1,
defaultTimeout: 30000,
browser: { capabilities: { browserName: 'chromium' } },
pageObject: new App(),
memory: new DevMemory()
}

export const staging = {
paths: ['features/**/*.feature'],
require: ['node_modules/@qavajs/steps-playwright/index.js', 'step_definitions/**/*.ts'],
format: ['@qavajs/console-formatter', ['@qavajs/html-formatter', 'reports/report.html']],
parallel: 4,
defaultTimeout: 60000,
browser: { capabilities: { browserName: 'chromium' } },
pageObject: new App(),
memory: new StagingMemory()
}

export const production = {
paths: ['features/smoke/**/*.feature'],
require: ['node_modules/@qavajs/steps-playwright/index.js', 'step_definitions/**/*.ts'],
format: ['@qavajs/console-formatter', ['junit', 'reports/junit.xml']],
parallel: 2,
defaultTimeout: 60000,
browser: { capabilities: { browserName: 'chromium' } },
pageObject: new App(),
memory: new ProdMemory()
}

Run with:

npx qavajs run --profile staging
npx qavajs run --profile production

Environment-Specific Memory

Each environment's Memory class holds its own URLs and credentials:

// memory/index.ts
export class DevMemory {
baseUrl = 'http://localhost:3000';
apiUrl = 'http://localhost:4000';
username = 'dev-user';
password = 'dev-password';
}

export class StagingMemory {
baseUrl = 'https://staging.myapp.com';
apiUrl = 'https://api.staging.myapp.com';
username = process.env.STAGING_USER!;
password = process.env.STAGING_PASSWORD!;
}

export class ProdMemory {
baseUrl = 'https://myapp.com';
apiUrl = 'https://api.myapp.com';
username = process.env.PROD_USER!;
password = process.env.PROD_PASSWORD!;
}

Using dotenv

For secrets that should not live in source code, use dotenv to load them from .env files.

Install:

npm install dotenv

Create environment-specific .env files (add all to .gitignore):

# .env.staging
STAGING_USER=testuser
STAGING_PASSWORD=secret123
BASE_URL=https://staging.myapp.com

Load in your config:

import 'dotenv/config'; // loads .env
// or for a named file:
import dotenv from 'dotenv';
dotenv.config({ path: '.env.staging' });

export const staging = {
// ...
memory: new StagingMemory() // reads process.env.STAGING_USER etc.
}

Overriding Memory Values at Runtime

Pass a JSON object via --memory-values to override any memory key without editing files:

npx qavajs run --config config.ts --memory-values '{"baseUrl": "https://staging.myapp.com"}'

This is useful for one-off runs or overriding a single value in CI without creating a new profile.

Environment Variables in CI

In CI pipelines, inject secrets as environment variables and read them in your memory class:

export class Memory {
baseUrl = process.env.BASE_URL ?? 'http://localhost:3000';
apiKey = process.env.API_KEY ?? '';
}

GitHub Actions example:

- name: Run tests
run: npx qavajs run --profile ci
env:
BASE_URL: ${{ secrets.STAGING_URL }}
API_KEY: ${{ secrets.API_KEY }}

Selecting Environment from CLI Without Profiles

If you prefer a single config that reads from a single environment variable:

// config.ts
import App from './page_object';
import { DevMemory, StagingMemory, ProdMemory } from './memory';

const memoryMap = {
dev: new DevMemory(),
staging: new StagingMemory(),
production: new ProdMemory()
};

const env = (process.env.TEST_ENV ?? 'dev') as keyof typeof memoryMap;

export default {
// ...
memory: memoryMap[env]
}
TEST_ENV=staging npx qavajs run

Summary

ApproachBest for
Config profilesDistinct configs with different formatters and parallelism
Environment-specific MemoryDifferent URLs and credentials per environment
dotenvLocal secrets not committed to source control
--memory-valuesOne-off overrides on the command line
process.env in MemoryCI/CD secret injection