Module API

You can require Cypress as a node module from your application under test and run Cypress via Node.js. This can be useful when you want access to the test results directly after the run. With this workflow, for example, you can:

  • Send a notification about failing tests with included screenshot images
  • Rerun a single failing spec file
  • Kick off other builds or scripts

cypress.run()

Runs Cypress tests via Node.js and resolve with all test results. See the Cypress Module API recipe.

// e2e-run-tests.js
const cypress = require('cypress')

cypress.run({
  reporter: 'junit',
  browser: 'chrome',
  config: {
    baseUrl: 'http://localhost:8080',
    video: true,
  },
  env: {
    login_url: '/login',
    products_url: '/products',
  },
})

You can then run Cypress by running the following in your terminal or an npm script:

node e2e-run-tests.js

Options

Just like the Command Line options for cypress run, you can pass options that modify how Cypress runs.

OptionTypeDescription
browserstringSpecify different browser to run tests in, either by name or by filesystem path
ciBuildIdstringSpecify a unique identifier for a run to enable grouping or parallelization
configobjectSpecify configuration
configFilestring / booleanPath to the config file to be used. If false is passed, no config file will be used.
envobjectSpecify environment variables
groupstringGroup recorded tests together under a single run
headedbooleanDisplays the browser instead of running headlessly (default Firefox and Chromium-based browsers)
headlessbooleanHide the browser instead of running headed (defaults for Electron)
keystringSpecify your secret record key
exitbooleanWhether to close Cypress after all tests run
parallelbooleanRun recorded specs in parallel across multiple machines
portnumberOverride default port
projectstringPath to a specific project
quietbooleanIf passed, Cypress output will not be printed to stdout. Only output from the configured Mocha reporter will print.
recordbooleanWhether to record the test run
reporterstringSpecify a Mocha reporter
reporterOptionsobjectSpecify Mocha reporter options
specstringSpecify the specs to run, see examples below
tagstringIdentify a run with a tag or tags

Examples

Run a single spec file

Here is an example of programmatically running a spec file. Note that the file path is relative to the current working directory.

// e2e-run-tests.js
const cypress = require('cypress')

cypress
  .run({
    // the path is relative to the current working directory
    spec: './cypress/integration/examples/actions.spec.js',
  })
  .then((results) => {
    console.log(results)
  })
  .catch((err) => {
    console.error(err)
  })

You can then run Cypress by running the following in your terminal or an npm script:

node e2e-run-tests.js

Run specs using wildcard

You can pass a wildcard pattern to run all matching spec files

const cypress = require('cypress')

cypress.run({
  // the wildcard path is relative to the current working directory
  spec: './cypress/integration/**/api*.js',
})

Use modern syntax

If your Node version allows you can use the modern async / await syntax to wait for the Promise returned by the cypress.run method.

const cypress = require('cypress')

;(async () => {
  const results = await cypress.run()
  // use the results object
})()

Results

cypress.run() returns a Promise that resolves with an object containing the tests results. A typical run could return something like this:

