The Problem
Having implemented Cypress recently for end to end testing I quickly realized the framework itself although pretty robust, was seriously lacking in the ajax support department. In other words, if an element wasn’t present within 5 seconds, the framework would throw and error and the test would fail.
This quickly becomes an issue for API calls that may require more time. There were quickly many scenarios where I needed the framework to wait for an element to be present and there was no native support for it that I could find.
The Solution
A quick web search showed a few threads on various websites where others discussed how to implement a simple version, but I wanted something a bit more robust, configurable and complete. Specifically, it needed to support custom timeouts as well as the default chaining behavior of all other Cypress queries. Here is the version I came up with.
Add the following to your /project/cypress/support/commands.js
file:
Cypress.Commands.add("waitForElement", (selector, options) => {
const defaults = {
timeout: 30000,
log: false,
time: Date.now(),
defaultCommandTimeout: Cypress.config("defaultCommandTimeout"),
};
options = { ...defaults, ...options };
const doc = cy.get("body", { log: options.log }).specWindow.parent[0]
.document;
if (Date.now() - options.time >= options.timeout) {
throw new Error(`Timed out waiting for element ${selector}`);
}
if (!doc.querySelector(selector)) {
cy.wait(options.defaultCommandTimeout, { log: options.log });
return cy.waitForElement(selector, options);
}
return cy.get(selector);
});
Example Usage
Once implemented, the waitForElement
command can be used in the following way:
cy.waitForElement(".my-element-to-be-rendered").click();
The command can be used in the standard chainable way as any other Cypress command, complete with a option
blocks for customization. The option
block supports a custom timeout
parameter which allows for customization of the timeout.
Hopefully, this helps anyone out there currently fighting with timing issues where elements aren’t immediately present or require a longer wait time. I’m always open to suggestions or ways to make code better, so if you have any feedback, I’d love to hear it. Thanks for stopping by.
0 Comments