When to use: Run Cypress pipelines for merge requests, default branch, and scheduled jobs in GitLab. Prerequisites: parallel-and-sharding.md, reporting-and-artifacts.md, docker-and-containers.md
npm ci
npx cypress verify
npx cypress run --browser chrome --headless
npx cypress run --record --parallel --group "gitlab-linux"image: cypress/browsers:node-20.11.1-chrome-121-ff-122
stages:
- test
variables:
CI: "true"
npm_config_cache: "$CI_PROJECT_DIR/.npm"
cache:
key:
files:
- package-lock.json
paths:
- .npm/
- node_modules/
cypress-e2e:
stage: test
script:
- npm ci
- npx cypress verify
- npx cypress run --browser chrome --headless
artifacts:
when: always
paths:
- cypress/screenshots/
- cypress/videos/
- cypress/results/
expire_in: 14 days
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHimage: cypress/browsers:node-20.11.1-chrome-121-ff-122
stages:
- test
cypress-parallel:
stage: test
parallel: 4
script:
- npm ci
- npx cypress verify
- |
npx cypress run \
--record \
--parallel \
--group "gitlab-linux-chrome"
variables:
CYPRESS_RECORD_KEY: $CYPRESS_RECORD_KEY
CYPRESS_PROJECT_ID: $CYPRESS_PROJECT_ID
CYPRESS_BASE_URL: $CYPRESS_BASE_URL
artifacts:
when: always
paths:
- cypress/screenshots/
- cypress/videos/
expire_in: 7 days
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHstages:
- lint
- component
- e2e
lint:
stage: lint
script:
- npm ci
- npm run lint
component:
stage: component
script:
- npm ci
- npx cypress run --component --browser chrome --headless
e2e:
stage: e2e
script:
- npm ci
- npx cypress run --e2e --browser chrome --headlessWhen the repo contains the Cypress handover package checks, publish the dedicated Pester results as an artifact:
handover-docs:
stage: test
script:
- pwsh -NoProfile -File ./scripts/check-cypress-handover-pester.ps1 -ResultsPath ./artifacts/pester/cypress-handover.xml
artifacts:
when: always
paths:
- artifacts/pester/
expire_in: 14 days
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHUse this alongside the main docs quality gate when you want a dedicated machine-readable result file for the handover package tests.
Use GitLab CI variables for credentials:
CYPRESS_BASE_URLCYPRESS_USER_EMAILCYPRESS_USER_PASSWORDCYPRESS_RECORD_KEY(if using Cloud)
Avoid committing .env secrets into the repository.
| Anti-pattern | Problem | Better approach |
|---|---|---|
| Single long job for all checks | Slow feedback and noisy logs | Split CT/E2E/lint |
| No artifacts on failure | Root cause is hard to diagnose | Always keep screenshots/videos/results |
| Running tests only on main | Late failure discovery | Run on merge requests |
- Use an image with browsers preinstalled (
cypress/browsersorcypress/included). - Confirm Docker executor supports required shared memory settings.
- Isolate test data per pipeline.
- Avoid shared mutable test accounts.
- Keep retries low and investigate failing specs.
- Confirm the job runs
check-cypress-handover-pester.ps1with-ResultsPath. - Confirm
artifacts/pester/is included in GitLab artifacts. - If the repo image lacks PowerShell or Pester, use a job image that can run
pwshand install Pester first.