3

I am trying to overwrite the Cypress visit method so that it can close the toast when the page is loaded. This is a draft which is trying just to get the element's length.

Cypress.Commands.overwrite('visit', (originalVisit, url, options = {}) => {
    options.onLoad = () => {
        const len = cy.get(BasePage.genericLocators.notificationToasts.releaseVersionToast).its.length;
        console.log(len);
    };
    return originalVisit(url, options);
});

Continuously facing the following error:

Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.

The command that returned the promise was:

cy.visit()

The cy command you invoked inside the promise was:

cy.get()

Because Cypress commands are already promise-like, you don't need to wrap them or return your own promise.

Cypress will resolve your command with whatever the final Cypress command yields.

This is an error instead of a warning because Cypress internally queues commands serially whereas Promises execute as soon as they are invoked. Attempting to reconcile this would prevent Cypress from ever resolving.

TesterDick
  • 3,830
  • 5
  • 18
Nikki
  • 31
  • 2
  • You could try changing your first line inside onload to this ```cy.get(BasePage.genericLocators.notificationToasts.releaseVersionToast).then((len) => { // check length here})``` – TheFlorinator Oct 11 '22 at 20:17

1 Answers1

0

Unfortunately, you can't use Cypress queued commands such as cy.get() inside a callback like onload(), but you could use Cypress.$() instead.

Cypress.Commands.overwrite('visit', (originalVisit, url, options = {}) => {
  options.onLoad = () => {
    const toast = Cypress.$(BasePage.genericLocators.notificationToasts.releaseVersionToast);
    console.log(toast.length);
  };
  return originalVisit(url, options);
});

although since the element is a toast, you probably won't catch it like that since there is no retry on Cypress.$().


Commands with retry

Alternatively, just run your onload code sequentially in the test.

cy.visit('/')
cy.get(BasePage.genericLocators.notificationToasts.releaseVersionToast)
  .should('be.visibile') 
  .click()                  // close the toast

Using .should('be.visibile') would be necessary to catch a transitory element such as a toast message.


As a command overwrite

You can do the above inside the command overwrite by using a cy.wrap(), but if you need to use the window object after cy.visit() you will need to re-wrap that.

Cypress.Commands.overwrite('visit', (originalVisit, url, options = {}) => {
  return cy.wrap(originalVisit(url, options))
    .then((win) => {
      
      // click the toast away      
      cy.get(BasePage.genericLocators.notificationToasts.releaseVersionToast)
        .should('be.visibile') 
        .click();

      //re-wrap the win so that cy.visit() has same return value as before
      cy.wrap(win)
    })
})

cy.visit('/')
  .then(win => {
    // can use AUT window here as usual
  })

Note standard cy.visit() already waits for the page load event to fire, so you don't need to explicitly do that.

TesterDick
  • 3,830
  • 5
  • 18