Type cy.task Command

How to write types for "cy.task" operations and its options argument.

Imagine your Cypress spec calling a cy.task command to run some code in Node.js. For this example, I will simply add two numbers by defining a task handler in the Cypress config file

cypress.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const { defineConfig } = require('cypress')

module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
add({ a, b }) {
console.log('adding %d + %d', a, b)
return a + b
},
})
},
},
})

In the spec file, we can write

cypress/e2e/spec.cy.ts
1
2
3
4
5
it('adds two numbers using a task', () => {
cy.task('add', { a: 2, b: 3 }).should((x) => {
expect(x).to.equal(5)
})
})

Note: I am using a should(x => ...) function to show the type of the x argument yielded by the cy.task command. Normally, I would simply write an assertion like this cy.task('add', { a: 2, b: 3 }).should('equal', 5)

When we write cy.task('add', options) our VSCode is no help. It does not know what the options object should be, since it cannot "look" into the cypress.config.js file and its on('task') definitions.

No IntelliSense for cy.task command

If you read my Cypress Env Types you might guess how we can fix it. We can describe our tasks by typing the methods like task('add', ...) on the global Cypress cy object and let TypeScript merge global interfaces together in our project. We need to create an ambient type definition file

cypress/index.d.ts
1
2
3
4
5
6
7
8
9
10
11
declare namespace Cypress {
interface Chainable {
/**
* Adds two numbers in Node and yields their sum
*/
task(
event: 'add',
options: { a: number; b: number },
): Chainable<number>
}
}

Our tsconfig.json needs to include the "cypress" package types. The namespaces Cypress and interfaces Cypress.Chainable between our index.d.ts and node_modules/cypress/types/index.d.ts are merged by TypeScript. Let's see how VSCode shows IntelliSense popup now

Custom type for cy.task with the first argument equal to "add"

The cy.task('add', ...) yields a number according to our definition.

Yields a number

Beautiful.

🎁 You can find the source code for this blog post in the repo bahmutov/cypress-task-typed.