In Playwright, environment variables are used to configure test settings such as base URLs, credentials, and other environment-specific values. They enable dynamic test execution across different environments without modifying the test code, ensuring flexibility and scalability.
Overview
Managing environment variables efficiently is crucial for scalable and secure Playwright test automation. By leveraging environment variables, teams can easily configure and switch between different environments, ensuring flexibility and scalability in their testing workflows.
Methods for Using Environment Variables in Playwright:
- .env Files: Store environment-specific variables in .env files and use the dotenv package to load them into Playwright tests.
- Process Environment (process.env): Access environment variables directly in your test code using process.env.VARIABLE_NAME.
- Playwright Config File: Define environment variables in playwright.config.ts to customize test configurations like base URL, credentials, etc.
- CI/CD Integration: Inject environment variables into tests via CI/CD tools (e.g., GitHub Actions, CircleCI) to securely manage different environments during automated testing.
- Command-Line Arguments: Pass environment variables when running Playwright tests via the command line, such as STAGING=true npx playwright test.
This article explores the importance of environment variables in Playwright, common methods for managing them, best practices, and advanced configurations for multi-environment orchestration.
Understanding Environment Variables
Environment variables are key-value pairs used to store configuration settings and sensitive data that an application or service needs to function. In the context of testing and automation, environment variables enable dynamic configuration of test settings without hardcoding values into the codebase.
They allow you to separate the configuration from the application logic, making it easier to switch between different environments (e.g., development, staging, production) without altering the source code.
In Playwright, environment variables are used to manage dynamic configurations, such as URLs, API keys, authentication credentials, and feature flags. By using environment variables, you can easily adjust test behaviors depending on the environment, ensuring that the same test code runs seamlessly in different stages of the deployment pipeline.
For example, instead of hardcoding a base URL for your application in the test script, you can use an environment variable like BASE_URL and load it dynamically based on the environment. This makes the tests more flexible, reusable, and secure, as sensitive data can be managed outside the codebase.
Why Environment Variables Are Critical in Playwright?
Environment variables play a vital role in Playwright test automation by offering flexibility, security, and scalability. Here are the key reasons why they are critical in Playwright:
- Environment Flexibility: They enable seamless switching between different environments (dev, staging, production) without altering test code, ensuring consistent test execution across all stages.
- Security: Sensitive data like API keys and credentials are stored in environment variables, reducing the risk of exposure in code and protecting critical information during test runs.
- Configurability: Environment variables externalize configurations like URLs and tokens, making it easy to adjust settings for different environments without code changes.
- Maintainability: Managing configurations through environment variables leads to cleaner, more maintainable tests by allowing updates to settings without modifying the code.
- Scalability: In large projects, environment variables enable scalable testing across multiple environments and configurations, simplifying automation in CI/CD pipelines.
By integrating environment variables into Playwright tests, teams can ensure a more robust, secure, and efficient testing workflow.
Common Approaches to Manage Environment Variables
There are several effective methods for managing environment variables in Playwright, each offering flexibility and security:
Using .env Files
The most common approach is to store environment-specific variables in .env files. Using the dotenv package, you can load these variables into your Playwright tests dynamically, keeping configuration separate from code. This allows for easy management of variables for different environments (e.g., .env.dev, .env.prod).
Process Environment (process.env)
Playwright allows direct access to environment variables using process.env.VARIABLE_NAME. This method lets you reference variables in your test scripts or configuration files, ensuring they adapt to the environment they are executed in without the need for hardcoding values.
CI/CD Integration
In modern testing workflows, environment variables are often injected during the CI/CD pipeline setup. Tools like GitHub Actions, CircleCI, and Jenkins allow you to securely pass environment variables as part of the pipeline, ensuring that sensitive information (like API keys and credentials) remains protected while being used in test runs.
Command-Line Arguments
Environment variables can also be passed directly via the command line when running Playwright tests. This is particularly useful for short-term overrides, such as specifying a different environment with a simple command like STAGING=true npx playwright test.
Playwright Configuration File
Variables can be accessed and utilized within the playwright.config.ts file, where you can define dynamic settings (like base URLs or retries) based on environment variables. This centralizes the configuration for multiple environments in one place.
Each approach provides a different level of control and flexibility, and often, a combination of these methods is used to manage environment variables effectively across different stages of test automation.
Read More: Web Scraping with Playwright
Setting Up Environment Variables in Playwright
Setting up environment variables in Playwright involves a few key steps to ensure your tests are dynamic and flexible across different environments. Here’s a simple guide to get started:
1. Install the dotenv Package
First, install the dotenv package, which helps load environment variables from a .env file into your Playwright configuration.
npm install dotenv
2. Create .env Files
Create a .env file in your project root directory. This file will store key-value pairs for your environment variables (e.g., BASE_URL, API_KEY). You can have different .env files for different environments like .env.dev, .env.prod, etc.
Example .env file:
BASE_URL=https://staging.example.com API_KEY=your_api_key_here
3. Load Environment Variables in playwright.config.ts
In your Playwright configuration file (playwright.config.ts), use the dotenv package to load the environment variables from the .env file.
import { defineConfig } from '@playwright/test';
import * as dotenv from 'dotenv';
// Load .env file
dotenv.config();
export default defineConfig({
use: {
baseURL: process.env.BASE_URL, // Accessing the environment variable
},
});4. Access Environment Variables in Tests
In your Playwright test files, you can access the environment variables using process.env. This allows you to dynamically load data based on the environment.
Example:
import { test, expect } from ‘@playwright/test’;
test(‘should load the correct base URL’, async ({ page }) => {
await page.goto(process.env.BASE_URL);
expect(page.url()).toBe(process.env.BASE_URL);
});
5. Using Environment Variables in CI/CD
In CI/CD pipelines, you can securely pass environment variables to Playwright tests without including them in .env files. For example, in GitHub Actions, you can set environment variables in the workflow YAML file:
jobs:
test:
runs-on: ubuntu-latest
env:
BASE_URL: ${{ secrets.BASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
By following these steps, you can set up environment variables in Playwright to handle different environments, manage sensitive data securely, and maintain scalable and maintainable test automation workflows.
Advanced Configuration: Playwright Projects and Multi-Environment Test Orchestration
Use Playwright Projects to model each target environment (dev/stage/prod) as a first-class config, then orchestrate them locally and in CI.
1. Project-per-environment config
Playwright, allowing each project to have its own environment setup, including browser/device settings and environment variables. Here’s how you can implement this using a project-per-environment approach:
// playwright.config.ts
import { defineConfig, devices } from ‘@playwright/test’;
import * as dotenv from ‘dotenv’;const ENV = process.env.ENV ?? ‘dev’;
dotenv.config({ path: `.env.${ENV}` }); // .env.dev | .env.staging | .env.prodfunction requireEnv(name: string) {
const v = process.env[name];
if (!v) throw new Error(`Missing env: ${name}`);
return v;
}export default defineConfig({
reporter: [[‘html’], [‘list’]],
timeout: 30_000,
projects: [
{
name: ‘chromium-dev’,
use: {
…devices[‘Desktop Chrome’],
baseURL: requireEnv(‘BASE_URL’),
httpCredentials: process.env.BASIC_AUTH_USER
? { username: requireEnv(‘BASIC_AUTH_USER’), password: requireEnv(‘BASIC_AUTH_PASS’) }
: undefined,
extraHTTPHeaders: { ‘x-api-key’: requireEnv(‘API_KEY’) },
},
},
{
name: ‘webkit-staging’,
use: {
…devices[‘Desktop Safari’],
baseURL: requireEnv(‘BASE_URL_STAGING’),
extraHTTPHeaders: { ‘x-api-key’: requireEnv(‘API_KEY_STAGING’) },
},
},
// Add prod, mobile, etc.
],
});
This setup ensures that each environment has its own configuration and environment variables, making the test configuration highly adaptable and maintainable.
2. Global setup to compute per-run values
Generate run-scoped values (e.g., auth tokens, test data IDs) once and expose via process.env.
// global-setup.ts
import { request, FullConfig } from ‘@playwright/test’;
export default async function (config: FullConfig) {
const ctx = await request.newContext({ baseURL: process.env.AUTH_BASE_URL });
const resp = await ctx.post(‘/token’, { data: { clientId: process.env.CLIENT_ID, secret: process.env.CLIENT_SECRET } });
const { accessToken } = await resp.json();
process.env.ACCESS_TOKEN = accessToken; // used by all projects
}
// playwright.config.ts (add)
globalSetup: require.resolve(‘./global-setup’),
3. Project-scoped fixtures (typed options)
Create environment-aware fixtures so tests don’t touch process.env directly.
// tests/fixtures/env.ts
import { test as base } from ‘@playwright/test’;type Env = { api: string; token: string };
export const test = base.extend({
env: async ({}, use) => {
await use({
api: process.env.API_BASE!,
token: process.env.ACCESS_TOKEN!,
});
},
});
export const expect = test.expect;
// tests/example.spec.ts
import { test, expect } from ‘./fixtures/env’;
test(‘uses env-aware client’, async ({ request, env }) => {
const res = await request.get(`${env.api}/health`, { headers: { Authorization: `Bearer ${env.token}` } });
expect(res.ok()).toBeTruthy();
});
4. Orchestrating environments in CI (matrix + sharding)
Run all environments in parallel; shard long suites for speed.
# .github/workflows/playwright.yml
jobs:
e2e:
runs-on: ubuntu-latest
strategy:
matrix:
env: [dev, staging, prod]
shard: [1/2, 2/2]
env:
ENV: ${{ matrix.env }}
# Secrets per env (Org/Repo Environments or masked secrets)
BASE_URL: ${{ secrets[format(‘BASE_URL_{0}’, upper(matrix.env))] }}
API_KEY: ${{ secrets[format(‘API_KEY_{0}’, upper(matrix.env))] }}
steps:
– uses: actions/checkout@v4
– uses: actions/setup-node@v4
with: { node-version: 20 }
– run: npm ci
– run: npx playwright install –with-deps
– run: npx playwright test –shard=${{ matrix.shard }}
5. Targeted selection via tags/grep
Scope runs by feature or risk level per environment.
// Tag tests: test.describe.configure({ mode: ‘parallel’ }); test(‘feature A @smoke’, …)# Only smoke tests on prod
ENV=prod npx playwright test –grep “@smoke”
Best Practices for Managing Environment Variables in Playwright
To ensure that your Playwright tests are secure, maintainable, and scalable, follow these best practices for managing environment variables:
1. Use .env Files for Local Development
Store environment-specific variables (e.g., base URLs, API keys, credentials) in .env files. This keeps sensitive data separate from your codebase. Always ensure .env files are ignored by version control (add them to .gitignore) to prevent accidental exposure of secrets.
2. Leverage CI/CD Secrets Management
For sensitive data like API keys and tokens, use CI/CD secrets management tools (e.g., GitHub Secrets, GitLab CI variables) instead of storing them in .env files. This ensures that credentials are securely injected into the test environment during execution, without exposing them in your code.
3. Validate Required Variables at Startup:
Use a function or tool to check that all necessary environment variables are defined before running tests. This ensures that your tests fail early with clear error messages if a required variable is missing, rather than running into issues midway through the test run.
4. Use Separate .env Files for Different Environments:
Maintain different .env files for different environments (e.g., .env.dev, .env.prod, .env.staging). This allows you to easily switch configurations without changing your code. Use environment-specific configurations in your Playwright test setup (e.g., dotenv.config({ path: .env.${process.env.ENV} })).
5. Keep Secrets Secure:
Avoid hardcoding sensitive information such as passwords or API keys directly into the code. Use environment variables to securely manage such data. Also, mask sensitive information in logs and reports to prevent accidental exposure.
6. Centralize Configuration with Playwright’s Config File:
Use Playwright’s playwright.config.ts to define environment-dependent settings, like base URLs, authentication credentials, and API keys. This centralizes your configuration management, reducing the chances of errors and improving test consistency.
7. Use Environment Variables for Feature Flags and Dynamic Configuration:
Manage feature toggles or other dynamic test configurations using environment variables. This allows you to enable or disable features in your tests without modifying the code, making your testing process more flexible and easier to manage.
8. Ensure Consistent Naming Conventions:
Maintain consistent naming conventions for your environment variables (e.g., BASE_URL_DEV, BASE_URL_PROD, API_KEY). This helps prevent confusion and makes it easier to maintain your environment-specific configurations, especially in large projects with multiple environments.
9. Document Environment Variables:
Keep a document or README that explains the required environment variables for your project. Include information about their purpose and how to set them up, especially for new team members or when onboarding to a new project.
10. Minimize the Number of Environment Variables:
Only define the variables that are absolutely necessary for the tests. Avoid unnecessary complexity by limiting the number of environment variables and ensuring they are well-organized and purposeful.
By following these best practices, you ensure that your Playwright tests are secure, maintainable, and adaptable to different environments, ultimately improving the efficiency and reliability of your testing process.
Example Walk-through: Setting Up Playwright with Environment Variables
Setting up environment variables in Playwright allows for flexible, environment-specific configurations that keep your test code clean and maintainable. Here’s a simple example of how to configure environment variables in Playwright:
1. Create .env Files
Create different .env files for each environment (e.g., .env.dev, .env.staging, .env.prod) to store environment-specific variables. For instance, the .env.dev file might look like this:
BASE_URL=https://dev.example.com
API_KEY=dev-api-key
2. Install dotenv Package
Use the dotenv package to load these environment variables into your Playwright configuration. Install it using:
npm install dotenv
3. Configure Playwright to Use Environment Variables
In your playwright.config.ts, load the environment variables using dotenv.config() and set them dynamically based on the environment:
import { defineConfig } from ‘@playwright/test’;
import * as dotenv from ‘dotenv’;
// Load .env file based on the environment
const ENV = process.env.ENV ?? ‘dev’; // default to ‘dev’
dotenv.config({ path: `.env.${ENV}` });
export default defineConfig({
use: {
baseURL: process.env.BASE_URL, // Access environment variable
extraHTTPHeaders: {
‘x-api-key’: process.env.API_KEY // Use API key from environment
},
},
});
4. Access Variables in Tests
In your test files, you can directly access these variables using process.env:
import { test, expect } from ‘@playwright/test’;
test(‘should visit the correct base URL’, async ({ page }) => {
await page.goto(process.env.BASE_URL); // Use the loaded base URL
expect(page.url()).toBe(process.env.BASE_URL);
});
5. Run Tests with Different Environments
When running your tests, specify which environment to use by setting the ENV variable:
ENV=staging npx playwright test
This command loads the .env.staging file, allowing you to run tests with staging-specific configurations.
This simple setup lets you manage environment variables for different configurations (e.g., development, staging, production) without modifying the test code, keeping your tests clean and adaptable.
Read More: Playwright Test Report: Comprehensive Guide
Leveraging BrowserStack Automate for Scalable Environment Variable Management in Playwright
BrowserStack Automate empowers teams to run Playwright tests at scale on real browsers and devices in the cloud, while maintaining consistent and secure management of environment configurations.
It complements your existing setup by ensuring that tests using environment variables execute reliably across diverse environments, without the overhead of maintaining local infrastructure.
- Seamless CI/CD Integration: BrowserStack Automate works hand-in-hand with CI/CD tools like GitHub Actions, Jenkins, and CircleCI, allowing you to pass environment variables securely during test execution. This ensures that Playwright tests can adapt dynamically to different configurations such as development, staging, or production.
- Multi-Environment Testing at Scale: With BrowserStack’s extensive cloud infrastructure, you can execute Playwright tests in parallel across multiple browsers, devices, and operating systems – all configured using your environment variables. This provides true scalability and ensures consistent behavior across environments.
- Security and Data Integrity: Sensitive information such as API keys, credentials, and tokens can be managed securely through your CI/CD’s secrets management system. BrowserStack executes the tests in isolated environments, helping maintain data privacy and integrity throughout the testing process.
- Consistent and Reliable Configuration: Environment variables defined in your CI/CD or local setup are used seamlessly during BrowserStack test runs, ensuring that every test environment mirrors your actual application setup. This consistency improves reliability and minimizes environment-related issues.
- Scalable Cross-Browser Execution: By leveraging BrowserStack Automate, teams can focus on scaling their Playwright tests efficiently – executing thousands of test cases across multiple browsers and devices, all driven by the same environment-variable-based configuration logic.
Conclusion
Effective environment variable management is a cornerstone of reliable and scalable Playwright test automation. It enables teams to configure tests dynamically, maintain security by keeping sensitive data out of code, and ensure consistency across development, staging, and production environments.
By structuring environment variables thoughtfully, through .env files, CI/CD pipelines, and Playwright’s configuration, teams can streamline test setup, reduce maintenance overhead, and improve collaboration.
When paired with BrowserStack Automate, these practices scale effortlessly. Teams can execute Playwright tests across real browsers and devices globally, maintaining the same secure and consistent environment configurations at every level.
In essence, robust environment variable management empowers Playwright to deliver flexible, secure, and high-performing automated testing – ensuring your tests adapt as smoothly as your applications evolve.
Useful Resources for Playwright
- Playwright Automation Framework
- Playwright Java Tutorial
- Playwright Python tutorial
- Playwright Debugging
- End to End Testing using Playwright
- Visual Regression Testing Using Playwright
- Mastering End-to-End Testing with Playwright and Docker
- Page Object Model in Playwright
- Scroll to Element in Playwright
- Understanding Playwright Assertions
- Cross Browser Testing using Playwright
- Playwright Selectors
- Playwright and Cucumber Automation
Tool Comparisons:




