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.
Method 1: Using invoke('show')
Section titled “Method 1: Using invoke('show')”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.
Implementation with invoke('show')
Section titled “Implementation with invoke('show')”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.
Method 2: Using click({ force: true })
Section titled “Method 2: Using click({ force: true })”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.
Important Considerations for force: true:
Section titled “Important Considerations for force: true:”- Bypasses Safety Checks:
force: trueskips 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.
Best Practices and Alternatives
Section titled “Best Practices and Alternatives”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’.