Automating APEX: Building a Robust APEX Test Suite with Cypress
- Isaac
- Aug 15, 2025
- 4 min read
In my last blog, I introduced Cypress and walked through the basic building blocks of a test suite. Now, I’ll dive into some of the challenges I’ve faced using Cypress with APEX, along with how to overcome them.

Secrets
As a basic rule of development, you should never hardcode sensitive information like login credentials or database connections, especially if your code is going to be stored in a public repository such as GitHub. Cypress provides a way of abstracting this information by using environment variables.
Cypress.env
You can create a new file in the root of your project titled cypress.env.json and store your credentials in this format:
{
"username": "your_username",
"password": "your_password"
}You must never commit your cypress.env.json file to a repository. Add the file to your .gitignore to prevent your secrets from being pushed! Then, you can reference the variables in your tests:
cy.get('#P9999_USERNAME').type(Cypress.env('username'));
cy.get('#P9999_PASSWORD').type(Cypress.env('password'));Log: false
Using environment variables is a great way of keeping your secrets out of your code, but they can still appear in Cypress’ test logs, as demonstrated below, the user’s password is displayed in plain text when running tests with the variables above.

You can hide sensitive values from the logs by adding {log: false} to the command:
cy.get("#P9999_USERNAME")
.type(Cypress.env('username'), {log: false})This ensures your information is kept secure and remains hidden throughout the test.
Avoiding flaky tests
The most frustrating problem I faced while testing my APEX applications was flaky tests. If you’ve experimented with Cypress before, this might sound familiar: you write a test suite, run it, and it passes - great! But when you run it again, it suddenly fails, stuck looking for a page item that should be clearly visible, and the test eventually times out.
Waits
At first, waits can seem like the magic fix to solve all problems involving slow page loads, modals, and select lists - but don’t fall into the trap of overusing them! Hard coded waits are actually one of the biggest causes of flaky tests, a lesson I learned early on as a novice tester. Instead, use assertions to wait until cypress can see a page item before moving on.
cy.get('#P9999_USERNAME')
.should('be.visible')
.type(Cypress.env('username'));The line .should('be.visible') will force cypress to wait until the item P9999_USERNAME is visible before moving onto the next line.
Selectors
Cypress can sometimes have trouble finding an element by its identifier. It’s important to follow best practices and avoid relying on CSS attributes like class or tag names, as these can change when your application is updated. Instead, in the APEX builder, open the advanced tab for the component you would like to select and add a data-cy custom attribute. This will give you a stable and reliable selector to use in your tests.

Add the data-cy attribute under the advanced tab of an item
cy.get('[data-cy="USERNAME"]')
.should('be.visible')
.type(Cypress.env('username'));Use the data-cy attribute as demonstrated in the code above
Dynamic components
Modals
Testing elements inside modals can seem impossible at first, this is because Cypress cannot see into iframes by default. An iframe is an HTML element that seamlessly embeds content from another source into your webpage, and is used in APEX to display modal dialogues. The simplest solution to this is to import the aptly named library cypress-iframe. Simply add the line import 'cypress-iframe'; into your commands.js file and call cy.iframe() each time before you access a modal.
Popup LOVs
I have experimented with lots of different ways of accessing popup LOVs while using cypress, and there are lots of different ways that work. I will share with you the method that I have found to run the fastest and least flaky.
First, we access the LOV itself, using its data-cy attribute we talked about earlier.
cy.get('[data-cy="my_LOV"]')
.should('be.visible')
.click()Then, we search the popup LOV attribute '.a-IconList-item' for our item and click it!
cy.get('.a-IconList-item')
.should('be.visible')
.contains('my_item')
.click()Select one
I was testing an app that featured a lot of select one lists, everything worked until APEX was upgraded to 24.2.6. All of a sudden my tests began to break when trying to populate the list values, throwing a CORS error at me. I won’t go into too much detail here about what was happening (read this blog by Richard for more info) but before accessing Select one lists you must add the line:
experimentalModifyObstructiveThirdPartyCode: true,to your cypress.config.js file. Once that is done we can proceed.
As with the PopUp LOVs, there are numerous ways to access Select One lists. My preferred method is to first get the list:
cy.get('[data-cy="my_Select_One"]')
.should('be.visible')Then search for the item, and use Cypress key sequence commands to select it.
.type("My item")
.type("{downArrow}{enter}", {delay: 500})The delay is key to ensure the key sequences are executed in the correct order, preventing the enter key running before the downArrow key.
Summary
Creating a robust Cypress test for APEX can be challenging and time consuming, but it’s extremely rewarding in the long run. Start small and build gradually, once your tests are set up, you will be able to confidently deploy and update applications without the worry of regressions. There are many things I have not covered in this blog, so stay tuned for future posts on advanced topics such as API testing, continuous integration, and more!




