Writing a Plugin

The Plugins API allows you to hook into and extend Cypress behavior.

Plugins API

To get started, open up this file:

cypress/plugins/index.js

The plugins file must export a function with the following signature:

// cypress/plugins/index.js

// export a function
module.exports = (on, config) => {
  // configure plugins here
}

The exported function is called whenever a project is opened either with cypress open or cypress run.

Your function will receive 2 arguments: on and config.

You can return a synchronous function, or you can also return a Promise, and it will be awaited until it resolves. This enables you to perform asynchronous actions in your exported function such as reading files in from the filesystem.

If you return or resolve with an object, Cypress will then merge this object into the config which enables you to overwrite configuration or environment variables.

on

on is a function that you will use to register listeners on various events that Cypress exposes.

Registering to listen on an event looks like this:

module.exports = (on, config) => {
  on('<event>', (arg1, arg2) => {
    // plugin stuff here
  })
}

Each event documents its own argument signature. To understand how to use them, please refer to the docs for each one.

config

config is the resolved Cypress configuration of the opened project.

This configuration contains all of the values that get passed into the browser for your project.

For a comprehensive list of all configuration values look here.

Some plugins may utilize or require these values, so they can take certain actions based on the configuration.

You can programmatically modify these values and Cypress will then respect these changes. This enables you to swap out configuration based on things like the environment you're running in.

Please check out our API docs for modifying configuration here.

List of events

The following events are available:

EventDescription
after:runOccurs after the run is finished.
after:screenshotOccurs after a screenshot is taken.
after:specOccurs after a spec is finished running.
before:browser:launchOccurs immediately before launching a browser.
before:runOccurs before the run starts.
before:specOccurs when a spec is about to be run.
file:preprocessorOccurs when a spec or spec-related file needs to be transpiled for the browser.
taskOccurs in conjunction with the cy.task command.

Execution context

Your pluginsFile is invoked when Cypress opens a project.

Cypress does this by spawning an independent child_process which then requires in your pluginsFile. This is similar to the way Visual Studio Code or Atom works.

The code in this file will be executed using the the Node version that launched Cypress.

npm modules

When Cypress executes your pluginsFile it will execute with process.cwd() set to your project's path. Additionally - you will be able to require any node module you have installed.

You can also require local files relative to your project.

For example, if your package.json looked like this:

{
  "name": "My Project",
  "dependencies": {
    "debug": "x.x.x"
  },
  "devDependencies": {
    "lodash": "x.x.x"
  }
}

Then you could do any of the following in your pluginsFile:

// cypress/plugins/index.js

const _ = require('lodash') // yup, dev dependencies
const path = require('path') // yup, built in node modules
const debug = require('debug') // yup, dependencies
const User = require('../../lib/models/user') // yup, relative local modules

console.log(__dirname) // /Users/janelane/Dev/my-project/cypress/plugins/index.js

console.log(process.cwd()) // /Users/janelane/Dev/my-project

Error handling

Cypress spawns your pluginsFile in its own child process so it is isolated away from the context that Cypress itself runs in. That means you cannot accidentally modify or change Cypress's own execution in any way.

If your pluginsFile has an uncaught exception, an unhandled rejection from a promise, or a syntax error - we will automatically catch those and display them to you inside of the console and even in the Test Runner itself.

Errors from your plugins will not crash Cypress.

File changes

Normally when writing code in Node, you typically have to restart the process after changing any files.

With Cypress, we automatically watch your pluginsFile and any changes made will take effect immediately. We will read the file in and execute the exported function again.

This enables you to iterate on plugin code even with Cypress already running.