'How to check for an element that may not exist using Cypress
I am writing a Cypress test to log in to a website. There are username and password fields and a Submit button. Mostly logins are straightforward, but sometimes a warning dialog appears first that has to be dismissed.
I tried this:
cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);
// Check for a possible warning dialog and dismiss it
if (cy.get('.warning')) {
cy.get('#warn-dialog-submit').click();
}
Which works fine, except that the test fails if the warning doesn't appear:
CypressError: Timed out retrying: Expected to find element: '.warning', but never found it.
Then I tried this, which fails because the warning doesn't appear fast enough, so Cypress.$ doesn't find anything:
cy.get('#login-username').type('username');
cy.get('#login-password').type(`password{enter}`);
// Check for a possible warning dialog and dismiss it
if (Cypress.$('.warning').length > 0) {
cy.get('#warn-dialog-submit').click();
}
What is the correct way to check for the existence of an element? I need something like cy.get() that doesn't complain if the element can't be found.
Solution 1:[1]
export function clickIfExist(element) {
cy.get('body').then((body) => {
if (body.find(element).length > 0) {
cy.get(element).click();
}
});
}
Solution 2:[2]
export const getEl = name => cy.get(`[data-cy="${name}"]`)
export const checkIfElementPresent = (visibleEl, text) => {
cy.document().then((doc) => {
if(doc.querySelectorAll(`[data-cy=${visibleEl}]`).length){
getEl(visibleEl).should('have.text', text)
return ;
}
getEl(visibleEl).should('not.exist')})}
Solution 3:[3]
The hasClass() or for CSS selector has() is an inbuilt method in jQuery which checks whether the elements with the specified class name exists or not. You can then return a boolean to perform assertion control.
Cypress.Commands.add('isExistElement', selector => {
cy.get('body').then(($el) => {
if ($el.has(selector)) {
return true
} else {
return false
}
})
});
Then, it can be made into a special cypress method with TypeScript file (index.d.ts) file and can be in the form of a chainable.
declare namespace Cypress {
interface Chainable {
isExistElement(cssSelector: string): Cypress.Chainable<boolean>
}
}
As in the example below:
shouldSeeCreateTicketTab() {
cy.isExistElement(homePageSelector.createTicketTab).should("be.true");
}
Solution 4:[4]
I have done it with pure js.
cy.get('body').then((jqBodyWrapper) => {
if (jqBodyWrapper[0].querySelector('.pager-last a')) {
cy.get('.pager-last a').then(jqWrapper => {
// hardcoded due to similarities found on page
const splitLink = jqWrapper[0].href.split("2C");
AMOUNT_OF_PAGES_TO_BE_RETRIEVED = Number(splitLink[splitLink.length - 1]) + 1;
})
} else {
AMOUNT_OF_PAGES_TO_BE_RETRIEVED = 1;
}
});
I'm trying to check if element exists on body
cy.get('body').then((jqBodyWrapper) => {
With a pure js querySelector
if (jqBodyWrapper[0].querySelector('.pager-last a')) {
Then I fire my cy.get
cy.get('.pager-last a').then(jqWrapper => {
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ran Adler |
| Solution 2 | M. Justin |
| Solution 3 | double-beep |
| Solution 4 | M. Justin |
