[Feature] Environment variable setting and retrieval by Playwright
Current situation: Playwright does not provide an out of the box solution for environment variables. This means in our project, we are using dot env library to keep local environment variable values and use Jenkinsfile to hold the CI/CD environment variable values. This means we need to:
- Maintain environment variables in two files
- Take extra steps to use a secondary plugin (.env)
Suggested solution:
-
User to be able to define JSON files which contains environment variable and values:
{ "env": { "baseUrl": "www.playwright.dev", "testUser": "abc", "someOtherServiceUrl": "value changes based on user locally/Jenkins" } } -
User is able to retrieve the values anywhere in the project (for example by environment.env.baseUrl)
-
User is able to define multiple files
-
User is able to set environment file globally in playwright.config.ts, with a default value
-
User to define 1 environment file per project in playwright.config.ts, which overrides the global value
-
User is able to set the environment file as a command line parameter, which overrides everything
Let's see if this gets community support!
yes please , ive asked about this in slack
https://playwright.slack.com/archives/CSUHZPVLM/p1647714390882259
Could you elaborate on the downsides of using dotenv & process.env.MYENV combo?
- Dotenv does not work with Jenkins, so I need to maintain two different set of env variables (one for dotenv and one in Jenkinsfile)
- I have to use a secondary plugin such as dotenv, which goes against the whole concept of Playwright being all in one pack
Downsides of using dotenv is only one part of the problem. Cypress offers some really nice test configuration and environment variable management, that I would love to see in Playwright: Link to Cypress documentation
Any updates on this?
Recommendation from Playwright maintainers:
Please use https://www.npmjs.com/package/dotenv package to manage your environment variables, you can load them in your config file:
// in your playwright.config.ts
import * as dotenv from 'dotenv';
dotenv.config();
or
require('dotenv').config();
Learn more at https://www.npmjs.com/package/dotenv
@pavelfeldman I can assure you that the 89 people who supported this are very well aware of dotenv. Dotenv doesn’t solve the issue as mentioned when asked by you.
Almost after a year of waiting for this feature you are dismissing it with dotenv? Not acceptable
I can assure you that the 89 people who supported this are very well aware of dotenv.
I'm not sure about this, dotenv has 27M weekly downloads and has worked very well for the mainstream use cases.
@irharrier2: could you please restore the maintainer's edit to the issue description? It is important that users see dotenv as the first recommendation when they stumble upon this issue.
Yeah, dotenv definitely has its place. However, for a testing tool and complete environment it is simply not adequate. There is a reason that Cypress, the most popular testing tool on the market with 4M weekly downloads, has developed their own solution.
No, the dotenv recommendation is not accepted for me as a solution to my issue. You can set the recommendation on the closing remark.
There is a reason that Cypress, the most popular testing tool on the market with 4M weekly downloads, has developed their own solution.
I believe the reason behind this solution is that Cypress tests run in the browser and don't have access to the Node runtime that has process.env and ability to use dotenv.
We prefer to not re-invent solutions when good options are available via the underlying platform and/or a popular package. Let me iterate over your requirements and demonstrate how an integrated solution would be indistinguishable from using process.env and/or dotenv:
User to be able to define JSON files which contains environment variable and values:
- integrated: playwright.env.json file
- dotenv: a properties .env file
- raw: a JS file that contains a bunch of process.env.MYVAR assignments
User is able to retrieve the values anywhere in the project (for example by environment.env.baseUrl)
That's available for both process.env assignments and dotenv, via process.env.baseUrl.
User is able to define multiple files
You can have as many JS files with your environments or as many .env variations as you'd like.
User is able to set environment file globally in playwright.config.ts, with a default value
// integrated
{ env: 'playwright.env.json' }
// dotenv
require('dotenv').configure({ path: './.env' });
// raw
require('./env.js')
User to define 1 environment file per project in playwright.config.ts, which overrides the global value
It sounds like you are looking for the project parametrization with this one: https://playwright.dev/docs/next/test-parameterize#parameterized-projects
User is able to set the environment file as a command line parameter, which overrides everything
You can use environment to pass the name of the environment file:
ENV=prod npx playwright test
require('dotenv').configure({ path: process.env.ENV });
@pavelfeldman that is not true. Cypress can use OS environment variables. A quick Google search would make that obvious. From what you have explained it is clear that Playwright team is a bit separated from reality and how does an actual project with multiple environments look like.
see also all the nice features that you get for environment variables in Cypress similar to what I was asking.
the way you have handled this issue is just disappointing. Asking for community support, and when you had it, you give a no solution.
Incorrect: require('dotenv').configure({ path: process.env.ENV }); correct: require('dotenv').config({ path: process.env.ENV });
@irharrier2 I ran into this same issue, and was a bit surprised others don't fully understand the underlying problem. I miss being able to set any arbitrary property on the Cypress config, and use it directly in any test file via the config API.
One workaround I found was just to install the npm config module, and set up dedicated qa, production, etc .js files in a separate config folder to store test variables. Then in any test files that need the config, you can just require in the config module, and destructure the returned config object to pull any relevant variables you need. Any sensitive variables I still pass down as Jenkins credentials in CI/CD, so I still have to store some variables in tow places, but I bind them to config properties in the individual config files, so that I have a single interface for fetching env variables. Figured I'd share in case useful.
@jwohlfahrt actually others fully understand the issue. there is like 100 likes on the original request, making it a popular request.
Unfortunately, the guy who is handling this issue, doesn't fully understand the issue and has a history of closing issues as much he can as fast as he can.