GitHub Action for running Cypress end-to-end and component tests. Includes NPM installation, custom caching and lots of configuration options.
- End-to-End testing
- Component testing
- Select action version
- Run tests in a given browser
- using Chrome
- using Firefox
- using Edge
- using headed mode
- Using Docker image
- Specify environment variables
- Run only some spec files
- Test project in subfolder
- Record results on Cypress Cloud
- Tag recordings
- Specify auto cancel after failures
- Store test artifacts on GitHub
- Quiet output
- Set Cypress config values
- Use specific config file
- Run tests in parallel
- Combine Component and E2E testing
- Build app before running the tests
- Start server before running the tests
- Start multiple servers before running the tests
- Wait for server to respond before running the tests
- Use custom install command
- Use command prefix
- Use own custom test command
- Pass custom build id when recording to Cypress Cloud
- Generate a robust custom build id to allow re-running the workflow
- Use different working-directory
- Use Yarn Classic
- Use Yarn workspaces
- Use custom cache key
- Run tests on multiple Node versions
- Split install and tests into separate jobs
- Use custom install commands
- Install only Cypress to avoid installing all dependencies
- Use timeouts to avoid hanging CI jobs
- Print Cypress info like detected browsers
- Run tests nightly or on any schedule
- Suppress test summary
- More examples
Current examples contained in this repository are based on Cypress 12.x and can be found in the examples directory. Examples for Legacy Configuration use Cypress 9.7.0
and are kept in the examples/v9 directory.
Some older external examples, linked to by this document, are based solely on Cypress 9 and below and therefore use a Legacy Configuration. These may need modification to be applied to Cypress 10 and later. Each of these external links is listed with a (legacy)
notation.
name: End-to-end tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
uses: cypress-io/github-action@v5
The workflow file example-basic.yml shows how Cypress runs on GH Actions using Ubuntu (20 and 22), Windows, and macOS without additional OS dependencies necessary.
This workflow uses the default test type of End-to-End (E2E) Testing. Alternatively, Component Testing can be utilized by referencing the Component Testing section below.
Note: this package assumes that cypress
is declared as a development dependency in the package.json
file. The cypress
NPM module is required to run Cypress via its NPM module API.
To use Cypress Component Testing add component: true
name: End-to-end tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
component: true
See the example project component-tests and the example-component-test.yml workflow for more details.
Best practice:
Our examples specify using branch v5 which is the action's latest major version:
- name: Cypress run
uses: cypress-io/github-action@v5
When using cypress-io/github-action@v5
from your workflow file, you will automatically use the latest tag from branch v5.
Alternatively, to mitigate unforeseen breaks, bind to a specific tag, for example:
- name: Cypress run
uses: cypress-io/github-action@v5.1.0
The changes associated with each tag are shown under GitHub's releases list. Refer also to the Changelog for an overview of major changes.
Specify the browser name or path with the browser
parameter. The default browser, if none is specified, is the built-in Electron browser.
name: Chrome
on: push
jobs:
chrome:
runs-on: ubuntu-22.04
name: E2E on Chrome
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
browser: chrome
name: Firefox
on: push
jobs:
firefox:
runs-on: ubuntu-22.04
name: E2E on Firefox
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
browser: firefox
name: Edge
on: push
jobs:
edge:
runs-on: ubuntu-22.04
name: E2E on Edge
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
browser: edge
Run the browser in headed mode - as of Cypress v8.0 the cypress run
command executes tests in headless
mode by default
name: Chrome headed
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
browser: chrome
headed: true
You can run tests in a GH Action in your Docker container.
name: E2E in custom container
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
# Cypress Docker image with Chrome v106
# and Firefox v106 pre-installed
container: cypress/browsers:node18.12.0-chrome106-ff106
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
browser: chrome
Specify the env argument with env
parameter
name: Cypress tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run with env
uses: cypress-io/github-action@v5
with:
env: host=api.dev.local,port=4222
When passing the environment variables this way, unfortunately due to GitHub Actions syntax, the variables should be listed in a single line, which can be hard to read. As an alternative, you can use the step's env
block where every variable can be set on its own line. In this case, you should prefix every variable with CYPRESS_
because such variables are loaded by Cypress automatically. The above code example is equivalent to:
name: Cypress tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run with env
uses: cypress-io/github-action@v5
env:
CYPRESS_host: api.dev.local
CYPRESS_port: 4222
For more examples, see the workflow example below.
Specify the spec files to run with spec
parameter
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
spec: cypress/e2e/spec1.cy.js
You can pass multiple specs and wild card patterns using multi-line parameter, see example-config.yml:
spec: |
cypress/e2e/spec-a.cy.js
cypress/**/*-b.cy.js
For more information, visit the Cypress command-line docs.
Specify the project to run with project
parameter
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
project: ./some/nested/folder
For more information, visit the Cypress command-line docs.
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# pass GitHub token to allow accurately detecting a build vs a re-run build
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Tip 1: We recommend using the action with on: [push]
instead of on: [pull_request]
to get the most accurate information related to the commit on the dashboard. With pull requests, the merge commit is created automatically and might not correspond to a meaningful commit in the repository.
Tip 2: we recommend passing the GITHUB_TOKEN
secret (created by the GH Action automatically) as an environment variable. This will allow correctly identifying every build and avoid confusion when re-running a build.
Tip 3: if running on pull_request
event, the commit message is "merge SHA into SHA", which is not what you want probably. You can overwrite the commit message sent to Cypress Cloud by setting an environment variable. See issue 124 for details.
Tip 4: to record the project needs projectId
. Typically this value is saved in the cypress.json
file. If you want to avoid this, pass the project id using an environment variable:
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# pass GitHub token to allow accurately detecting a build vs a re-run build
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# pass the project ID from the secrets through environment variable
CYPRESS_PROJECT_ID: ${{ secrets.PROJECT_ID }}
You can pass a single or multiple tags when recording a run. For example
name: tags
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
# let's make sure our "app" works on several versions of Node
strategy:
matrix:
node: [14, 16, 18, 19]
name: E2E on Node v${{ matrix.node }}
steps:
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- run: node -v
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
tag: node-${{ matrix.node }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The recording will have tags as labels on the run.
You can pass multiple tags using commas like tag: node-18,nightly,staging
.
Specify the number of failed tests that will cancel a run when using the Cypress Cloud Auto Cancellation feature.
This feature requires Cypress 12.6.0 or later and a Cypress Cloud Business or Enterprise account.
name: Cypress E2E Tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
name: E2E
steps:
- name: Setup Node
uses: actions/setup-node@v3
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
# Cancel the run after 2 failed tests
auto-cancel-after-failures: 2
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
See Auto Cancellation for more information.
If you don't record the test run on Cypress Cloud, you can still store generated videos and screenshots as CI artifacts. See cypress-gh-action-example (legacy) and the workflow example below
name: Artifacts
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
name: Artifacts
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
# after the test run completes
# store videos and any screenshots
# NOTE: screenshots will be generated only if E2E test failed
# thus we store screenshots only on failures
# Alternative: create and commit an empty cypress/screenshots folder
# to always have something to upload
- uses: actions/upload-artifact@v3
if: failure()
with:
name: cypress-screenshots
path: cypress/screenshots
# Test run video was always captured, so this action uses "always()" condition
- uses: actions/upload-artifact@v3
if: always()
with:
name: cypress-videos
path: cypress/videos
You can provide quiet
flag for cypress run to silence any Cypress specific output from stdout
name: example-quiet
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
# Install NPM dependencies, cache them correctly
# and run all Cypress tests with `quiet` parameter
- name: Cypress run
uses: ./
with:
working-directory: examples/quiet
quiet: true
Specify configuration values with config
parameter
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
config: pageLoadTimeout=100000,baseUrl=http://localhost:3000
Specify the path to your config file with config-file
parameter
name: Cypress tests
on: push
jobs:
cypress-run:
name: Cypress run
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
config-file: tests/cypress-config.json
Note: Cypress parallelization requires a Cypress Cloud account.
You can spin multiple containers running in parallel using strategy: matrix
argument. Just add more dummy items to the containers: [1, 2, ...]
array to spin more free or paid containers. Then use record
and parallel
parameters to load balance tests.
name: Parallel Cypress Tests
on: push
jobs:
test:
name: Cypress run
runs-on: ubuntu-22.04
strategy:
# when one test fails, DO NOT cancel the other
# containers, because this will kill Cypress processes
# leaving Cypress Cloud hanging ...
# https://github.com/cypress-io/github-action/issues/48
fail-fast: false
matrix:
# run 3 copies of the current job in parallel
containers: [1, 2, 3]
steps:
- name: Checkout
uses: actions/checkout@v3
# because of "record" and "parallel" parameters
# these containers will load balance all found tests among themselves
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
parallel: true
group: 'Actions example'
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
# Recommended: pass the GitHub token lets this action correctly
# determine the unique run id necessary to re-run the checks
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Warning GITHUB_TOKEN
to get the correct branch and the number of jobs run, making it possible to re-run without the need of pushing an empty commit. If you don't want to use the GITHUB_TOKEN
you can still run your tests without problem with the only note that Cypress Cloud's API connects parallel jobs into a single logical run using GitHub commit SHA plus workflow name. If you attempt to re-run GitHub checks, Cypress Cloud thinks the run has already ended. In order to truly rerun parallel jobs, push an empty commit with git commit --allow-empty -m "re-run checks" && git push
. As another work around you can generate and cache a custom build id, read Adding a unique build number to GitHub Actions.
The Cypress GH Action does not spawn or create any additional containers - it only links the multiple containers spawned using the matrix strategy into a single logical Cypress Cloud run where it splits the specs amongst the machines. See the Cypress parallelization guide for the explanation.
During staged rollout of a new GitHub-hosted runner version, GitHub may provide a mixture of current and new image versions used by the container matrix. It is recommended to use a Docker image in the parallel job run which avoids any Cypress Cloud errors due to browser major version mismatch from the two different image versions. A Docker image is not necessary if testing against the default built-in Electron browser because this browser version is fixed by the Cypress version in use and it is unaffected by any GitHub runner image rollout.
Component Testing and End-to-End (E2E) Testing types can be combined in the same job using separate steps
- name: Run E2E tests
uses: cypress-io/github-action@v5
- name: Run Component Testing
uses: cypress-io/github-action@v5
with:
# we have already installed everything
install: false
component: true
You can run a build step before starting tests
name: Build
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
build: npm run build
If your tests run against a local server, use start
parameter, the server will run in the background and will shut down after tests complete
name: With server
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
Note: sometimes on Windows you need to run a different start command. You can use start-windows
parameter for this
name: With server
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
# Linux and MacOS
start: npm start
# Takes precedences on Windows
start-windows: npm run start:windows:server
Note: GitHub cleans up the running server processes automatically. This action does not stop them.
You can start multiple server processes. For example, if you have an API to start using npm run api
and the web server to start using npm run web
you can put those commands in start
using comma separation.
name: With servers
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm run api, npm run web
You can place the start commands in separate lines
with:
start: |
npm run api
npm run web
If you are starting a local server and it takes a while to start, you can add a parameter wait-on
and pass url to wait for the server to respond.
name: After server responds
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
# quote the url to be safe against YML parsing surprises
wait-on: 'http://localhost:8080'
By default, wait-on
will retry for 60 seconds. You can pass a custom timeout in seconds using wait-on-timeout
.
- uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'http://localhost:8080/status'
# wait for 2 minutes for the server to respond
wait-on-timeout: 120
You can wait for multiple URLs to respond by separating urls with a comma
- uses: cypress-io/github-action@v5
with:
# API runs on port 3050
# Web server runs on port 8080
start: npm run api, npm run web
# wait for all services to respond
wait-on: 'http://localhost:3050, http://localhost:8080'
The action will wait for the first url to respond, then will check the second url, and so on.
You can even use your own command (usually by using npm
, yarn
, npx
) to wait for the server to respond. For example, if you want to use wait-on utility to ping the server and run the Cypress tests after the server responds:
- uses: cypress-io/github-action@v5
with:
start: npm start
wait-on: 'npx wait-on --timeout 60000 http://localhost:3000'
See example-wait-on.yml workflow file.
If this action times out waiting for the server to respond, please see Debugging section in this README file.
Under Node.js version 18 and later, wait-on
may fail to recognize that a localhost
server is running. This affects development web servers which do not listen on both IPv4 and IPv6 network stacks.
- Check your server documentation to see if it can be started using
0.0.0.0
(all addresses) and use this if available. If this option is not available or does not resolve the issue then carry on to the next steps: - If the action log shows that
wait-on
is failing to connect to127.0.0.1
, replacelocalhost
by[::1]
(the IPv6 loopback address) - If the action log shows that
wait-on
is failing to connect to::1
, replacelocalhost
by127.0.0.1
(the IPv4 loopback address)
If you want to overwrite the install command
- uses: cypress-io/github-action@v5
with:
install-command: yarn --frozen-lockfile --silent
See example-install-command.yml workflow file.
You can prefix the default test command using the command-prefix
option. This is useful for example when running Percy, which requires the test command to be wrapped with percy exec --
.
name: Visual
on: push
jobs:
e2e:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
start: npm start
# quote the url to be safe against YML parsing surprises
wait-on: 'http://localhost:8080'
# the entire command will automatically be prefixed with "npm"
# and we need the second "npm" to execute "cypress run ..." command line
command-prefix: 'percy exec -- npx'
You can overwrite the Cypress run command with your own
steps:
- name: Checkout 🛎
uses: actions/checkout@v3
- name: Custom tests 🧪
uses: cypress-io/github-action@v5
with:
command: npm run e2e:ci
See .github/workflows/example-custom-command.yml file.
You can overwrite ci-build-id
used to link separate machines running tests into a single parallel run.
name: Parallel
on: push
jobs:
test:
runs-on: ubuntu-22.04
strategy:
matrix:
# run 3 copies of the current job in parallel
containers: [1, 2, 3]
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
record: true
parallel: true
group: 'Actions example'
ci-build-id: '${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }}'
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Tip: see Learn GitHub Actions, with sections on Expressions, Contexts and Environment variables.
If you re-run the GitHub workflow, if you use the same custom build id during recording, Cypress Cloud will cancel the run with "Build already finished" error. To avoid this, you need to generate a new custom build id on every workflow re-run. A good solution showing in the example-custom-ci-build-id.yml file is to run a common job first that just generates a new random ID. This ID can be used by the testing jobs to tie the build together. If the user re-runs the workflow a new unique build id is generated, allowing recording the new Cypress Cloud run.
jobs:
# single job that generates and outputs a common id
prepare:
outputs:
uuid: ${{ steps.uuid.outputs.value }}
steps:
- name: Generate unique ID 💎
id: uuid
# take the current commit + timestamp together
# the typical value would be something like
# "sha-5d3fe...35d3-time-1620841214"
run: echo "value=sha-$GITHUB_SHA-time-$(date +"%s")" >> $GITHUB_OUTPUT
smoke-tests:
needs: ['prepare']
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
record: true
parallel: true
ci-build-id: ${{ needs.prepare.outputs.uuid }}
env:
# pass the Cypress Cloud record key as an environment variable
CYPRESS_RECORD_KEY: ${{ secrets.EXAMPLE_RECORDING_KEY }}
See the example-custom-ci-build-id.yml for the full workflow
In a monorepo, the end-to-end or component test might be placed in a different sub-folder from the application itself.
Using a Cypress legacy configuration (Version 9 or earlier) the structure could look like this:
repo/
app/
app-test/
cypress/
fixtures/
integration/
plugins/
support/
cypress.json
package.json
For End-to-End testing using a Cypress configuration for Version 10 and later, the structure could look like this :
repo/
app/
app-test/
cypress/
e2e/
fixtures/
support/
cypress.config.js
package.json
Similarly for Component Testing with a Cypress configuration for Version 10 and later, the structure could look like this:
repo/
app/
app-test/
cypress/
component/
fixtures/
support/
cypress.config.js
package.json
You can specify the app-test
working directory when running Cypress tests using the working-directory
parameter
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
start: npm start
working-directory: app-test
See example-basic.yml for an End-to-End test example and example-component-test.yml for a Component test example, using the parameter working-directory
.
Sometimes Cypress and end-to-end tests have their own package.json
file in a subfolder, like
root/
e2e/
(code for installing and running Cypress tests)
package.json
package-lock.json
cypress.json
cypress
(code for running the "app" with "npm start")
package.json
yarn.lock
In that case you can combine this action with bahmutov/npm-install action to install dependencies separately.
name: E2E
on: push
jobs:
test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@master
- name: Install root dependencies
uses: bahmutov/npm-install@v1
- name: Start server in the background
run: npm start &
# Cypress has its own package.json in folder "e2e"
- name: Install Cypress and run tests
uses: cypress-io/github-action@v5
with:
working-directory: e2e
See cypress-gh-action-subfolders (legacy) for example.
The package manager pnpm
is not pre-installed in GitHub Actions runner images (unlike npm
and yarn
): to install pnpm
include pnpm/action-setup in your workflow. If the action finds a pnpm-lock.yaml
file, it uses the pnpm command pnpm install --frozen-lockfile
by default to install dependencies.
name: example-basic-pnpm
on: push
jobs:
basic-pnpm:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 7
- name: Cypress run
uses: cypress-io/github-action@v5
with:
working-directory: examples/basic-pnpm
If a yarn.lock
file is found, the action uses the Yarn 1 (Classic) command yarn --frozen-lockfile
by default to install dependencies.
name: example-yarn-classic
on: push
jobs:
yarn-classic:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
working-directory: examples/yarn-classic
See example-yarn-classic.yml for an example.
To install dependencies using a yarn.lock
file from Yarn Modern (Yarn 2 and later) you need to override the default Yarn 1 (Classic) installation command yarn --frozen-lockfile
. You can do this by using the install-command
parameter and specifying yarn install
for example:
name: example-yarn-modern
on: push
jobs:
yarn-classic:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
working-directory: examples/yarn-modern
install-command: yarn install
See example-yarn-modern.yml for an example.
This action should discover the Yarn workspaces correctly. For example, see folder examples/start-and-yarn-workspaces and workflow file example-start-and-yarn-workspaces.yml
name: example-start-and-yarn-workspaces
on: push
jobs:
single:
# the example has Yarn workspace in its "root" folder
# examples/start-and-yarn-workspaces
# and tests in a subfolder like "workspace-1"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
with:
working-directory: examples/start-and-yarn-workspaces/workspace-1
build: yarn run build
start: yarn start
wait-on: 'http://localhost:5000'
Sometimes the default cache key does not work. For example, if you cannot share the Node modules across Node versions due to native extensions. In that case pass your own cache-key
parameter.
name: End-to-end tests
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
# let's make sure our "app" works on several versions of Node
strategy:
matrix:
node: [14, 16, 18, 19]
name: E2E on Node v${{ matrix.node }}
steps:
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: Checkout
uses: actions/checkout@v3
# run Cypress tests and record them under the same run
# associated with commit SHA and just give a different group name
- name: Cypress run
uses: cypress-io/github-action@v5
with:
record: true
group: Tests on Node v${{ matrix.node }}
cache-key: node-v${{ matrix.node }}-on-${{ runner.os }}-hash-${{ hashFiles('yarn.lock') }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
You can run your tests across multiple Node versions.
name: Node versions
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
strategy:
matrix:
node: [14, 16, 18, 19]
name: E2E on Node v${{ matrix.node }}
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
Sometimes you may want to run additional commands between installation and tests. To enable this use the install
and runTests
parameters.
name: E2E
on: push
jobs:
test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@master
- name: Install dependencies
uses: cypress-io/github-action@v5
with:
# just perform install
runTests: false
- run: yarn lint
- name: Run e2e tests
uses: cypress-io/github-action@v5
with:
# we have already installed all dependencies above
install: false
# Cypress tests and config file are in "e2e" folder
working-directory: e2e
See cypress-gh-action-monorepo for working example.
Finally, you might not need this GH Action at all. For example, if you want to split the NPM dependencies installation from the Cypress binary installation, then it makes no sense to use this action. Instead you can install and cache Cypress yourself. See cypress-gh-action-split-install (legacy) for a working example.
If the project has many dependencies, but you want to install just Cypress you can combine this action with actions/cache
and npm i cypress
commands yourself.
- uses: actions/checkout@v3
- uses: actions/cache@v2
with:
path: |
~/.cache/Cypress
node_modules
key: my-cache-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- run: npm i cypress
- uses: cypress-io/github-action@v5
with:
install: false
See .github/workflows/example-install-only.yml file.
You can tell the CI to stop the job or the individual step if it runs for longer then a given time limit. This is a good practice to ensure the hanging process does not accidentally use up all your CI minutes.
jobs:
cypress-run:
runs-on: ubuntu-22.04
# stop the job if it runs over 10 minutes
# to prevent a hanging process from using all your CI minutes
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v5
# you can specify individual step timeout too
timeout-minutes: 5
See cypress-gh-action-example (legacy).
Name | Description |
---|---|
cypress-gh-action-small-example (legacy) | Runs tests and records them on Cypress Cloud |
cypress-gh-action-example (legacy) | Uses Yarn, and runs in parallel on several versions of Node, different browsers, and more |
cypress-gh-action-monorepo | Splits install and running tests commands, runs Cypress from sub-folder |
cypress-gh-action-subfolders (legacy) | Has separate folder for Cypress dependencies |
cypress-gh-action-split-install (legacy) | Only install NPM dependencies, then install and cache Cypress binary yourself |
cypress-gh-action-changed-files (legacy) | Shows how to run different Cypress projects depending on changed files |
cypress-examples | Shows separate install job from parallel test jobs |
cypress-gh-action-split-jobs (legacy) | Shows a separate install job with the build step, and another job that runs the tests |
This action installs local dependencies using lock files. Ensure that exactly one type of lock file is used for each project or working-directory from the following supported package managers:
Lock file | Package Manager | Installation command |
---|---|---|
package-lock.json |
npm | npm ci |
pnpm-lock.yaml |
pnpm | pnpm install --frozen-lockfile |
yarn.lock |
Yarn Classic | yarn --frozen-lockfile |
See section Yarn Modern for information about using Yarn version 2 and later.
Node.js is required to run this action. The current version v5
supports:
- Node.js 14.x
- Node.js 16.x
- Node.js 18.x and above
and is generally aligned with Node.js's release schedule.
This action uses the debug module to output additional verbose logs. You can see these debug messages by setting the following environment variable:
DEBUG: @cypress/github-action
You can set the environment variable using GitHub UI interface, or in the workflow file:
- name: Cypress tests with debug logs
uses: cypress-io/github-action@v5
env:
DEBUG: '@cypress/github-action'
See the example-debug.yml workflow file.
The above ACTIONS_STEP_DEBUG
setting enables the debug logs from the action itself. To see the Cypress debug logs add an environment variable to the action:
- name: Cypress tests with debug logs
uses: cypress-io/github-action@v5
env:
DEBUG: 'cypress:*'
If you have a problem with wait-on
not working, you can check the src/ping.js logic from the local machine.
- clone this repository to the local machine
- install dependencies with
npm install
- start your server
- from another terminal call the
ping
yourself to validate the server is responding:
$ node src/ping-cli.js <url>
For example
$ node src/ping-cli.js https://example.cypress.io
pinging url https://example.cypress.io for 30 seconds
::debug::pinging https://example.cypress.io has finished ok
- Read our blog post Drastically Simplify Testing on CI with Cypress GitHub Action
- Read Test the Preview Vercel Deploys blog post
- Creating actions docs
- practice using the Cypress GitHub Action by following the Cypress on CI Workshop
If you add workflow_dispatch
event to your workflow, you will be able to start the workflow by clicking a button on the GitHub page, see the Test External Site Using GitHub Actions video.
This action sets a GitHub step output dashboardUrl
if the run was recorded on Cypress Cloud using the action parameter setting record: true
(see Record test results on Cypress Cloud). Note that using a Custom test command with the command
parameter overrides the record
parameter and in this case no dashboardUrl
step output is saved.
This is an example of using the step output dashboardUrl
:
- name: Cypress tests
uses: cypress-io/github-action@v5
# let's give this action an ID so we can refer
# to its output values later
id: cypress
# Continue the build in case of an error, as we need to set the
# commit status in the next step, both in case of success or failure
continue-on-error: true
with:
record: true
env:
CYPRESS_RECORD_KEY: ${{ secrets.RECORDING_KEY }}
- name: Print Cypress Cloud URL
run: |
echo Cypress finished with: ${{ steps.cypress.outcome }}
echo See results at ${{ steps.cypress.outputs.dashboardUrl }}
Note: every GitHub workflow step can have outcome
and conclusion
properties. See the GitHub Contexts documentation section steps context. In particular, the outcome
or conclusion
value can be success
, failure
, cancelled
, or skipped
which you can use in any following steps.
Sometimes you might want to print Cypress and OS information, like the list of detected browsers. You can use the cypress info
command for this.
If you are NOT using the build
command in your project, you can run the cypress info
command:
name: info
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
build: npx cypress info
If you are already using the build
parameter, you can split the installation and the test steps and insert the cypress info
command in between:
name: info
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress install
uses: cypress-io/github-action@v5
with:
# just perform install
runTests: false
- name: Cypress info
run: npx cypress info
- name: Cypress run
uses: cypress-io/github-action@v5
with:
# we have already installed all dependencies above
install: false
# rest of your parameters
Sometimes you want to execute the workflow on a schedule. For example, to run Cypress tests nightly, you can schedule the workflow using cron
syntax:
name: example-cron
on:
schedule:
# runs tests every day at 4am
- cron: '0 4 * * *'
jobs:
nightly:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress nightly tests 🌃
uses: cypress-io/github-action@v5
See the example-cron.yml workflow.
The default test summary can be suppressed by using the parameter publish-summary
and setting its value to false
.
Sometimes users want to publish test summary using a specific action.
For example, a user running Cypress tests using a matrix and wants to retrieve the test summary for each matrix job and use a specific action that merges reports.
name: Example no summary
on: push
jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cypress run
uses: cypress-io/github-action@v5
with:
publish-summary: false
See Releases for full details of changes.
Version | Changes |
---|---|
v5 | Examples and workflows additionally use Node.js 18. Use of the end-of-life Node.js version 12 in examples and workflows is removed. |
v4.2.0 | Support for pnpm added. |
v4 | Support for Cypress 10 and later versions is added. |
v3 | Action runs under Node.js 16 instead of Node.js 12. |
v2 | Cypress runs using the NPM module API instead of being started via the command line. |
v1 | This version is no longer runnable in GitHub due to security changes. |
Note: GitHub announced their plan to disable save-state
and set-output
commands by May 31, 2023. This will prevent cypress-io/github-action version v4.2.1, and earlier, running after this date since they use set-output
. Affected users should update to using v5
of the cypress-io/github-action action before the deadline.
Please see our Contributing Guideline which explains how to contribute fixes or features to the repo and how to test.
This project is licensed under the terms of the MIT license.