Reputation: 888
Let's consider the case where I need to assert if an element exists. There are 2 possible ways of doing this in cypress:
1) cy.get('button').contains('Save')
2) cy.get('button').contains('Save').should('exist')
In both cases the test will fail if the 'Save' button not exist.
What are the reasons apart from maybe better code readability/maintainability that I should add the .should('exist') to my cypress tests?
Upvotes: 36
Views: 34559
Reputation: 49
From my test,
cy.get('button').contains('Save').should('exist')
is not redundant.
It's true that, if it contains Save
, your test is successful. If it doesn't, your test fails with the desired reason description. In that aspect, should('exist')
is redundant.
However, if you do cy.get('button').contains('Save')
, and the button exists, you only get a grey step which means the step is executed without error. But it does not show a green assert
badge, because you don't have an assertion there.
So I could suggest removing line 1) and keep line 2).
Then if it passes, you get a green assert
badge. If it fails, it actually fails at contains('Save')
part rather than should
part. But anyway, you get red error with meaningful error messages.
Although, I do agree with @Durkomatko that 'be.visible' is better if you do want it to show on the page.
Upvotes: 0
Reputation: 7284
Actually, until v4.0 is released (and this PR is merged), you need to chain should('exist')
assertion if you chain any negative assertions yourself. This is because the default should('exist')
assertion is skipped when you chain your own assertions.
Not necessary for positive assertions because they won't pass on non-existent elements.
Also see Implicit should 'exist' assertion is not being applied on cy.get() when other assertion.
Below, the element .first-item
does not exist but the assertion passes:
describe('test', () => {
it('test', () => {
cy.get('.first-item').should('not.have.class', 'is-selected');
});
});
Upvotes: 1
Reputation: 5844
For your usecase of asserting whether an element exists, they are indeed redundant.
.contains()
yields a DOM element and according to documentation, .should
yields the same element it was given as an input. There are some exceptions when .should yields different element (as you can see in the documentation) but in case of using should('exist')
, they are really redundant
As you mentioned, I personally also prefer adding should
for better readability. Actually I prefer .should('be.visible')
because of following scenario - when an element is hidden or is pushed out of the screen because of some CSS issues, it doesn't exist from user perspective. But..
cy.get('button').contains('Save')
- passes test
cy.get('button').contains('Save').should('exist')
- passes test
cy.get('button').contains('Save').should('be.visible')
- fails test
Upvotes: 35