Transcripted Summary

In this test, we would like to click this star icon.



This will add our groceries board to a “Starred” category.

So, let's go ahead and write a click command.

When I saved my test, you can see that my test is failing. The reason for that is described into error message.



Our star element is not visible because it has a CSS property of “display: none”.

Before we make a click in our test, Cypress will actually check whether that element that we want to click on is actionable. That means it must be visible, it cannot be disabled, and it cannot be covered by any other element.

In our application, the star icon is actually visible only when we hover over our board.


Hovering with Cypress

Since Cypress is all JavaScript, we are not able to do a hover, at least not with commands that Cypress provides out of the box. We will later look at a plugin that actually adds hover capabilities using the Chrome dev tools protocol. But for now, let's look at a couple of workarounds, which may be a good enough solution.


The first workaround we have at our disposal is basically forcing the click.

This way, we will skip all of those checks that I mentioned and basically click on the element, whether it is actionable or not.

To do that, I'm going to type force with the value of “true”.



When I save my test, you can see that I have clicked on my star.

Although this is not the best solution, sometimes it’s nice to know that it’s there.

A real user would of course not click on an invisible element. So, lets, instead of forcing our click, make that star element visible.

To do that, we are going to use the invoke function.

With this command, we can invoke any function we want on our element. And since we have whole jQuery at our disposal, we can use a function that is called "show".

I'll delete this click for now and make sure that we only have one star in our board list. Now when I saved my test, you can see that my star has appeared.


  cy
    .get('[data-cy=star]')
    .invoke('show')
    .click()

I can now click on it using regular click command.



So, what we did here is that we changed the visibility of our DOM element since Cypress executes its test inside the browser right next to our application. We get full access to our application and to the whole DOM structure.

There's also another thing we can do with the invoke command.

Inside our board, we have a couple of tasks. When we look into the detail of each task, there's an attribute called "Due date".



If the due date is today or before today, our task will become red.

When we look into the detail of our task, we can see that this overdue task has a class called “overDue”.



Using our invoke command, we can add this class to another task without changing the date.

Let's go ahead and do that.

I'm first going to change my visit command so that we open our board and then I will select my task: .get('[data-cy="task"]')

Instead of the “show” function, I'm going to invoke('addClass').

As a second argument, I will use the name of the class we want to add. So that will be “overDue”: invoke('addClass', 'overDue')

We're not going to click anything, but since our get command is going to return 3 elements, I'm just going to select the first one: eq(0)

When I now save my test, you can see that the invoke command has added the “overDue” class, even though when I click on the detail, the date has not changed.



Let's back up a little and go back to our board list.

I'm going to remove the star and look more into the detail of how our board item actually displays the star.

When I look into the elements panel and unwrap it, I can see that my star element has a style of “display: none”. When I hover over the board item, this style will disappear. You can see it changing as I move my mouse.

Now this tells us that the visibility of our star element is actually handled by JavaScript.

And we can see a proof of this when we look into the Event Listeners panel, you can see that there are 3 Event Listeners bounds to our board item — click, mouseout, and mouseover.



Click will of course, redirect us to our board, and "mouseout" and "mouseover" are actually the events that changed the visibility of our star.

In Cypress, we can actually call this event to trigger the behavior — to do that, we are going to use command called trigger.

So let me go back to my test, change this URL back to our homepage, and I'm going to select my "board-item" and use trigger command. And the event I want to trigger is “mouseover”.


  cy
    .get('[data-cy="board-item"]')
    .trigger('mouseover')

When I now save my test, you can see that the star has appeared.

So, I'm basically firing the same events that our user would if they would interact with our application.

To make sure that the behavior works as intended, we can add a couple of assertions.

The first one would be that our star element is visible.


  cy
    .get('[data-cy=star]')
    .should('be.visible')

And when I save my test, I can actually see the assertion passing and the second one would be the exact opposite.

So, “I will trigger the event “mouseout” and make sure that after that event, our star element is not visible.


beforeEach(() => {

  cy
    .visit('/');

});

it('Changing the DOM', () => {

  cy
    .get('[data-cy="board-item"]')
    .trigger('mouseover')

  cy
    .get('[data-cy=star]')
    .should('be.visible')

  cy
    .get('[data-cy="board-item"]')
    .trigger('mouseout')

  cy
    .get('[data-cy=star]')
    .should('not.be.visible')

})

And now my test is complete.



So, let's recap.

When we want to interact with our application, Cypress, we'll actually check whether the element we want to interact with is actually actionable.

If we want to bypass these checks, we can, we just need to add an option to force the action.

The second thing we learned here is that we can change our DOM elements by using invoke function. We can reveal hidden elements or change different attributes, such as classes.

And finally, we can trigger different types of events that are bound to the elements in our DOM.



Resources



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