DEV Community

Cover image for Three optional styles for UI assertions in Cypress
Sam E. Lawrence
Sam E. Lawrence

Posted on

Three optional styles for UI assertions in Cypress

.contains()

Often, I just want to scan over a UI in Cypress and make sure that a set of text labels are present. It's typically been my habit to style these sorts of tests like this:

cy.contains('element.class', 'Element text')
  .should('be.visible');    
Enter fullscreen mode Exit fullscreen mode

I love the simplicity of cy.contains(), and the log output of this command will show what text was queried for, but not in the clearest, most visible way.

Cypress log output using cy.contains()

.should()

After a recent code review, I noticed a team-mate styling a similar query like this:

cy.get('element.class')
  .should('be.visible')
  .should('contain.text', 'Element text');
Enter fullscreen mode Exit fullscreen mode

After a bit of thought, I realized that this would make for much better output in the Cypress runner log. Here's a screenshot where you can see that the expected text is now highlighted and easier to read. This makes debugging a much simpler process when we get feedback about what text the query was looking for.

Cypress log output showing an assertion with .should()

expect()

However, we can go even further and have the Cypress runner log tell us both which string was expected and what was actually found.

cy.get('element.class')
  .should('be.visible')
  .invoke('text')
  .then((text) => {
    expect(text).eq('Element text');
  });
Enter fullscreen mode Exit fullscreen mode

As you can see, this provides the richest output to the log, showing both what was expected and what was found.

Cypress log output showing an assertion with expect()

This style is certainly more verbose, but the additional clarity in log output may make it worth your time. Having consistent style in a codebase can be valuable, but I think it's ok to mix all these various approaches together as long as your focus is on test effectiveness. Hopefully this article gets you thinking about how you might want clearer logging in certain situations, and how to change up your code style based on your situational needs.

addendum

Gleb Bahmutov talks about this in his video "Use Stronger Assertions":

You can see that he opts for the second style, using a .should() assertion to highlight just the expected text in the log. I think this is actually the best style for most use cases, but it can be helpful to lean on richer logging at times, especially when debugging a test as it's being written or modified.

Top comments (3)

Collapse
 
jmosley profile image
Judy Mosley

What a great post! Really appreciate the reminder that I can string together .should(). Sometimes my brain thinks I can only make an assertion using .should() once.

Collapse
 
hammzj profile image
Zachary Hamm

One thing to note with the approach of using expect in a then chain is that it performs the assertion immediately instead of retrying until a timeout, like with should. We would need to ensure that the text was loaded and would not change within the element by the time the assertion is performed — there are certain stateful elements which might use something like a “Loading…” message until the content is loaded, so logging may show a difference in the text contents unless we wait for those changes to process first.

Collapse
 
samelawrence profile image
Sam E. Lawrence

That's a great point! Thanks for reminding me of that nuance!