Cypress is a powerful test automation tool that executes very fast, in my experience, sometimes even too fast… I used a recursive function to reload the window if an element was not propagated on the frontend on time.
Test case: Remove the tag from a mention.
(Test case background: Determ app is a media monitoring tool that tracks brand mentions from all over the internet. One of its features is that a user, for easier sorting of their mentions, can create and add tags to each of the mentions, and remove them of course.)
In my Cypress automated test, to remove a tag from a mention, the tag needs to be created first, so the test creates a tag on the backend before validating that it can be removed on the frontend. However, sometimes it happens that the tag gets created on the backend and does not get propagated on the frontend soon enough, i.e. it does not appear before the Cypress visits the feed page. If that happens when manually visiting the page, which is hard to happen — only in the case of a heavy load on a system, you would need to reload the page and the tag would show up. And that is exactly what I needed to implement in my automated test.
Problems and Solutions
-
Issue: Sometimes, but not every time, Cypress visits the page too soon before the “tag” element is propagated on the frontend.
Solution: Use
cy.reload()
to reload the window. - Issue: When Cypress does not find an element that you put in the test, it fails with an error that element does not exist. Solution: Use a recursive function* that reloads the window if the given element is not found.
- Issue: Edge case alert — if somehow happens that the tag does not get created on the backend at all, the function will end up in an infinite loop because no matter how many times it reloads the element won't be found. Solution: Add a retry increment to each call of the function and add a rule for maximum retries — if the element did not show up after the first or second window reload, it probably won’t at all so throw an error.
- Positive outcome: If the tag element is loaded on time or loaded after a window reload, validate that it is visible and continue with the test.
Function explanation:
- First Cypress gets an element of one mention.
- On that element/mention checks if there is text with the added tag name
- First if condition — if the text on the mention does not include added tag name -> reload the window -> call the function again and increment retries by one.
- Second if condition — if max retries is equal to retries -> throw an error and fail the test.
- If all conditions pass — Cypress checks that the tag on the mention element contains the text of the created tag -> the function finishes -> the test continues with execution
Using recursion instead of loop commands (like while)
Using JavaScript loop commands like while can have unexpected effects because Cypress commands are asynchronous and get queued for execution at a later time. And in my case, if I had used the loop instead of recursion, the Cypress would just pile up “cy.get(‘mention-tags’)” commands to the test chain, without executing any. Then the chain of commands would keep growing but never execute — since the test function would never finish running. The while loop never allows Cypress to start executing even the very first cy.get(…)
command.
Final thoughts
By implementing a recursive function and utilizing window reloading in Cypress test automation, we have effectively addressed the issue of elements not being propagated on the front end in time. This solution ensures more reliable and stable test execution, enhancing the effectiveness of our Cypress automated tests.
Also, there are many useful ways to utilize recursion with Cypress. For example, if you need to find a user in a list that has pagination, a function can check if the user’s name is on the first page, if not, click on the next page and call the function again, if the next page can’t be clicked, throw an error that the user is not to be found in the list.
*A recursive function is a type of function that calls itself until your program achieves the desired result.
Find out more:
- https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Avoid-loops
- https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code
- https://www.freecodecamp.org/news/what-is-recursion-in-javascript/
- https://help.determ.com/en/articles/6600022-mention-tagging
Top comments (0)