The code I’m testing has a lot of <a>
tag elements that render with an href tag but shortly after page load are given some click event that does something different (such as opening a modal). The href is a fallback and the intended behavior is in the click event.
Cypress is often too fast for the page’s javascript and clicks the element before the event has been added to it. This causes the page to navigate to the default href, rather than triggering the behavior I want to test. Here’s an example, where I use a timeout to simulate the slow-loading JS:
<a id="reveal_cats" href="https://http.cat" >
Show me cats!
</a>
<div id="cats_div" style="display: none;">
Cats!
</div>
<script>
// Using a timeout to simulate a slow-loading JS file
// that adds a click handler
setTimeout(
() => {
console.log("Handler is added")
$("#reveal_cats").on("click", function(e) {
e.preventDefault();
$("#cats_div").show()
})
}, 3000
)
</script>
it("fails because the click handler isn't loaded yet", () => {
cy.contains("a", "Show me cats!").click()
// This fails because the event handler isn't loaded yet
// so instead we've navigated to http.cat
cy.get("#cats_div").should("be.visible")
})
it("passes, but uses an undesirably long hardcoded wait", () => {
cy.contains("a", "Show me cats!").click()
cy.wait(5000)
cy.get("#cats_div").should("be.visible")
})
How can I get Cypress to wait for the handler to be loaded?
My first guess was to use an intercept to wait for the JS file that adds the handler, but the filenames are randomly generated, so they’re not reliable.
My second guess was to try to assert for event handlers on the element, but I don’t see a standard assertion for that. I thought maybe I could look for listeners in a then()
block using the jQuery utility, but I don’t believe that will retry properly if the event isn’t found on the first try.
The only solution I’ve found so far that works is hardcoded waits…
hasEventListeners
command off a different Cypress command, such ascy.contains()
orcy.get().find()
, and it doesn't appear that the package supports that. Still, helpful! – Babblement