Search code examples
testingcypress

Cypress Error: cy.click() can only be called on a single element for Single Element


I'm using Cypress to test the logout functionality of my UI. However, I'm encountering an error that doesn't seem accurate to me because I only have one element with the specified attribute. Here's the code I'm using:

Cypress.Commands.add('logOut', () => {
    cy.get('button[data-cy="account-menu-button"]').click();
    cy.get('button[data-cy="account-menu-logout-button"]').click();
});

When I run my tests, I receive the following error:

cy.click() can only be called on a single element. Your subject contained 2 elements. Pass { multiple: true } if you want to serially click each element.

I tried modifying the code to ensure only one element is selected:

Cypress.Commands.add('logOut', () => {
    cy.get('button[data-cy="account-menu-button"]').eq(0).click();
    cy.get('button[data-cy="account-menu-logout-button"]').click();
});

Timed out retrying after 4050ms: cy.click() failed because this element is not visible:

<button class="flex h-7 w-7 items-center justify-center rounded-full bg-flow-turquoise text-sm font-medium text-flow-purple md:bg-flow-purple md:bg-opacity-20" data-cy="account-menu-button" type="button">AU</button>

This element button.flex.h-7.w-7.items-center.justify-center.rounded-full.bg-flow-turquoise.text-sm.font-medium.text-flow-purple.md:bg-flow-purple.md:bg-opacity-20 is not visible because its parent div.flex.items-center.gap-x-4.md:hidden has CSS property: display: none Fix this problem, or use {force: true} to disable error checking.

It seems like the element is not visible because its parent has display: none. Here are the relevant parts of my HTML:

<div class="flex items-center gap-x-4 md:hidden">
    <button class="flex h-7 w-7 items-center justify-center rounded-full bg-flow-turquoise text-sm font-medium text-flow-purple md:bg-flow-purple md:bg-opacity-20" data-cy="account-menu-button" type="button">AU</button>
</div>

Solution

  • If you have two elements with the same button[data-cy="account-menu-button"] it could be that there are two version on the page for two different page layouts, but only one is visible at any time.

    This is confirmed by the message

    failed because this element is not visible

    so just picking the first one isn't the best option.

    Instead, use :visible in the selector.

    cy.get('button[data-cy="account-menu-button"]:visible')
      .click();
    

    Don't use {force:true} as suggested, the visibility check is a better way.

    Generally, forcing the click gives you a bad test that can can pass when it should be failing.

    For instance, if the CSS is altered and creates a bug that stops either button from being visible, your test will not pick it up. The test will still pass even though an actual user cannot see either button.