{
  "cypressVersion": "3.0.2",
  "endedTestsAt": "2018-07-11T17:53:35.675Z",
  "browserName": "electron",
  "browserPath": "path/to/browser",
  "browserVersion": "59.0.3071.115",
  "config": {...},
  "osName": "darwin",
  "osVersion": "14.5.0",
  "runs": [{
    "error": null,
    "hooks": [{
      "hookName": "before each",
      "title": [ "before each hook" ],
      "body": "function () {\n  expect(true).to.be["true"];\n}"
    }],
    "reporter": "spec",
    "reporterStats": {...},
    "shouldUploadVideo": true,
    "spec": {...},
    "stats": {
      "suites": 1,
      "tests": 1,
      "passes": 0,
      "pending": 0,
      "skipped": 0,
      "failures": 1,
      "startedAt": "2020-08-05T08:38:37.589Z",
      "endedAt": "2018-07-11T17:53:35.675Z",
      "duration": 1171
    },
    "tests": [{
      "title": [ "test" ],
      "state": "failed",
      "body": "function () {\n  expect(true).to.be["false"];\n}",
      "displayError": "AssertionError: expected true to be false\n' +
      '    at Context.eval (...cypress/integration/spec.js:5:21",
      "attempts": [{
        "state": "failed",
        "error": {
          "message": "expected true to be false",
          "name": "AssertionError",
          "stack": "AssertionError: expected true to be false\n' +
      '    at Context.eval (...cypress/integration/spec.js:5:21"
        },
        "screenshots": [{
          "name": null,
          "takenAt": "2020-08-05T08:52:20.432Z",
          "path": "User/janelane/my-app/cypress/screenshots/spec.js/test (failed).png",
          "height": 720,
          "width": 1280
        }],
        "startedAt": "2020-08-05T08:38:37.589Z",
        "duration": 1171,
        "videoTimestamp": 4486
      }]
    }],
    "video": "User/janelane/my-app/cypress/videos/abc123.mp4"
  }],
  "runUrl": "https://dashboard.cypress.io/projects/def456/runs/12",
  "startedTestsAt": "2018-07-11T17:53:35.463Z",
  "totalDuration": 212,
  "totalFailed": 1,
  "totalPassed": 0,
  "totalPending": 0,
  "totalSkipped": 0,
  "totalSuites": 1,
  "totalTests": 1,
}

You can find the TypeScript definition for the results object in the cypress/cli/types folder.

Handling errors

Even when tests fail, the Promise resolves with the test results. The Promise is only rejected if Cypress cannot run for some reason (for example if a binary has not been installed or it cannot find a module dependency). In that case, the Promise will be rejected with a detailed error.

There is a third option - Cypress could run, but the tests could not start for some reason. In that case the resolved value is an object with two fields

{
  "failures": 1,    // non-zero number
  "message": "..."  // error message
}

In order to handle these possible errors, you can add a catch to cypress.run():

// e2e-run-tests.js
const cypress = require('cypress')

cypress.run({...})
.then(result => {
  if (result.failures) {
    console.error('Could not execute tests')
    console.error(result.message)
    process.exit(result.failures)
  }

  // print test results and exit
  // with the number of failed tests as exit code
  process.exit(result.totalFailed)
})
.catch(err => {
  console.error(err.message)
  process.exit(1)
})

cypress.open()

Open Cypress tests via Node.js.

// e2e-open-tests.js
const cypress = require('cypress')

cypress.open({
  config: {
    baseUrl: 'http://localhost:8080',
  },
  env: {
    login_url: '/login',
    products_url: '/products',
  },
})

You can then open Cypress by running the following in your terminal or an npm script:

node e2e-open-tests.js

Options

Just like the Command Line options, you can pass options that modify how Cypress runs.

OptionTypeDescription
browserstringSpecify a filesystem path to a custom browser
configobjectSpecify configuration
configFilestring / booleanPath to the config file to be used. If false is passed, no config file will be used.
detachedbooleanOpen Cypress in detached mode
envobjectSpecify environment variables
globalbooleanRun in global mode
portnumberOverride default port
projectstringPath to a specific project

Example

// e2e-open-tests.js
const cypress = require('cypress')

cypress.open({})

You can then open Cypress by running the following in your terminal or an npm script:

node e2e-open-tests.js

cypress.cli

parseRunArguments()

If you are writing a tool that wraps around the cypress.run() command, you might want to parse user-supplied command line arguments using the same logic as cypress run uses. In that case, you can use the included parseRunArguments function.

// wrapper.js
const cypress = require('cypress')

const runOptions = await cypress.cli.parseRunArguments(process.argv.slice(2))
const results = await cypress.run(runOptions)
// process the "cypress.run()" results

An example use running from your terminal could be:

node ./wrapper cypress run --browser chrome --config ...

Note: the arguments passed to parseRunArguments should start with cypress run.

We use CLI parsing and calling cypress.run to repeat tests to find flaky tests and to validate test numbers after a test run. Read Wrap Cypress Using npm Module API for more examples.

History

VersionChanges
5.0.0Test results returned from cypress.run() changed.
4.11.0Added cypress.cli with parseRunArguments function.
4.9.0Added quiet option to cypress.run()