Environment Variables | Bondar Academy
Course: Cypress UI Testing with JavaScript
Module: Advanced Features
Instructor: Artem Bondar
Lesson Summary
In this lesson, we explore environment variables , which are special variables that hold values related to the environment where tests are run. They are essential for managing configurations across different machines and environments (e.g., dev, QA, staging). Key Concepts Purpose: Store sensitive information like credentials securely, rather than hardcoding them in the code. Cypress Configuration: Cypress provides various methods to manage environment variables, each with its pros and cons. Managing Environment Variables in Cypress Using cypress.config.js : env: { username: 'commands', password: 'welcome12345' } Using a .env file: Create a cypress.env.json file to override default settings, keeping sensitive data safe. Command Line Overrides: Pass environment variables directly via the command line using --env option. NPM Scripts: Customize scripts in package.json for different environments, allowing for easy switching. Multiple Configuration Files: Create separate configuration files for different environments (e.g., cypress.dev.config.js ). Environment variables can be set in various ways, allowing flexibility and security when running tests. Always ensure sensitive data is not exposed in version control by using .gitignore for files like cypress.env.json . Choose the method that best fits your project needs, and implement it to enhance your testing framework.
Video Transcript
Hey guys, welcome back, and in this lesson, we will talk about environment variables. So first of all, what is environment variable? Environment variable is a special variable or variables that holds the value inside of your framework related to the environment where you want to run your test framework. For example, you want to run your test suite on different test machines, on different developer machines, or you want to run your test in different environment, dev environment, QA environment, staging environment, and so on. Or you have a special credentials or maybe other variable values that specifically only you want to use to run the test and nobody else should use those credentials. So for such situations, environment variables is the best way how to manage those cases. And in this lesson, I will show you how to do this. So let's jump into it. So Cypress, in its documentation, offering five different options, how to manage environment variables, presenting different pros and cons. I will show you some of those and a little bit more what is not shown in this documentation, and you can choose whatever works best for you, for your use case, and for your scenario. So let's go back to our test application. Previously, for Conduit application in the course to log in to our application, we created a custom command. This custom command make an API call and then makes headless authorization to the application. And the credentials for this API call stored directly inside of the custom command inside of this request body. And I think you would agree that this is definitely not the best place to keep username and password somewhere buried in the code. We should manage those type of data in more meaningful place. And for that, we can use environment variables, saving the email and password into environment variables. And inside of the code, we will create just a reference to those variables. So let's jump into it. The first example, you just go to cypress.config.js. And here, Cypress have a special object, which is env to store all your environment variables related to the project. And let's create a new variables. For example, I call it username, and I give it a value, commands, Ctrl C and paste in Ctrl V. And then the second value will be password. And the same thing, I will take welcome, 1, 2, 3, 4, 5, and save it over here. And also I need to put comma, since this is a JavaScript object. All right, the next step, we need to create the reference to these variables. So instead of hard-coded value, I will call cypress.env method. And inside, I will provide the argument with the name of the variable that I just created. First variable is username, and the second variable will be a password. And password, just like this. And I guess we can double-check if it is working correctly. So I run a new terminal, npx cypress open. Running Cypress, so e2e. And when you open Cypress, so here you can double-check in the settings, what are the values for the variables are set. You go to the settings, you go to the project settings, scroll all the way down. And all the variables that are configured for the framework, you can find over here. Default config env, they highlighted by this color, CLI and dynamic. We scroll all the way down and look, in the env section, we see a highlighted section with our environment variables. It means that framework were able successfully to define those. And now if I run the test, all my tests that were executed previously should work exactly the same way. So you see five tests passed successfully, everything is working. So what else? Also, we have API URL over here. So for the application URL, Cypress has a predefined environment variable, which is a base URL under e2e. But for the API URL, we don't have it. And we use API URL multiple times across the project. For example, for every API request over here and over here, we provide the full API URL. But what if we need to change our environment to a different environment? For example, dev environment or staging environment. Every time we need to go and change the URLs everywhere where it was used. Absolutely not convenient. So let's replace it with environment variable as well. I'm going back here and create new environment variable API URL. And provide the value. So the value, let's go here. So I take this including API, because API repeated again and again across the URLs, and paste it right here. And I need to put comma. And we repeat this operation one more time. So I replace this with cypress.env and create the reference to API URL. And since we have a string, we can create concatenation. So plus and single quote. And I need to remove API over here, by the way. So API and then users.login. That's it. And the same way, now we can update everywhere inside of our application. But instead of doing this manually, we can ask VSCode to help us doing this. So I hit Find and Replace. And now what I want to replace? I want to replace the beginning of this URL, including API. Find all occurrences of this stuff and replace it with this string, Ctrl C, Ctrl V. Now I just go here and find Replace, Replace, Replace, Replace, and Replace. And let's check it out. And it seems like everything is fine except this one, because this one is interpolation. Let's change it manually. So I put $ and curly braces. Then I take this CypressENV, going back, pasting it over here. And I need to remove the portion of this URL. All right, so cypressenv API URL slash article slash slug ID. And I guess we did everything correctly. Let's just double check this. So opening Cypress. First of all, I'm going to the settings just one more time to double check that environment variable is set. So you see environment API URL is set. Go into the specs and let's try to run it. Running the test and all test passed successfully. Everything is working. All right, perfect. So that's the most easiest way how you can organize your all environment variables in just a single place. But let's say that you have credentials that you would like to use specifically for your test run. Let's say this username and password are some public credentials that used by everyone. But you have your own secret credentials that you don't want to share with anyone else. You want to use it only for your test runs when you use this application. For scenarios like that, you can create a separate .env file. So I create a new file, cypress.env.json, like this. It will be a simple object. And here you put the environment variables that you want to override. For example, I want to use a different user. Instead of using cyuser-qqq.com, I want to use. Let me fix this. It should be in double quotes because this is a JSON file. Double quotes, double quotes. And I want to use cyuser, let's say, 555 at qqq.com, something like this. And when you run the Cypress in this type of configuration using .env file, and look what's gonna happen. So I'm running the Cypress, going to the settings, project settings, scrolling down. And now the cyuser555 is used as a username for this execution. So what technically happens, when you have this cypress.env.json, this file overrides the settings in the main configuration file. So it's override these settings. It's still gonna use this password, but will use a different user. And you can add as many environment variables as you need to this .env file. And the purpose of this file is to keep it safe and secret. And to do that, make sure that you add this cypress.env.json into gitignore file, so cypress.env.json. So this file will be ignored from the version in control and will not be committed to the source code when you make any updates to the project. You see, currently, it's grayed out. So it means that this file exists only on your computer, only with the data that you use on your computer, and nobody else will be able to use it. All right, so that's the option number two. So let's talk about the option number three. So let me close Cypress, first of all. Option number three, you can pass the environment variables also through their command line. And you can do it something like this. So I type npx cypress open, and then I type --env. And then you provide the variables that you want to override. For example, username, and I want to call the username equals to hello at test.com, something like this. And then if I want to use the second variable, I put comma. And without spaces, I provide the second variable, for example, password. And use the value 123123, something like this, and hit Enter. And Cypress is launching, opening the Cypress, looking over here, going to the settings, project settings, scrolling it down. And what we see, here we go. Now we pass the values from the command line. So you see the hierarchy of the environment variables. So the lowest level would be configuration file, then env file. And then if you pass something from the command line, the command line overrides all other settings that you have on the framework. So command line input has the highest authority in this example. And we have a new values passed in the framework. And this username and password will be used to execute your test. All right, so let's move on. And since you can pass anything in the command line, now based on different scripts, you can create different NPM scripts for different environments. And for example, going back to the package.json, you already know about customization of your own scripts. So for example, I want cy run dev, something like this. I want to create the script, and where is my command? And let's say this will be my dev environment configuration. And I need to replace it with a single quotes to avoid the conflicts. Like this and like this. And for example, hello dev at test.com. And let's say I want to create the second script to run across the QA environment like this. And it will be hello QA at test.com. So now we have a dedicated script calling the different script. It will trigger execution of different variables for the different environment. And now if I just call NPM run cy run QA. And it will trigger the script with a username and password related to the QA environment. Scrolling all the way down, here we go. Hello QA at test.com and password 123. All right, so this is how it works. And I think you may agree that sometimes when we talk about username and password, you probably don't want to store the credentials like this directly in the NPM script. You would want to hide those values and preferably pass them as environment variable, for example, when you run the script on the CI server, on CICD environment. And so when you run the script, the environment will read the environment, process environment variable, and put the values into those variables inside of the NPM script. So how would you do this? So let's replace, for example, the username. I would put a dollar sign and put username. It will be the name of my environment variable. And here I put the dollar sign and password. Why I use a capital case? It's just a naming convention to use a capital casing for the process environment variables. Now, how to define process environment variables? Going to the cypressconfig.js. And here in the node events, we need to configure this. I call config.env. And then environment variable that I want to set the value to. I want to set value to username. And external environment variable will be process.env. And the variable name is username, this guy. Okay, and the similar we need to do for the password. Instead of username, it will be username password. So this is where we're gonna assign. And this is a password that will be called from the environment variable. And after you've done this, you call return.returnConfig. So you need to return the updated configuration for the env. And that's it. After that, after you define this, if you want to assign values when you run this NPM script, so if I call this cyrunqa, now I need to assign the value to this username and password. So what I do, and this would work in the Linux or Mac environment. The syntax for the Windows PowerShell and Windows Command Prompt will be slightly different, how you need to assign the value to process environment variables. Please Google this syntax, it's quite simple, just there are some little specific related to Windows PowerShell and Windows Command Prompt, depend where you run it. So username, and let's say, I put test.com. And then space, and I call password equals to 1, 2, 3. And then I call NPM run, and then I call cyrunqa, cy underscore run underscore qa. So that's the name of the script, and look what I'm doing. I'm assigning the values to the process environment variables. Those process environment variables will be passed into the script on the script level. Then they run the script inside the configuration file. This process will be transformed into config env file within the Cypress framework, and then this value will be written by the framework itself, where we use it inside of the framework, right? So running this thing, and now opening the framework, going to the settings, project settings, scrolling a little bit down. And here we go, test.test.com, and 1, 2, 3. Environment variables were set correctly. And one last thing, let me show you one last thing that you can use. Sometimes you may go a little bit different route. For example, apart from environment variables, you may have a different base URL, maybe some other configurations. Depends on the environment, maybe you want to use a different viewport or different browser settings, different framework settings for different environment. It's also a possibility. In this case, you can create a multiple configuration files, and each of the configuration file in Cypress will have a different set of settings, including environment variables. So for example, you can create a new file, and I call it cypress.dev.config.js. Let me take this file as the base for my file. And let's say for the dev variable, I will change this to a dev. And welcome, I say dev 1, 2, 3, 4, 5. It's just for you to see that it's actually work. And then when I call npx cypress open, I can set different config file. And I say I want to use cypress.dev.config.js, and hit Enter. And loading Cypress framework, opening settings, project settings, scrolling all the way down, and look what we have here. And we have a password, welcome dev 1, 2, 3, 4, 5, but not for the username. Cyuser555. And why is that? It's because we have this guy, cypressenv.json, that overrides the configuration file, okay? So if you want to go with the approach of different config files for different environments, maybe in this case, you don't need to use the env.json. Or if you use it, make sure that you not be confused where your environment variable is coming from. All right, guys, I guess that's it, what I wanted to share with you about environment variables. You see, you have tons of different options what you can do. You can have just a simple setup within config files, you can use different NPM script, you can have your own env file with the environment variables, or you can have multiple config files, including different Cypress settings and environment variables. Choose the option that works best for you, and I'll see you in the next lesson.