Maccurt
Maccurt

Reputation: 13817

Using Cypress, how to test if element does not exist?

I want to be able to click on a check box and test that an element is no longer in the DOM in Cypress. Can someone suggest how you do it?

// This is the Test when the checkbox is clicked and the element is there

cy.get('[type="checkbox"]').click();
cy.get('.check-box-sub-text').contains('Some text in this div.')

I want to do the opposite of the test above.

So when I click it again the div with the class check-box-sub-text should not be in the DOM.

Upvotes: 413

Views: 381272

Answers (16)

madhuri varada
madhuri varada

Reputation: 101

You can use the cypress if-else condition

cy.get('body').then(()=> {
cy.get('[type="checkbox"]').if('visible').check().else().log('there is no check box')
})

The above code is use for the if check box is visible it will click

cy.get('body').then(()=> {
cy.get('[type="checkbox"]').if('check').log('it is already checked').else().check()
})

This code is useful for the if the check box is already checked

Upvotes: 0

Darveena A
Darveena A

Reputation: 19

If there is no element, you can use

cy.get('[type="checkbox"]').should('not.exist')

Upvotes: 0

Marek Skokánek
Marek Skokánek

Reputation: 61

For me this solution worked:

cy.get('body').then($body => {
  if ($body.find("mat-option[aria-selected='true']").length) {
    // Do something if exist
  } else {
    // Do if not exist
  }
})

Upvotes: 2

McLayn
McLayn

Reputation: 462

Apart from

cy.get('.check-box-sub-text').should('not.exist');

another option is

cy.get('.check-box-sub-text').should(checkBoxSubText => {
  expect(checkBoxSubText).to.not.exist;
});

It doesn't add much in this case, but it could be more readable in more complex situations as it splits selecting the object from asserting.

Upvotes: 0

Alan
Alan

Reputation: 10183

You can also search for a text which is not supposed to exist:

cy.contains('[email protected]').should('not.exist')

Here you have the result in Cypress: 0 matched elements

enter image description here

Reference: Docs - Assertions, Existence

Upvotes: 117

Dominik Ehrenberg
Dominik Ehrenberg

Reputation: 1754

In case anyone comes across this, I was having the issue that neither .should('not.exist') nor .should('have.length', 0) worked - even worse: If the element I was querying was actually there right from the get-go, both asserts still returned true.

In my case this lead to the very strange situation that these three assertions, executed right after each other, were true, even though asserts 1+2 and 3 contradict each other:

cy.get('[data-cy="foobar"]').should('not.exist')
cy.get('[data-cy="foobar"]').should('have.length', 0)
cy.get('[data-cy="foobar"]').should('have.text', 'Foobar')

After extensive testing, I found out that this was simply a race condition problem. I was waiting on a backend call to finish before running the above 3 lines. Like so:

cy.wait('@someBackendCall')
cy.get('[data-cy="foobar"]').should('not.exist')

However once the backend called finished Cypress immediately ran the first two assertions and both were still true, because the DOM hadn't yet caught up rerendering based on the backend-data.

I added an explicit wait on an element that I knew was gonna be there in any case, so my code now looks something like this:

cy.wait('@someBackendCall')
cy.get('[data-cy="some-element"]').should('contain', 'I am always here after loading')
cy.get('[data-cy="foobar"]').should('not.exist')

Upvotes: 0

Mihail Şalari
Mihail Şalari

Reputation: 69

You can also query for the matched elements inside the body or inside the element's parent container, and then do some assertions on its length:

cy.get("body").find(".check-box-sub-text").should("have.length", 0);

Upvotes: 0

t_dom93
t_dom93

Reputation: 11496

Use .should('not.exist') to assert that an element does not exist in the DOM.


Do not use not.visible assertion. It would falsely pass in < 6.0, but properly fail now:

// for element that was removed from the DOM
// assertions below pass in < 6.0, but properly fail in 6.0+
.should('not.be.visible')
.should('not.contain', 'Text')

Migration Docs here: Migrating-to-Cypress-6-0

Upvotes: 81

Urasquirrel
Urasquirrel

Reputation: 1585

Cypress 6.x+ Migration

According to cypress docs on Existence

The very popular attempt which is a bit naive will work until it doesn't and then you'll have to rewrite it again... and again...

// retry until loading spinner no longer exists
cy.get('#loading').should('not.exist')

This doesn't really work for the title problem which is what most people will be looking for.

This works for the case that it is being removed. but in the case that you want it to never exist... It will retry until it goes away.

However, if you want to test that the element never exists in our case.

Yes lol. This is what you really want unless you want to just have your headache again another day.

// Goes through all the like elements, and says this object doesn't exist ever
cy.get(`img[src]`)
  .then(($imageSection) => {
    $imageSection.map((x, i) => { expect($imageSection[x].getAttribute('src')).to.not.equal(`${Cypress.config().baseUrl}/assets/images/imageName.jpg`) });
})

Upvotes: 38

Jayanth Bala
Jayanth Bala

Reputation: 838

No try-catch flow in cypress

In java-selenium, we usually add the NoSuchElementException and do our cases. if UI is not displaying element for some Role based access cases.

Upvotes: 0

sakibdroho
sakibdroho

Reputation: 9

I closed an element and checked should('not.exist') but the assertion failed as it existed in the DOM. It just that it is not visible anymore.

In such cases, should('not.visible') worked for me. I have just started using cypress. A lot to learn.

Upvotes: 0

user11898240
user11898240

Reputation:

You can use get and contains together to differentiate HTML elements as well.

<button type='button'>Text 1</button>
<button type='button'>Text 2</button>

Let's say you have 2 buttons with different texts and you want to check if the first button doesn't exist then you can use;

cy.get('button').contains('Text 1').should('not.exist')

Upvotes: 5

MrSmiley
MrSmiley

Reputation: 357

cy.get('[data-e2e="create-entity-field-relation-contact-name"]').should('not.exist');

might lead to some false results, as some error messages get hidden. It might be better to use

.should('not.visible');

in that case.

Upvotes: 24

Rajan Domala
Rajan Domala

Reputation: 143

You can also use below code

expect(opportunitynametext.include("Addon")).to.be.false

or

should('be.not.be.visible')

or

should('have.attr','minlength','2')

Upvotes: 0

Mikhail Vasin
Mikhail Vasin

Reputation: 2580

Here's what worked for me:

cy.get('[data-cy=parent]').should('not.have.descendants', 'img')

I check that some <div data-cy="parent"> has no images inside. Regarding original question, you can set data-cy="something, i.e. child" attribute on inner nodes and use this assertion:

cy.get('[data-cy=parent]').should('not.have.descendants', '[data-cy=child]')

Upvotes: 7

Maccurt
Maccurt

Reputation: 13817

Well this seems to work, so it tells me I have some more to learn about .should()

cy.get('.check-box-sub-text').should('not.exist');

Upvotes: 550

Related Questions