Cypress NPM module API
Cypress test runner has NPM module API that lets you call Cypress programmatically from a Node script. For example, you might get the number of passing and failed tests from the test results.
1 | const cypress = require('cypress') |
When cypress.run
executes, it resolves with an object that contains detailed information about all tests that Cypress executed or skipped. But before we can check the test results, we must check if Cypress ran at all - maybe the Cypress binary was not installed? Thus we check using status
property:
1 | cypress.run(options) |
Thus we check runResults.status
property that can be either failed
or finished
to tell if the Test Runner executed before drilling into the test results.
How do we get the right options
object to pass into cypress.run
call? You do not want to implement your own CLI parsing logic - because it might parse arguments differently from Cypress' CLI. Recently we have introduced an utility to parse the cypress run ...
command line arguments to make creating such Node wrappers very easy.
Parsing the CLI arguments
When running Cypress, you might be passing cypress run CLI parameters to use a specific the browser, record the test results on the Cypress Dashboard:
1 | npx cypress run --browser chrome --record |
How would you pass the same CLI arguments to cypress.run({...})
Node call? You need to parse the CLI arguments and convert to the equivalent options object. Recently we have exposed the CLI parsing logic to allow you to do exactly this:
1 | const cypress = require('cypress') |
If we run this wrap script, it will accurately transform the CLI arguments to an options object
1 | node ./src/wrap run --browser chrome --record |
The same code is used internally by npx cypress run
code, thus the Cypress behavior should be the same.
Meta testing
Now that we parse the Cypress arguments using the its own logic, we can create useful cypress run
wrappers. For example, I might want to validate the number of passing tests in a project to ensure that accidentally we don't skip bunch of tests and get a green build only because the tests were not run.
Tip: you can find this wrapper in bahmutov/cypress-expect
The wrapper needs its own command line parameters, for example we want to specify the number of tests, and the rest of the arguments should go into cypress.cli.parseRunArguments
like this:
1 | run Cypress tests in Chrome browser, record on the Dashboard |
The cypress-expect
needs to grab its own parameter --expect
and then let Cypress' logic to parse the rest of the arguments. We can use the parsing module arg for this:
1 |
|
Once Cypress runs, we can check if the two numbers match - and if they don't we can fail the program.
1 | const testResults = await cypress.run(cypressOptions) |
On top of the exact match, we can specify the minimum expected number of passing tests. We can even extend the program in the future to do meta-testing - allow specifying tests we expect to fail or to skip.
Repeat tests
If our tests suffer from flake, we can run the tests multiple times to catch the flaky behavior. The project cypress-repeat does exactly this - it runs the same project the specified number of times to flush out conditions leading to flaky tests.
1 | npx cypress-repeat run -n <N> ... rest of "cypress run" arguments |
The arguments are parsed the same way as in cypress-expect
1 |
|
Then we iterate and run the same test N times - and we can adjust the options to avoid clashing with previously recorded groups.
1 | const Bluebird = require('bluebird') |
By using cypress-repeat
and running projects five, even ten times in a row on CI we are able to flush out all the weird test situations that cause flake and finally fix them.
Link to Cypress Dashboard
If you record a Cypress run with cypress run --record
you will see the Dashboard URL shown in the terminal output.
1 | (Run Starting) |
If you have your own CI scripts you might want to grab this URL to send in a build notification or add to a test status page, linking back to the recorded run. Now it is simple to do by writing own wrapper
1 | cypress.run(...) |
Links
- bahmutov/cypress-expect wrapper lets you specify the total expected number of passing tests
- bahmutov/cypress-repeat runs Cypress multiple times in a row
- Cypress NPM module .d.ts file has the latest type information for
cypress.run
results