Transcripted Summary

Let's now take a look at some assertions.

In my test, I want to add another card, so I'll add some bread to my "groceries" list, and after, I confirm that I want to make sure that this card is actually visible.

I'm going to delete the card and start writing my test.

The first thing I want to do is to get my element, so that will be data-cy=new-card, which represents this button, which I want to click on, so I'll use the click command.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy=new-card]')
    .click()
});

Save my test to check if everything is correct - it seems so.

Let's now take that input and type in some text.

I'm going to use the selector playground, copy my selector, paste it into my test, and now use the type command to type and just add 'bread' and confirm that with an "Enter" key.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy=new-card]')
    .click()

  cy.get('[data-cy="new-card-input"]')
    .type('bread{enter}')
});

As soon as I do that, I will have my card complete, which is great, but now I want to make sure that this card is actually visible and my application is working correctly.

The way I'm going to do that is I'm going to target this card, use the selector, and now I'm going to write an assertion.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy=new-card]')
    .click()

  cy.get('[data-cy="new-card-input"]')
    .type('bread{enter}')

  cy.get('[data-cy="card"]')
    .should('be.visible')
});

In Cypress, whenever you want to use an assertion, you can use the should command.

Now since we have the autocomplete set up with this reference types="cypress", we can just start typing and we will get this nice overview of different assertions that we can do.



Right now, we want to make sure that our card is visible, so we'll use the assertion should('be.visible').

So, I'll delete my card and run my test and now I can see that after I have created my card, it has become visible which is great.

So what if I were to create two cards?

I'm just going to copy and paste this card so we actually create two cards - one for bread and the other for milk.

Then, instead of checking visibility we want to make sure that after these two actions, we'll actually have two cards.

The way I'm going to do that is I'm going to use the assertion have.length and I'll add a second parameter which will be the number 2.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy=new-card]')
    .click()

  cy.get('[data-cy="new-card-input"]')
    .type('bread{enter}')

  cy.get('[data-cy="new-card-input"]')
    .type('milk{enter}')

  cy.get('[data-cy="card"]')
    .should('have.length', 2)
});

I'll delete the card that I have already in my app, I'll save my test, and now we can see that after creating two cards, the length of cards is two.

Now you might be asking why we use length and not, for example, count or some other assertion.

This is because whenever we use the get command to find our elements on a page, what Cypress is going to do is that it is going to create an array of elements.

When I click on my get command and take a look into the Console, I can see the details of this command.

So, I'll see that we have used the get command, we have used the [data-cy="card"] selector and we have yielded or passed on two elements, which are in an array.



Cypress uses this chaining syntax where one command passes information into the other.

What this means is that when we are using the should command, we're actually asserting the length of that array.

If we have found two elements with this selector, the array of elements will have a length of two.

Let's now try another test.

I'm going to delete these commands and I'm also going to delete one of these cards.

The next thing I want to test is this checkbox.

If I click on it, the background behind this element is going to get green.



If I uncheck it, then it goes back to transparent.

There are actually two changes happening.

One, the checkbox is getting ticked and the background is going to change, and we're going to write an assertion for both of them.

I'm going to find a selector for our checkbox, and then I'll use the click command to click on this element.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy=card-checkbox]')
    .click()

});

Notice what happens when I run my test.

So I run my test, and I can see the checkbox is ticked off.

When I rerun my test again, the checkbox is ticked off.

The checkbox is empty, and depending on how many times I run my test the state of that checkbox is going to change.

While this may be okay for most of the situations, if we want to keep our test steady, then we can use a check command instead of click.

This will make sure that no matter how many times we run the test, we're going to finish in the checked state.

And vice versa, if we use uncheck, then again no matter how many times we run our test, it's going to end up in an unchecked state.

Let's now finish our test.

I'm going to revert this back to check, and then select my checkbox element again and write an assertion.

We want to make sure that the checkbox is checked.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy="card-checkbox"]')
    .check()

  cy.get('[data-cy="card-checkbox"]')
    .should('be.checked')

});

Then finally, let's take a look at this date element.

I'm going to inspect that, put my Console at the bottom, and I'm just going to follow what's happening with this element when I interact with the checkbox.



You can see that we have some classes that dynamically change.

Most importantly, once the checkbox is checked, we will see this completed class.

If we check off the checkbox, that class is going to disappear.

This completed class is what gives our element the styling.

Now, of course, if you want to watch for visual changes using a tool like Applitools, that would definitely do an amazing job here.

With Cypress, we can just write a functional test to see that this class will actually appear on our element.

I'm going to select our due date element, paste it into my test, and then write an assertion.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy="card-checkbox"]')
    .check()

  cy.get('[data-cy="card-checkbox"]')
    .should('be.checked')

  cy.get('[data-cy="due-date"]')
    .should('have.class', 'completed')

});

We'll use should and have.class, and the name of the class which is completed.

Notice that we are typing only the name of the class, so it's not actually a selector and we're not going to type '.completed' as we would if we were to select this element using the get command, but just with the name completed.

Let's save our test to see if everything works and it seems so, so that's great.

Let's go for one final test.

In this final test, I want to look for this list name and I want to check the text that's inside.



I'll select the element, use the should command, and search for an assertion that might be good for this.

Let's check for have.text.

This element should have text 'groceries'.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy="list-name"]')
    .should('have.text', 'groceries')

});

Let's save the test now and as you can see my test has failed.



The error message tells us a little bit more about this failure.

You can see that we are asserting the text groceries, but the text is actually empty.

So what's happening? Because we can clearly see the text.

Well, if we take a closer look using our Inspect element, we'll notice that this element is actually an input.



You can see that we don't really see the text groceries in here.

In HTML5, input elements are for holding values.

If we examine this element using our dev tools, we can take a look at the properties of this element.



Here, we can see different attributes like data-cy, list of classes, etc.

If we scroll down, we can see that there is no innerText, which would be something that would be checked with the should('have.text') assertion.

Now if I scroll even lower, then under value, we can actually see the text "groceries".

What this essentially means is that we don't have the right assertion.

For input elements we're always checking for value.


/// <reference types="cypress" />

it('making assertions', () => {

  cy.visit('/board/1')

  cy.get('[data-cy="list-name"]')
    .should('have.value', 'groceries')

});

When I save my test, now it's working.

If, however, we have some other element like this card-text, the assertion would actually be have.text.

The reason for that is that if we take a look using the Elements panel, we can see that this is a div element.

It has an opening tag and a closing tag and text inside.

You can always refer to the Elements panel to check for things that Cypress is actually testing.

A good rule of thumb is that if you can see the text, it's a text, and if you don't, it's probably something else.



Resources



© 2024 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR