Cypress version pinning: binary cache or Docker image for a repeatable test environment
0 reputation · 10 Mar 2021, 12:18 UTC
0 reputation · 10 Mar 2021, 12:18 UTC
Our team runs Cypress end-to-end tests on developer laptops and in CI, and we want every run to use the same Cypress binary and browser versions. Cypress documents two routes: the official Docker images (cypress/included pins Cypress plus specific Chrome, Firefox, Edge and Electron versions) or pinning the npm package version and managing the binary cache ourselves.
The npm route worries us. The Cypress binary is downloaded into a cache (default ~/.cache/Cypress on Linux) rather than installed by npm, so package-lock.json alone does not seem to guarantee a hermetic install. Variables like CYPRESS_INSTALL_BINARY and CYPRESS_CACHE_FOLDER also appear to change whether installs stay reproducible, and we are unsure how they interact with a clean CI workspace. Assume a current Cypress major version; we will confirm exact tag names and defaults against the docs.
There is also a browser question: the bundled Electron browser is pinned by the Cypress version, but system Chrome floats unless the image pins it, and we are not sure how far Electron results can stand in for real Chrome.
1. Is a pinned package-lock entry plus a controlled cache sufficient for bit-for-bit repeatable installs, or is Docker the only reliable option?
2. Which cache-related environment variables must be fixed in CI to avoid silent drift?
3. How should we handle Chrome version skew if we stay outside Docker?
34775 reputation · 10 Mar 2021, 18:49 UTC
Yes. When you lock the Cypress npm version in package-lock.json and force a deterministic cache location, the same binary is downloaded every run, giving bit‑for‑bit repeatability.
npm install cypress@13.6.0 --save-exact (or use --save with an exact version in package.json).export CYPRESS_CACHE_FOLDER=$RUNNER_TEMP/cypress-cache (or any directory that is cleared for each job).export CYPRESS_INSTALL_BINARY=1. If you prefer to pre‑populate the cache, set CYPRESS_INSTALL_BINARY=0 and ensure the folder already contains the exact binary.unset CYPRESS_DOWNLOAD_SKIP and unset CYPRESS_NODE_BINARY.npm ci (or npm install) in a clean workspace.The variables that influence where and whether the binary is fetched are:
CYPRESS_CACHE_FOLDER – must point to a dedicated, isolated directory per job.CYPRESS_INSTALL_BINARY – set to 1 to guarantee a download, or 0 only if you have verified the cache already holds the correct binary.CYPRESS_DOWNLOAD_SKIP – should be unset or explicitly 0.CYPRESS_NODE_BINARY – should be unset unless you intentionally want to use a custom Node binary.Fixing these four ensures the same binary is used regardless of the worker’s global ~/.cache/Cypress state.
Cypress bundles Electron, which has its own Chromium base. To match the Chrome version used by the official Docker images you have two practical options:
cypress/included:13.6.0 the Chrome version is 114.0.5735.90). On Ubuntu you can do:# Example: install Chrome 114.0.5735.90
wget -q https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_114.0.5735.90-1_amd64.deb
sudo dpkg -i google-chrome-stable_114.0.5735.90-1_amd64.deb
sudo apt-get install -f # resolve dependencies
chrome-aws-lambda (or playwright-chromium) and launch Cypress with cypress open --browser chrome pointing to that binary via CYPRESS_browser or the browser configuration.If you cannot lock Chrome, accept that Electron‑based tests may diverge in CSS, JavaScript engine, or security features. In that case run a subset of critical tests against real Chrome (installed as above) to validate fidelity.
npx cypress version and npx cypress info.shasum -a 256 $(npx cypress cache path)/cypress and compare to a stored hash.google-chrome --version.https://example.com and assert an element) in both the npm‑cache setup and the Docker image; identical outcomes indicate repeatability.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.