Optimizing Cypress Test Scripts with Conditional Element Interactions

Optimizing Cypress Test Scripts with Conditional Element Interactions

During the promotion testing in an online back office system (SAP Hybris), I needed to interact with multiple UI components like “Container” and “Qualifying products.” These elements, buried inside other parent elements, would sometimes collapse, requiring additional clicks to expand and proceed with the test. However, if the components were already open, clicking them would close them, resulting in failed tests.

This small but significant roadblock inspired me to improve my approach to testing. After some trial and error, I came up with the following piece of Cypress code, which proved to be a game-changer:

cy.get('body').then($body => {
if ($body.find('.z-label:contains("Container")').length > 0) {
// If the element exists, scroll into view and click it
cy.get('.z-label')
.contains('Container')
.scrollIntoView()
.then(($container) => {
if (!$container.hasClass('open')) { // Assuming 'open' class signifies it's open
cy.wrap($container).click({ force: true }); // Click if not open
}
});
} else {
cy.log('Container not found, skipping to the next step.');
}
});

The Problem

I needed to check whether the “Container” section was open in the promotion testing workflows. If it wasn’t, my test needed to open it by clicking. But the challenge was making this interaction dynamic. If the “Container” was already open and Cypress clicked it again, it would collapse, causing the test to fail.

I needed a way to conditionally click the element only if it was closed. This would ensure smooth test execution without the risk of unnecessary interactions, especially in environments where UI states weren’t predictable.

The Solution

The solution came from leveraging Cypress’s ability to work with the DOM directly. Instead of simply trying to click an element and risking unwanted behavior, I decided to first check whether the element even existed. Here’s a breakdown of what the code does:

  • Checking if the element exists: The first step is to check whether the “Container” label is present. By using cy.get('body').then($body => {...}), I inspect the entire page and search for the element using $body.find('.z-label:contains("Container")'). This ensures that the test doesn’t break or time out if the “Container” label is missing.
  • Scrolling and opening the element: If the element exists, I scroll it into view with .scrollIntoView() and then check if it has an open class. If it’s not already open, Cypress clicks the element to open it. This conditional behavior made the test much more resilient and reliable.
  • Skipping if the element doesn’t exist: If the “Container” label isn’t present on the page, the code simply logs this and moves on to the next step in the test without throwing any errors or causing a timeout. This saved a lot of time when running tests in environments where certain sections might not always be visible.

Impact on My Test Scripts

This code dramatically reduced test failures that were caused by unpredictable UI states. Since promotions involved multiple components and steps, having a reliable way to conditionally interact with elements like “Container” was crucial.

Before implementing this solution, I found myself frustrated with rerunning tests due to minor issues like sections not being open. This meant either manually resetting the UI or writing repetitive test steps to handle every possible UI state. But this piece of code made my tests smarter—allowing them to dynamically adapt based on the state of the page.

Application in the Cypress Script Generator App

This approach didn’t just benefit me in the short term—it also influenced the app I was creating to generate Cypress scripts for testing promotions. The goal of the app was to make it easier to dynamically generate Cypress test scripts based on input, allowing multiple promotions and environments to be tested efficiently.

The logic used in this code—checking for element existence and only interacting when necessary—became a key component of how the app handled complex, multi-step interactions. It allowed me to abstract away the repetitive UI checks into a reusable pattern. As the app generated scripts, this logic ensured that tests were adaptable and resilient to changes in the promotion pages, meaning the generated scripts worked for different states without modification.

Lessons Learned

The process of refining this code taught me the importance of conditional logic in testing. Not all test steps need to be performed linearly—sometimes, a quick check to see if an element exists or is in the correct state can save a lot of headache down the line. By incorporating these smart checks, I created scripts that worked consistently, regardless of whether the “Container” section was open or closed, present or absent.

Scroll to Top