How to override the subject option command in Cypress

868 Views Asked by At

Cypress says

options is only supported for use in Cypress.Commands.add() and not supported for use in Cypress.Commands.overwrite()

So we can't change the subject behavior when overwriting a command, and We can't add a new command with the same name as a core command (link).

How can I create a find command with my own custom behavior and an optional subject.

(Note: I would take a different name, but I guess find and get are the most readable and are already part of the Cypress)

// this is just an example of a custom find
Cypress.Commands.overwrite('find', (originalFn, selector, options) => {
  return cy.log('my custom find')
})

cy.get('body').find('div') // OK
cy.find('div')             // throws ERROR (I want this to be possible)

2

There are 2 best solutions below

1
On

Not sure if you're just giving an example, but cy.find('div') (if it were valid syntax) is equivalent to cy.get('div') because get always searches from <body>.

The whole reason find exists is to search from a different element, a shorthand for .within()

cy.get('my-parent-element').within(() => {
  cy.get('my-child-element')
})

// is equivalent to

cy.get('my-parent-element').find('my-child-element')

In the general case, if you're not using typescript you can just go ahead and add new properties to the options parameter and access them inside the overwrite.

If you are using typescript, you need to amend the type definition to include the new option.

0
On

You're correct you cannot provide options to command overwrite.

But you can substitute cy.find() with a new command.

Cypress.Commands.add('find2', 
  { prevSubject: ['optional', 'window', 'document', 'element'] },
  (subject, selector, options) => {

    const originalFn = Cypress.Commands._commands.find.fn;
    if (subject) {
      return originalFn(subject, selector, options)
    } else {
      cy.get('body').then($body => {
        return originalFn($body, selector, options)
      })
    }
})
cy.find = cy.find2

cy.get('div').find('p')   // ✅ 
cy.find('div')            // ✅