I have a suite of Cypress tests that all use the same base Url except for one legacy test. The legacy test is using a before hook which has a cy.visit of http://e2etest.dev.my-company.com:8081/company/sign-in
. The problem is that this test is running e2etest.dev even when ran against staging.
I created an if statement in the relevant code:
if (Cypress.env('CYPRESS_ENV') === 'test') {
cy.visit('http://e2etest.dev.my-company.com:8081/company/sign-in');
} else {
cy.visit('http://e2etest.staging.my-company.com:8081/company/sign-in');
}
I also have a Github Actions ci.yaml. I do not have an e2e.yaml. The way the ci.yaml works is it takes in the branch name and it runs this:
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME}"
BUILD_REF="${GITHUB_REF_NAME}"
FORMATTED_BUILD_REF="$(echo $BUILD_REF | sed 's/[^a-zA-Z0-9]/-/g')"
VERSION="$(date -u +'%Y%m%d')-$GITHUB_RUN_NUMBER-${GITHUB_SHA:0-7}"
SERVICE='my-company-pro'
case "${GITHUB_REF_NAME}" in
"master")
BASE_URL="https://e2etest.my-company.com"
API_HOST="api.my-company.com"
NAMESPACE="app-prod"
;;
"staging")
BASE_URL="https://e2etest.staging.my-company.com"
API_HOST="api.staging.my-company.com"
NAMESPACE="app-staging"
CF_WORKER_ENV="staging"
;;
"sandbox")
BASE_URL="http://e2etest.sandbox.my-company.com"
API_HOST="api.sandbox.my-company.com"
NAMESPACE="app-sandbox"
;;
*)
BASE_URL="https://e2etest.dev.my-company.com:3003"
API_HOST="api.staging.my-company.com"
NAMESPACE="app-test"
CF_WORKER_ENV="test"
;;
In the cypress job, I printed out what variables are available and I got this back, indicating I edited the yaml correctly:
Run echo "CF Worker Env: staging"
CF Worker Env: staging
and
Run echo "CYPRESS_ENV=${CYPRESS_ENV}"
CYPRESS_ENV=staging
These values say test on a feature branch and staging on the staging branch. In Cypress dashboard I can see that on a feature branch, it’s going to the if statement for the dev environment and I can see my console.log(Cypress.env(‘CYPRESS_ENV’)) printed out the word test
However, when the test merges into staging in my pipeline it still prints the word test and goes to the dev environment.
Here is my cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
chromeWebSecurity: false,
pageLoadTimeout: 60000,
blockHosts: '*datadoghq.com',
projectId: '5cwnfh',
defaultCommandTimeout: 40000,
requestTimeout: 40000,
responseTimeout: 40000,
execTimeout: 15000,
taskTimeout: 15000,
viewportWidth: 1440,
viewportHeight: 900,
numTestsKeptInMemory: 0,
retries: {
runMode: 2,
},
env: {
COMPANY_API_BASE_URL: 'api.staging.my-company.com',
CYPRESS_ENV: 'test',
},
e2e: {
fixturesFolder: 'fixtures',
baseUrl: 'https://e2etest.dev.my-company.com:3003',
specPattern: 'cypress/e2e/**/*.{ts,tsx}',
},
component: {
devServer: {
framework: 'next',
bundler: 'webpack',
},
},
});
I think the test is failing in CI because of my CYPRESS_ENV I put in my cypress.config.ts while I was troubleshooting. However, if I take out the CYPRESS_ENV from my config.ts, the test goes to the else block and runs against staging when I run it locally because in the console.log when I’m running locally, it’s printing out "undefined"
How do I make Cypress run the ‘test’ env for CYPRESS_ENV locally, the ‘test’ env for CYPRESS_ENV when GITHUB_REF is not staging in CI, and the ‘staging’ env for CYPRESS_ENV when GITHUB_REF is staging in CI?
In other projects, I have a command in the cypress job in CI where I can adjust the values in command line but this test runs cypress automatically. Here is my cypress job in CI:
cypress-test:
needs: [workflow-info, build]
runs-on: ubuntu-latest
env:
WORKER_ENV: ${{ needs.workflow-info.outputs.cf-worker-env }}
BASE_URL: ${{ needs.workflow-info.outputs.base-url }}
API_BASE_URL: ${{ needs.workflow-info.outputs.api-host }}
CYPRESS_ENV: ${{ needs.workflow-info.outputs.cf-worker-env }}
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4, 5, 6, 7, 8, 9]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
cache: 'yarn'
node-version: '20.9.0'
- name: Install Specific Chrome Version
run: |
sudo apt-get install -y wget
sudo wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt-get install ./google-chrome-stable_current_amd64.deb
- name: Get yarn cache directory path
id: yarn-cache-dir-path
shell: bash
run: |
echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-${{ hashFiles('yarn.lock') }}
restore-keys: |
yarn-
- name: Restore next build and deps
uses: actions/cache@v4
with:
path: |
./next/.next
./next/node_modules
./legacy/node_modules
./node_modules
~/.cache/Cypress
key: next-build-${{ github.sha }}
- name: Setup /etc/hosts
run: sudo echo "127.0.0.1 e2etest.dev.my-company.com" | sudo tee -a /etc/hosts
- name: Print CF Worker Env
run: |
echo "CF Worker Env: ${{ needs.workflow-info.outputs.cf-worker-env }}"
- name: Print CYPRESS_ENV
run: echo "CYPRESS_ENV=${CYPRESS_ENV}"
- name: Run App
run: yarn dev &
- name: Run Cypress Tests
uses: cypress-io/github-action@v6
with:
browser: chrome
working-directory: next
record: true
parallel: true
config: baseUrl=${{ needs.workflow-info.outputs.base-url }}
ci-build-id: ${{ needs.workflow-info.outputs.cypress-run-id }}-${{ github.run_attempt }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_DASHBOARD_KEY_NEXT }}
DEBUG: '@cypress/github-action'
CYPRESS_ENV: ${{ needs.workflow-info.outputs.cf-worker-env }}
2
Answers
I was not able to use the CYPRESS_ENV variables in my CI to do this but I was able to use this because the baseUrl is called in
config: baseUrl=${{ needs.workflow-info.outputs.base-url }}
in my CI. I printed out `console.log('base Url is', Cypress.config().baseUrl); to get this value.It doesn't use env vars, so I'd still like to know how to use them for this purpose, but this works. Please comment if you know how to use env vars from CI.
The environment var
CYPESS_ENV
does not find it’s way into the test code, most likely becauseenv
is a reserved word and is therefore rejected.Experimenting
In a clean project (Windows syntax),
Running
yarn start1
withCYPRESS_ENV=legacy
, the above test logs empty environment object:Running
yarn start2
withCYPRESS_CYPRESS_ENV=legacy
, the above test logs the environment value you want:Note there is an extra space at the end of the value for some weird reason.
If you double-prefix the environment variable, then your
before()
code should work with a.trim()
in theif()
statement: