Resolving Yarn2 + Cypress GitHub Action: Cannot find module ‘cypress’
--
An open issue exists for running the Cypress.io end-to-end test GitHub Action in a Yarn2 plug-and-play repository: the action fails with the following error:
Error: Cannot find module 'cypress'
Require stack:
- /home/runner/work/_actions/cypress-io/github-action/v2/dist/index.js
I dug into resolving this myself, and I found the root cause to be this line of the GitHub Action:
// If `command:` is provided, run it.
const customCommand = core.getInput('command')
if (customCommand) {
console.log('Using custom test command: %s', customCommand)
return execCommand(customCommand, true, 'run tests')
}// If `command-prefix:` is provided, use it.
const commandPrefix = core.getInput('command-prefix')
if (commandPrefix) {
return runTestsUsingCommandLine()
}// Otherwise, find `cypress` and run it.
debug('Running Cypress tests using NPM module API') debug(`requiring cypress dependency, cwd is ${process.cwd()}`)
debug(`working directory ${workingDirectory}`)
const cypressModulePath =
require.resolve('cypress', {
paths: [workingDirectory]
}) || 'cypress'
debug(`resolved cypress ${cypressModulePath}`)
In the above code, implementations that do not provide a command
or command-prefix
variable in the GitHub Action’s with
configuration fallback to the require.resolve
method in Node. This means that implementations that use command
(like command: yarn cypress
) or a command-prefix
will not encounter this error, since they will not reach the line that contains require.resolve
.
Resolving the path to cypress
fails on a Yarn2 repository, because the GitHub Action executes its Node script using NPM. It therefore makes the assumption that NPM installed its dependencies, despite otherwise checking for Yarn installations. I contributed a request to the original issue to support Yarn’s .pnp.cjs
file, which should patch require.resolve
to find modules installed using Plug and Play.
To unblock yourself until this gets formal support, add command-prefix: yarn dlx
. By replacing cypress run --flags
with yarn dlx cypress run --flags
, the Node module command is passed through yarn
first, which injects the .pnp.cjs
file for Plug and Play support.
While you can add a script to your package.json
file that contains cypress run — flags
, the command-prefix
option offers one important benefit over its command
alternative: automatically injecting flags as specified by with
. When you use command
, your configuration in with
will be ignored, requiring you to specify all your flags in the NPM script definition in package.json
. While this is fine for many use cases, allowing you to easily run your Cypress tests locally, it becomes problematic when using GitHub secrets (such as your record key) in your Cypress run.
For any souls brave to dive deeper than my investigation, the Cypress team might appreciate a pull request to resolve this issue in code. 😉