2
votes

I have a situation where I want to open the sub-submenu of the main menu which has layout build using nested "ul-li ".

sub-menu gets open when mouse is hover to the li which has Children (ul-li) as below

<ul class="dropdown"> 
  <li>/<li>
  <li>/<li>
  <li class="dropdown-menu">
      <a> Target Menu </a>
      <ul class="dropdown"> 
        <li class="dropdown-sub-menu"><a> Sub Menu 1</a></li>
        <li class="dropdown-sub-menu"><a> Sub Menu 2</a></li>
       <li class="dropdown-sub-menu"> <a> Sub Menu 3</a></li>
     </ul>
  </<li>
</ul>

Here, My requirement is to mouse over to "Target Menu" which will open its sub-menu and then want to trigger the click the event of "Sub Menu 1/2/3" respectively.

I have gone through the documents of cypress for handling this feature. As .hover() feature is not available with cypress.

https://docs.cypress.io/api/commands/hover.html# https://docs.cypress.io/api/commands/trigger.html#Syntax https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Actionability

I have also tried the below commands but it fails too. Nothing hover or mouseover effect occurs and due to which automation breaks when it tries to click the "hidden Li (sub Menu 1/2/3)".

cy.get("target the li/a").trigger("mouseover")

One of the blogs while searching I found that to Interact with hidden elements which gets visible on mouse hovering effect on some button or link, you have to use the cy.invoke as below which will execute the jquery "show" event and makes the hidden element visible and then you can click on the hidden elements. Unfortunately, that method too is not working as in Typescript when I write the below command it doesn't allow me to compile as "show" is not the valid function name.

cy.get("li.dropdown-menu ul.dropdown").invoke("show")

Please guide for the possible solution related to this. Executing click command with { force: true } of the hidden element is the work around for this but is not a valid one though.

3
If you don't like using force: true, another potential workaround could be to queue a native or jquery-based hover trigger using .then().Joshua Wade
Sorry if I am missing something, but cy.get("target the li/a") does not look correct. I would use cy.get('a').content(' Target Menu ').trigger('mouseover').user8745435
@eric99 I believe they are saying that "target the li/a" would be replaced with a selector that actually targets the element.Joshua Wade
Ah yes, well that is a bit daft - the problem may be in the selector. Sailing close to getting a minimal, complete and verifiable example ticket.user8745435
Is the logic for showing and hiding your menu options in javascript or CSS? Could you post the code that actually handles mouse events on the menu? I just implemented a test for my project that used .trigger('mouseover'), but if your app code for handling those events is different then the same thing might not work.Joshua Wade

3 Answers

2
votes

Friends

Firstly, Thanks for all your time & suggestions.

I have found the work around to trigger the mouseover event and show the bootstrap submenu. without using the { force: true }.

Solution that I implemented. Appreciated if anyone finds different and better solution. Please do share.

Cypress.$($elem[0]).siblings("ul").show();

Using this I have manually makes the ul to show first and then execute the click event of the submenu. For this I have tried

Cypress.$($elem[0]).hover(false, false);
Cypress.$($elem[0]).mouseover();
Cypress.$($elem[0]).trigger("hover");
Cypress.$($elem[0]).trigger("mouseover");

but above commands didn't work. So I move to manually trigger the hide/show event of jquery.

1
votes

Based on the comments, your issue seems to be with how menus are handled in Bootstrap.

Bootstrap menus can be triggered with a special .dropdown() function added to jQuery. Since Cypress gives you native access to the DOM, you can just call that function from within your test. Here's how this would look in Cypress:

cy.get('li.dropdown-menu a').then((elem) => {
    $(elem).dropdown('toggle');
});
0
votes

hidden elements are not shown through invoke('show') because, you are using the locator of the grand parent of the hidden elements. Try using the immediate parent of the Hidden elements. Then invoke('show') will do the mouse hover function.