Writing a Plugin
The Plugins API allows you to hook into and extend Cypress behavior.
Note: This document assumes you have read the Plugins Guide.
Deprecated
Configuring plugins via cypress/plugins/index.js
is no longer supported as of
Cypress version 10.0.0.
We recommend that you update your configuration. Please see the plugins guide and the migration guide for more information on how to update your configuration.
Plugins API
The setupNodeEvents
function (or deprecated
plugins file function)
receives 2 arguments: on
and config
. It can return a
synchronous value or can also return a Promise, which will be awaited until it
resolves. This enables you to perform asynchronous actions 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.
const { defineConfig } = require('cypress')
module.exports = defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
// configure plugins here
}
}
})
import { defineConfig } from 'cypress'
export default defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
// configure plugins here
}
}
})
The plugins file is no longer supported as of Cypress version 10.0.0.
We recommend that you update your configuration. Please see the plugins guide and the migration guide for more information.
// cypress/plugins/index.js
module.exports = (on, config) => {
// configure plugins here
}
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:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
on('<event>', (arg1, arg2) => {
// plugin stuff here
})
}
}
})
import { defineConfig } from 'cypress'
export default defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
on('<event>', (arg1, arg2) => {
// plugin stuff here
})
}
}
})
The plugins file is no longer supported as of Cypress version 10.0.0.
We recommend that you update your configuration. Please see the plugins guide and the migration guide for more information.
// cypress/plugins/index.js
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.
Some plugins may utilize or require these values, so they can take certain actions based on the configuration. If these values are programmatically modified, Cypress will use the new values.
The config
object also includes the following extra values that are not part
of the standard configuration. These values are read only and cannot be
modified from the plugins file.
configFile
: The absolute path to the Cypress configuration file. See the --config-file and configFile docs for more information on this value.projectRoot
: The absolute path to the root of the project (e.g./Users/me/dev/my-project
)version
: The version number of Cypress. This can be used to handle breaking changes.
Please check out our API docs for modifying configuration here.
List of events
The following events are available:
Event | Description |
---|---|
after:run | Occurs after the run is finished. |
after:screenshot | Occurs after a screenshot is taken. |
after:spec | Occurs after a spec is finished running. |
before:browser:launch | Occurs immediately before launching a browser. |
before:run | Occurs before the run starts. |
before:spec | Occurs when a spec is about to be run. |
file:preprocessor | Occurs when a spec or spec-related file needs to be transpiled for the browser. |
task | Occurs in conjunction with the cy.task command. |
Execution context
The setupNodeEvents
function (or deprecated
plugins file function) is
invoked when Cypress opens a project.
Cypress does this by spawning an independent child_process
which then
requires
the Cypress configuration file.
This is similar to the way Visual Studio Code or Atom works.
This code will be executed using the the Node version that launched Cypress.
npm modules
When Cypress executes the
setupNodeEvents
function
(or deprecated plugins file
function) 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, including local files inside 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 setupNodeEvents
function:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
const _ = require('lodash') // yup, dev dependencies
const path = require('path') // yup, core node library
const debug = require('debug') // yup, dependencies
const User = require('./lib/models/user') // yup, relative local modules
console.log(__dirname) // /Users/janelane/Dev/my-project
console.log(process.cwd()) // /Users/janelane/Dev/my-project
}
}
})
import { defineConfig } from 'cypress'
export default defineConfig({
// setupNodeEvents can be defined in either
// the e2e or component configuration
e2e: {
setupNodeEvents(on, config) {
const _ = require('lodash') // yup, dev dependencies
const path = require('path') // yup, core node library
const debug = require('debug') // yup, dependencies
const User = require('./lib/models/user') // yup, relative local modules
console.log(__dirname) // /Users/janelane/Dev/my-project
console.log(process.cwd()) // /Users/janelane/Dev/my-project
}
}
})
The plugins file is no longer supported as of Cypress version 10.0.0.
We recommend that you update your configuration. Please see the plugins guide and the migration guide for more information.
// cypress/plugins/index.js
module.exports = (on, config) => {
const _ = require('lodash') // yup, dev dependencies
const path = require('path') // yup, core node library
const debug = require('debug') // yup, dependencies
const User = require('../../lib/models/user') // yup, relative local modules
console.log(__dirname) // /Users/janelane/Dev/my-project
console.log(process.cwd()) // /Users/janelane/Dev/my-project
}
Error handling
The Cypress configuration file is loaded 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 setupNodeEvents
function (or deprecated
plugins file function) has an
uncaught exception, an unhandled rejection from a promise, or a syntax error -
Cypress will automatically catch those and display them to you inside of the
console and even in Cypress itself.
Errors in your setupNodeEvents
function will not crash Cypress.
File changes
Normally when writing code in Node, you typically have to restart the process after changing any files.
Cypress automatically watches your Cypress configuration file 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.