Do stuff according to whether an element exists or not

115 Views Asked by At

I want to know whether an element exists or not and do stuff according to that. I tried many options but failed. For example:

cy.get(deleteCellButtonLocator).then(($el) => {
    if ($el.length > 0) { //found
        cy.log(cellName + ' exists. Deleting...');
    } else { //not found
        console.error('Element not found');
    }
});

This one enter only the found block, but not the 'not found' block. It simply fails on AssertionFailure and stops execution. Why?

2

There are 2 best solutions below

0
On BEST ANSWER

Setting timeout to 0 just makes it fail quicker.

One way to do it is to add an assertion that modifies the fail behavior. Cypress runs the whole queue as single command.

It does look-ahead checks to see if the get() should be negated. It happens that returning undefined in an assertion also changes the get() query to stop it from failing.

The subject is passed on the the next command in the queue where you can perform the existence check.

cy.get(deleteCellButtonLocator)
  .should(() => undefined) //           <-- stops get() from failing
  .then(($el) => {
    if ($el.length > 0) { //found
        cy.log(cellName + ' exists. Deleting...');
    } else { //not found
        console.error('Element not found');
    }
})
0
On

If the element is not found, it will wait for the default timeout (usually 4 seconds) and then throw an AssertionError, causing the test to fail. This is why your 'not found' block is not being executed.

The fix for this is to simply use the { timeout: 0 } option with cy.get() function to disable the waiting time and then use the .then() function with a .catch() block to handle the cases when the element is not found. Something like:

cy.get(deleteCellButtonLocator, { timeout: 0 }).then(($el) => {
    // Found block
    cy.log(cellName + ' exists. Deleting...');
}).catch((err) => {
    // Not found block
    console.error('Element not found');
});