Testing with Cypress Across Multiple Environments
Tags: cypress, javascript, testing, tutorial
Published: 2022-07-18 04:30:35

##Overview
You may need to configure Cypress across multiple test environments and find it useful to know how to modify the `baseUrl` value. In this essay, I'll go over the ways my team achieves this goal. This is by no means the only or most correct way, so if you can see something you think I should change, please let me know on Twitter. This article only covers implementation of e2e testing, not component testing.

> We use [Yarn](https://yarnpkg.com/) as our package manager, so if you use NPM, when I describe what I type into my terminal, know that you can probably replace `yarn` with `npx` and get similar results.

We have two environments we test, `qa` and `master`, and because of some environmental differences, we want to only run what we consider smoke tests against `master`, while running more data-centric tests against `qa`. In your setup, `master` might be something more like a `dev` environment, under more change and with less assumed reliability. One important thing to know is that we consider `qa` to be our *default* environment.

## The scripts
Everything kicks off from our `package.json` file, where we have defined several test scripts in the `scripts` object.

```json
{
  "scripts": {
    "open:qa": "cypress open --e2e --browser chrome",
    "open:master": "cypress open --e2e --browser chrome --env master=1",
    "test:smoke": "cypress run --browser chrome --headless --env master=1 --spec 'cypress/e2e/**/*.smoke.cy.ts'",
    "test:regression": "cypress run --browser chrome --headless --spec 'cypress/e2e/**/*.ts'"
  },
}
```

One important thing to note here are that both the `open:master` and `test:smoke` scripts have `--env master=1` passed in, which we'll pick up on later. This essentially just allows our config to differentiate between this environment and the default `qa` environment. Note that this is a completely custom environmental variable, and you can create any environmental variables you want by passing them into your script with the `--env` flag. Another thing worth pointing out is that the `test:smoke` script only runs specs which have the name scheme `*.smoke.cy.ts`, whereas `test:regression` will run these files *plus* anything with the scheme `*.spec.cy.ts`, in otherwords, every spec file.

##The config
In the `cypress.config.ts` file, we use conditional logic (`if (config.env.master)`) to choose which config to launch based on the `--env master=1` flag (or we *default* to `qa` environment config if we don't see it). Note that this approach can scale to any number of uniquely named environments.

```typescript
e2e: {
  setupNodeEvents(on, config) {
    if (config.env.master) {
      return {
        baseUrl: "<master env baseUrl>",
        env: {
          env: "master",
          auth_username: "<email>",
          auth_password: "<password>",
        },
      };
    } else
      return {
        baseUrl: "<qa env baseUrl>",
        env: {
          env: "qa",
          auth_username: "<email>",
          auth_password: "<password>",                  
        },
      };
  },
},
```
Note that we are only checking for the existence of the `master` environmental variable. Its value doesn't have to be `1`, it could be anything, we're merely checking that it exists. Also note that `baseUrl` must be returned *outside* the `env` object.

## The runtime
In a Github Actions workflow file, or from the command line, we can run tests against whichever environment we choose by running things like:

```shell
yarn run open:qa
```
or
```shell
yarn run test:smoke
```
You'll recall that these commands will call scripts defined in the `package.json` file, which will then kick off this whole process I've described of inserting an environmental flag, then reading that flag to choose which environmental config to work with from the `cypress.config.ts` file.

Hopefully this makes someone's life a little easier. As I said at the outset, this isn't the *only* way to do this, it's just *a* way, and might be useful for you.

##Acknowledgements
Much thanks to Gleb Bahmutov for all the work he does for the Cypress community and his [blogging on this subject](https://glebbahmutov.com/blog/cypress-v10-env/). He also has [a great video](https://www.youtube.com/watch?v=f5UaXuAc52c) on how to set the `baseUrl` property.