3

So I am trying to migrate our existing protractor test suite to cypress. For one of the tests, we have scenario where we can have two expected conditions which easier to handle in protractor. But I was wondering if there is any similar cypress command function to achieve that?? sharing the code snippet

confirmation.getConfirmButton().click().then(() => {

            // We will either get a successful cancellation OR an alert modal with an OK
            // button saying that the contract cannot be cancelled yet

            browser.wait(ExpectedConditions.or(
                ExpectedConditions.textToBePresentInElement(this.getViewAllFirstStatus(), "Cancelled"),
                ExpectedConditions.elementToBeClickable(this.getModalOkButton())
            ), 5000);

            this.getModalOkButton().isPresent().then((present) => {
                if (present) {
                    this.getModalOkButton().click().then(() => {
                        browser.sleep(8000).then(() => {
                            this.cancelFirstContract();
                        });
                    });
                }
            });
        });
Fody
  • 23,754
  • 3
  • 20
  • 37
  • 1
    I think the usual way would be to setup the test, such that you know which of these two will happen. Is this possible in your case, e.g. by intercepting a http request? – A_A Aug 25 '22 at 15:44
  • It takes a while to process the request, that's why we use the loop to try until it succeeds. So no easy way to judge it – Aspiring Coder Aug 25 '22 at 15:50
  • If you can detect via the UI if the action finished, maybe you could increase the timeout and wait for it (`cy.contains("this text shows up when finished", { timeout: 150000 })`)? – A_A Aug 25 '22 at 15:55
  • Is there a network request that you're waiting on to complete? – agoff Aug 25 '22 at 15:58
  • So basically this test is check if a 'contract' can be 'cancelled'. But the 'contract' after 'submission' takes a while to be in a state where it can be 'cancelled'. So no network request that we can wait to be completed. UI can either have alert modal to say it can't be cancelled or the contract will be successfully cancelled. I have to retry until it can be successfully cancelled. Hope I am making sense and its clear to you guys – Aspiring Coder Aug 25 '22 at 16:06

2 Answers2

1

I think what you want to do in Cypress is use the jQuery multiple selector.

This will essentially wait for one selector or the other, equivalent to the Protractor expression ExpectedConditions.or(...).

Whichever selector appears first will pass on as "subject" on the command chain.

If neither element turns up within 10 seconds, the test fails.

const cancelledStatus = 'span:contains("Cancelled")';  // adjust as appropriate
const modalOkButton = 'button:contains("Ok")';         // adjust as appropriate 

const multipleSelector = `${cancelledStatus}, ${modalOkButton}`

cy.get(multipleSelector, {timeout:10000})
  .then($subject => {
    if ($subject.text() === "Ok") {  // equiv to "getModalOkButton().isPresent()"
      cy.wrap($subject).click()
    }
  })
Fody
  • 23,754
  • 3
  • 20
  • 37
0

I think the most appropriate way to handle this would be to wait on the first condition to be true, and then continue to check for the second one. As suggested, we can increase the timeout for each condition.

cy.get('foo', { timeout: 15000 })
  .should('have.text', 'Cancelled')
  .get('bar', { timeout: 15000 })
  .should('have.attr', 'enabled') // or whatever property is used to determine clickability
// continue with other actions
agoff
  • 5,818
  • 1
  • 7
  • 20