Skip to content

Cypress - Hidden Elements

Cypress - Interacting with Hidden Elements

Section titled “Cypress - Interacting with Hidden Elements”

Modern web applications often feature elements that are not immediately visible, such as submenus appearing on hover, or content loaded dynamically. These elements might be hidden using CSS properties like display: none; or visibility: hidden;. Cypress provides robust mechanisms to interact with such hidden elements.

One common scenario is a submenu that appears only when you hover over a main menu item. Let’s explore two primary ways Cypress handles these.

Cypress can leverage jQuery methods to manipulate DOM elements. The invoke('show') command calls the jQuery show() method on the selected element. This method typically changes the element’s CSS (e.g., from display: none to display: block), making it visible and thus interactable.

This approach is useful when you need to programmatically ensure an element is visible before interacting with it, effectively bypassing the user interaction (like hover) that would normally reveal it.

Consider a hypothetical scenario on an e-commerce site where a ‘Sign In’ link is inside a flyout menu that’s initially hidden:

describe('Hidden Elements Test - invoke(show)', () => {
it('Should interact with a hidden element after making it visible', () => {
// Example: Visit a page with a hidden flyout menu
cy.visit("https://www.example.com"); // Replace with your test page
// Assume '#accountMenuFlyout' is the hidden container
// and it becomes visible on hover of '#accountMenuTrigger'
// We directly make the flyout visible
cy.get('#accountMenuFlyout').invoke('show');
// Now that it's shown, we can click the 'Sign In' link within it
// Using a more specific selector for 'Sign In' is recommended
cy.get('#accountMenuFlyout').contains('Sign In').click();
// Add assertions for the expected outcome, e.g., navigation to sign-in page
cy.url().should('include', '/signin');
});
});

In the Cypress command log, you would see the invoke command followed by the click command. The element, though initially hidden, is made visible by invoke('show') and then successfully clicked.

Cypress has a powerful feature to force actions on elements, bypassing its default actionability checks. For clicking hidden elements, you can use cy.click({ force: true }).

This option tells Cypress to click the element even if it’s hidden, covered, or otherwise not considered ‘clickable’ under normal circumstances. While convenient, it should be used judiciously.

  • Bypasses Safety Checks: force: true skips checks like visibility, ensuring the element is not disabled, and not covered. This means your test might pass even if a real user couldn’t interact with the element.
  • Masking Issues: Overuse can hide genuine bugs in your application (e.g., an element that should be visible isn’t).
  • When to Use: It’s appropriate for elements that are programmatically hidden but still part of a valid user flow (e.g., custom styled radio buttons where the actual <input type="radio"> is hidden, and you interact with a styled <span>), or when simulating events that are hard to trigger through standard user actions.

Implementation with click({ force: true })

Section titled “Implementation with click({ force: true })”

Here’s how you might use force: true to click a hidden ‘Sign In’ link:

describe('Hidden Elements Test - force:true', () => {
it('Should force click a hidden element', () => {
// Example: Visit a page with a hidden sign-in link
cy.visit("https://www.example.com"); // Replace with your test page
// Assume '.hidden-signin-link' is a selector for an element that is display:none
// A more robust selector like data-cy attribute is recommended in real projects.
cy.contains('Sign In') // Or a more specific selector for the hidden link
.click({ force: true });
// Add assertions for the expected outcome
cy.url().should('include', '/signin');
});
});

The execution logs will show the click command being performed, and Cypress will indicate that the action was forced. This method directly interacts with the element despite its hidden state.

Whenever possible, try to interact with your application as a user would. If an element becomes visible after a hover, consider using cy.get('.trigger-element').trigger('mouseover') and then interacting with the now-visible element. If an element appears after an animation, use Cypress’s built-in retry-ability with assertions like .should('be.visible') before interacting.

For further reading on actionability and interacting with elements, refer to the official Cypress documentation on ‘Interaction’ and ‘Actionability’.