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
1 | const { defineConfig } = require('cypress') |
In the spec file, we can write
1 | it('adds two numbers using a task', () => { |
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.
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
1 | declare namespace Cypress { |
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
The cy.task('add', ...)
yields a number according to our definition.
Beautiful.
🎁 You can find the source code for this blog post in the repo bahmutov/cypress-task-typed.