Creating Custom Commands in Cypress using the PrevSubject option
How can we create functions in cypress like `.type`, `.click`, etc...? Yes, on this page we will learn how we can do that.
Tags
Basically, the prevSubject option controls whether the function will be used with a subject
, to have the result like this for example:
cy.get(selector).nameOfYourFunction(params)
Option | Accepts | Default |
---|---|---|
prevSubject | Boolean, String or Array | false |
The prevSubject accepts the following values:
false
: Ignore any previous subjectstrue
: Receives the previous subject as the first param (example 1)optional
: May start a chain, or use an existing chain (require some conditional to control - example 2)
In addition to controlling the command's implicit behavior, you can also add declarative subject validations such as:
element
: Requires the previous subject be a DOM elementdocument
: Requires the previous subject be the documentwindow
: Requires the previous subject be the window
Examples:
You can see the examples here, and run that if you want: Commands file in my application
Example 1
Look that in this example we are passing an array with the element value to prevSubject, it means that we just can pass an element as the subject.
Not is necessary to pass it as an array, we can pass just the "element" for this example.
Cypress.Commands.add('handleEmail', { prevSubject: [true, 'element'] }, (subject, text) => {
cy.wrap(subject).type('invalid-email')
cy.get('[data-cy=sign-in]').click()
cy.toastError()
cy.wrap(subject).clear().type(text)
})
Also, we can pass more than 1 validation to each function, like:
Cypress.Commands.add('handleSomething', { prevSubject: ['element', 'window', 'document'] }, (subject, ...args) => {
// Something that can use 3 type of prevSubjects...
})
Example 2
We can also create a function that, in addition to being able to use it with prevSubject, could be used in the normal model, take a look:
/**
* This function can be used with prevSubject or not.
*
* @memberOf cy
* @function handlePassword
*/
Cypress.Commands.add('handlePassword', { prevSubject: ['optional', 'element'] }, (subject, text) => {
if (subject) {
cy.wrap(subject).type(text).clear()
} else {
cy.get('[data-cy=password]').type(text)
}
})
Possible usages:
1: With prevSubject
cy.get('[data-cy=password]').handlePassword('St0n6Pass5rd')
2: Without prevSubject
cy.handlePassword('St0n6Pass5rd')
Thanks for reading, any suggestion is welcome!