packages/electron/README.md
This package is responsible for installing, building, and managing the Electron binary that powers Cypress. It enables development with an Electron shell that matches the final compiled Cypress binary 1:1 by using symlinks during development.
The package uses TypeScript to compile to CJS. ESM builds are not run by default, but can be enabled or tested with build:esm.
dist/cjs/, and a binary in dist/Cypress.# Build both CommonJS and ES Module versions
yarn workspace @packages/electron build
# Build only CommonJS version
yarn workspace @packages/electron build:cjs
# Build only ES Module version
yarn workspace @packages/electron build:esm
# Clean build artifacts
yarn workspace @packages/electron clean-deps
Note: The build process compiles TypeScript source to JavaScript. The --install command packages the actual Electron binary for your OS-specific platform.
The package provides a binary script cypress-electron with several commands:
# Install/build Electron binary for current platform
./bin/cypress-electron --install
# Show help and usage information
./bin/cypress-electron --help
# Launch an Electron app (development mode)
./bin/cypress-electron /path/to/your/app
# Launch with debugging enabled
./bin/cypress-electron /path/to/your/app --inspect-brk
These commands are parsed out from argv in the cli() function defined in ./lib/electron.ts
/**
* Checks if Electron binary exists and is up-to-date, installs if needed
*/
function installIfNeeded(): Promise<void>
/**
* Forces installation of Electron binary with optional arguments
*/
function install(...args: any[]): Promise<void>
/**
* Launches an Electron app with the specified path and arguments
* @param appPath - Path to the application to launch
* @param argv - Command line arguments to pass to the app
* @param callback - Optional callback when the app exits
* @returns Promise that resolves to the spawned Electron process
*/
function open(
appPath: string,
argv: string[],
callback?: (code: number) => void
): Promise<ChildProcess>
/**
* Returns the Electron version being used
* @returns String version (e.g., "36.4.0")
*/
function getElectronVersion(): string
/**
* Returns the Node.js version bundled with Electron
* @returns Promise that resolves to Node.js version string
*/
function getElectronNodeVersion(): Promise<string>
/**
* Returns the icons package for platform-specific icon paths
* @returns Icons package object
*/
function icons(): any
/**
* CLI entry point for command-line operations
* @param argv - Command line arguments array
*/
function cli(argv: string[]): void
# Run unit tests
yarn workspace @packages/electron test
# Run tests with debugger
yarn workspace @packages/electron test-debug
# Run tests in watch mode
yarn workspace @packages/electron test-watch
packages/electron/
├── bin/ # Binary scripts
│ └── cypress-electron # Main CLI script
├── lib/ # TypeScript source
│ ├── electron.ts # Main entry point and CLI logic
│ ├── install.ts # Installation and packaging logic
│ ├── paths.ts # Platform-specific path resolution
│ └── print-node-version.ts
├── dist/ # Compiled output
│ ├── cjs/ # CommonJS build
│ ├── esm/ # ES Module build
│ └── Cypress/ # Electron app binary (created by --install)
├── app/ # App template for packaging
└── test/ # Test files
The version of electron that is bundled with Cypress should be kept as up-to-date as possible with the stable Electron releases. Many users expect the bundled Chromium and Node.js to be relatively recent. Also, historically, it has been extremely difficult to upgrade over multiple major versions of Electron at once, because of all the breaking changes in Electron and Node.js that impact Cypress.
Upgrading electron involves more than just bumping this package's package.json. Here are additional tasks to check off when upgrading Electron:
Write accurate changelog items. The "User-facing changelog" for an Electron upgrade should mention the new Node.js and Chromium versions bundled. If this is a patch version of electron, a changelog entry might not be needed.
electron from 21.0.0 to 25.8.4.16.16.0 to 18.15.0.106.0.5249.51 to 114.0.5735.289.Determine if the Electron upgrade is a breaking change. Electron upgrades constitute "breaking changes" in Cypress if:
.js fixtures, or Create and publish Docker base-internal family images matching the Node.js and Chromium versions in Electron. These images live inside the cypress-docker-images repository. The base-internal images will be used inside our CI pipelines. For general use of Cypress in Docker, we encourage the use of the Cypress Docker Factory. This works great for using Cypress as an end user, but doesn't fully suit the needs for developing Cypress, as we require:
curl, xauth, and build-essential/make needed for our circleci jobs/pipelines.ubuntu.These images are currently created on an 'as-needed' basis and are published manually to the cypress docker repository. When creating these images, make sure:
Update src/@workflows.yml
base-internal Docker imagesEnsure that a matching Node.js version is enforced in the monorepo for local development and CI. When Electron is upgraded, oftentimes, the bundled Node.js version that comes with Electron is updated as well. Because all unit and integration tests run in normal Node.js (not Electron's Node.js), it's important for this Node.js version to be synced with the monorepo. There are a few places where this needs to be done:
/.node-version - used by some Node version managers/.nvmrc - used by nvm@types/node used throughout the monorepo to determine compatible node types. The major version of this package must reflect the node version set in /.node-version.develop must also be updated. A repository administrator will need to accomplish this./package.json - update enginesdocker-compose.yml - update Docker image to the new matching internal image/system-tests/test-binary/* - update binary system tests to use the newly published Ubuntu and Node images mentioned above, if applicable Update better-sqlite3 version if needed Look through the commit history of better-sqlite3 and find the first version that supports the proper version of electron's prebuilds. Update /packages/server/package.json and /packages/types/package.json to the appropriate version.
Update cypress-publish-binary For binary publishing, make sure the electron version that we updated in /package.json matches the electron version inside the publish binary project. This is to make sure add-on tests inside the publish-binary repository work locally, but are not required to install the correct version of electron in CI when publishing the binary. Ensure the electron target in this project's .circleci configuration is updated as well. Set the Remove this before merging, and ensure that branch is merged as well.
cypress-publish-binaryelectron version in package.jsonelectron version in the circle configuration&full-workflow-filters anchor in @pipeline.ymlpublish-binary-branch parameter to the branch you created in the cypress-publish-binary repository. Manually smoke test cypress open. Upgrading Electron can break the desktop-gui in unexpected ways. Since testing in this area is weak, double-check that things like launching cypress open, signing into Cypress Cloud, and launching Electron tests still work.
Manually smoke test cypress run in record mode Upgrading Electron can cause better-sqlite3 to SIGSEGV the Electron process.
Fix failing tests. Usually, these are due to breaking changes in either Node.js or Electron. Check the changelogs of both to find relevant changes.
If needed, update the V8 Snapshot Cache by running the GitHub workflow. Make sure to use the branch that contains the electron updates to populate the 'workflow from' and 'branch to update' arguments. Select 'Generate from scratch' and 'commit directly to branch'. This will usually take 6-8 hours to complete and is best to not be actively developing on the branch when this workflow runs.
yarn build:cjs (or yarn build for both formats)./bin/cypress-electron --installyarn testEnable debug logging by setting the DEBUG environment variable:
DEBUG=cypress:electron* ./bin/cypress-electron --install
DEBUG=cypress:electron:install* ./bin/cypress-electron --install
@electron/packager and other dev dependencies are available./bin/cypress-electron --install to create the Electron binaryWhen contributing to this package:
yarn build:cjs./bin/cypress-electron --installFor more detailed information about the build system, see BUILD.md.
Solution: Update the string representation of fs.readFileSync in scripts/binary/binary-integrity-check-source.js to match the string generated by the new version of electron. To do this, create a throw-away script that runs console.log(fs.readFileSync.toString()). Execute this with Electron rather than Node (ie. npm i -g [email protected] && electron throwaway-script.js).
Solution: This error is benign. From time to time, the error message we match against in order to swallow the error changes. Update the necessary support files with the new error message.
Solution: This is often due to a mismatched prebuild of better-sqlite3. Ensure your repository is clear of untracked files with git clean -xfd, and run yarn again. If the issue persists, ensure you are running the latest version of your operating system. Electron prebuilds key to darwin/linux/windows, and do not differentiate between versions of the same.
If you run into an error like below, please try some of the strategies below.
Could not detect abi for version X.X.X and runtime electron. Updating "node-abi" might help solve this issue if it is a new release of electron
Solution: See if there's a new version of @electron/rebuild with a newer version of node-abi within it. If there is not a newer version, find the latest release of node-abi that has an updated ABI registry with an abi entry matching the major version of Electron that you're updating to. Set this node-abi version in the resolutions of our package.json file and rerun yarn.