Search code examples
javascripthtmlmaterial-uicypressregression-testing

data-cy exists in DOM tree but not visible


I need some clarification on the usage of Cypress. I'm writing some e2e tests and one of them failed, because the element is not visible.

I found this answer helpful, it solved my problem. Clicking element which is reported to be not visible.

cy.get('[data-cy="dApp Info"]').click({force: true});

But now I'm wondering about Cypress best practice.

For example, let's say I have a component, which I want to click. It's a link a inside a div, inside a div, inside a nav. (I gave the link the data-cy property.) Even though as a user, the component is visible and clickable (see 1st image), the component is reported not to be visible (see 2nd image).

Is it best practice to add a data-cy property to any element I want to click and just use .click({force: true}) or should I add a data-cy property to one of the divs which wrap my actual link and click those (is that even possible?)?

enter image description here

not visible

Edit

DOM Structure

<nav data-cy="sidebar-nav-studio">
 <div>
  <div>
   <div>
    <div>
     <ul data-cy="dApp-sub-section-sidebar-nav-studio">
      <span>
       <a data-cy="Add Templates">
        <div> </div>
        <div>
         <p>
         Add Templates
         </p>
        </div>
      </a>
      <a data-cy="Look & Feel">
       <div> </div>
       <div>
        <p>
         Look & Feel
        </p>
      </div>
     </a>
     <a data-cy="dApp Info">
      <div> </div>
      <div>
       <p>
       dApp Info
       </p>
      </div>
    </a>
    </div>
  </div>
 </div>
</div>

Solution

  • I think adding the data-cy attribute to the a tag would be a good option, so that you get the element as visible and click it. What I understood from the cypress best practices page, the data-cy or data-test or data-testid should be added to the target element, which in your case is the a tag.

    I would suggest you to not use click({force: true}) until absolutely required because it forces the action and disables waiting for actionability.

    By actionability, cypress means commands that simulate a user interacting with your application. Under the hood, Cypress fires the events a browser would fire thus causing your application's event bindings to fire.

    So in case, a real user is not able to see or interact with a button for some reason, then the test should fail, but with force:true, the test will pass because it bypasses the actionability checks and forcefully clicks the button. You can read more about Actionability and Forcing from the docs.

    Or in case you don't want to use any tags, one good way would be to use the combination of a selector and inner text value to find the element and click it, something like:

    cy.get('[data-cy="sidebar-nav-studio"]').click() //opens the nav
    cy.contains('a', 'dApp Info').click()