Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Hover over menu's using Cypress

I recently stumbled upon the e2e tool - Cypress.io. I'm currently doing a POC for the firm I work with for e2e testing of a react app. It has a hover over menu like most of the web apps have now.

An example :

URL : Fmovies

I was trying to click a menu item from this hover over but the test fails saying that the display is set to none.

In Selenium, we use the moveElement approach to go to this element, and then do whatever we need to do. However, I'm failing to do so using Cypress.

Considering the current menu, I wrote this

it('goes to specific element in Genre',()=>{
        cy.get('#menu').within(()=>{
            cy.get('ul').within(()=>{
                cy.contains('Family').click();
            });
        });
    }); 

Error : Error

like image 921
demouser123 Avatar asked Feb 18 '18 13:02

demouser123


People also ask

How do you handle mouseover in Cypress?

If the hover behavior depends on a JavaScript event like mouseover , you can trigger the event to achieve that behavior. Using . trigger() will only affect events in JavaScript and will not trigger any effects in CSS.

How do you get the mouse over the element in Cypress?

This is done by passing an option as an argument to the click() command in Cypress. click({ force: true }) − The click() command with the option force set to true [force:true ] modifies the default behavior of the hidden element and we can click on it.

How do you handle hidden elements in Cypress?

Cypress has another technique for handling hidden elements. For example, to click a hidden element we can use the Cypress command click and pass the option {force : true} as a parameter to it - click({ force: true }). This modifies the hidden characteristics of the hidden element and we can click it.

How do you wait for an element in Cypress?

Wait for API response Cypress works great with http requests. If you are waiting for some resources to be loaded in your app, you can intercept a request and then create an alias for it. That alias will then be used with . wait() command.


1 Answers

Cypress has a unique workflow that is based around baking in as many tests as possible into its default behavior. Before it simulates the click on the element containing "Family", it checks for actionability. This is a built in test that will fail if the element is hidden, display:none(that's the case here), size 0,0, etc. Only after it passes that test will it simulate the action on the element containing 'Family'.

You can override the actionability check by using .click({force:true}), but then you lose the guarantee that the user would actually be able to find and click on the element.

The proper way to do this test is to trigger the dropdown menu so that the element becomes visible, and then do the click. Here's what you would do if you wanted to find the "Genre" menu item, reveal the dropdown menu, and click the "Family" item:

describe('Hover Menu',()=>{
    it('can click on a genre sub-menu item',()=>{
        cy.get('#menu').contains('Genre').next('.sub-menu').then($el=>{
            cy.wrap($el).invoke('show')
            cy.wrap($el).contains('Family').click()
        })
    })
})

Here, show is a jQuery method that modifies CSS properties to make the element visible.

cy.wrap($el) turns a jQuery element into a Cypress Chainer, which you can then call Cypress commands on.

like image 139
bkucera Avatar answered Sep 19 '22 06:09

bkucera