{"id":119,"date":"2024-01-05T10:27:13","date_gmt":"2024-01-05T09:27:13","guid":{"rendered":"https:\/\/sii.ua\/blog\/?p=119"},"modified":"2024-02-20T18:01:29","modified_gmt":"2024-02-20T17:01:29","slug":"automated-tests-cypress-waits-until-introduction-to-waits","status":"publish","type":"post","link":"https:\/\/sii.ua\/blog\/en\/automated-tests-cypress-waits-until-introduction-to-waits\/","title":{"rendered":"Automated tests: Cypress waits until\u2026 \u2013 introduction to waits"},"content":{"rendered":"\n<p>In the work of an automation tester, one of the key tasks is the correct handling of waits for the events, which allows us to perform assertions on an already prepared element. In testers jargon, we encounter the term &#8220;waits&#8221; from the wait() method, and this nomenclature is used in this article.<\/p>\n\n\n\n<p>In this post, I will elaborate on what waits are needed for in automated tests, present a comparison of waits available in Selenium and in Cypress, along with an example implementation in Cypress.<\/p>\n\n\n\n<p>Cypress significantly stand out from other available applications for automated testing due to one specific wait, which will also be described along with the cy.wait() and cy.intercept() methods.<\/p>\n\n\n\n<p>The last aspect raised in this article will be recursion, which can also be used in Cypress to wait for an item, as its own custom approach.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wait in automated tests<\/strong><\/h2>\n\n\n\n<p>Wait is one of the basic and key parts of an automated test. It allows us to perform a delay in the test to, in order to load the web page, or any element on that page, correctly. This will make it possible to check, that the results in a positive or negative completion of the test.<\/p>\n\n\n\n<p>Wait\u2019s wrong implementation can result in an incorrect test result, e.g. by trying to interact with a page, which has not fully loaded. Another popular problem is lack of an item\u2019s display, because it was waiting, for example, for the server response. However, one of the biggest difficulties connected with the wait\u2019s wrong implementation is the unnecessary waiting, which increases our test duration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wait in Selenium<\/strong><\/h2>\n\n\n\n<p>In one of the most popular tools for tests automation, that is Selenium, we encounter three types of waits, which I will describe below.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Implicit wait<\/strong><\/h3>\n\n\n\n<p>It consists of an attempt to find an element in the DOM for a spcidied time if it is not immediately available. The default value of this wait is 0 and when we change this value, the implicit wait lasts until the end of the session.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"769\" height=\"140\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/1-1.png\" alt=\"\" class=\"wp-image-71\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/1-1.png 769w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/1-1-300x55.png 300w\" sizes=\"(max-width: 769px) 100vw, 769px\" \/><figcaption class=\"wp-element-caption\">Fig. 1 Selenium example \u2013 Implicit wait<\/figcaption><\/figure>\n\n\n\n<p>As presented in the code above, the implementation of this solution is very fast, but it has some limitations. This wait <strong>works only with the findElement() method<\/strong>, and that keeps us from waiting to load, for example, the text in the element.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Explicit wait<\/strong><\/h3>\n\n\n\n<p>Thanks to it, we have a possibility to stop the test until our expected condition is met. Checking the condition is triggered with a certain frequency until the timeout expires. This means, that when the condition returns a false value, Selenium will wait and try again.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"908\" height=\"52\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/2-1.png\" alt=\"\" class=\"wp-image-73\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/2-1.png 908w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/2-1-300x17.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/2-1-768x44.png 768w\" sizes=\"(max-width: 908px) 100vw, 908px\" \/><figcaption class=\"wp-element-caption\">Fig. 2 Selenium example \u2013 Explicit wait<\/figcaption><\/figure>\n\n\n\n<p>In the code presented above, we wait until the title of our page gains the expected value. Keep in mind that <strong>the wait is now used only at the time of the trigger<\/strong>, and not as previously \u2013 globally. Here you will find <a aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.selenium.dev\/selenium\/docs\/api\/javascript\/module\/selenium-webdriver\/lib\/until.html\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >a list of available expected explicit wait conditions for Selenium<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>FluentWait<\/strong><\/h3>\n\n\n\n<p>We wait in an <strong>explicit manner<\/strong> for a certain situation for a given number of seconds \u2013 for example: the following code for 10 seconds will check if our website has the expected title with the frequency of one second.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1024\" height=\"42\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/3-1024x42-1.png\" alt=\"\" class=\"wp-image-75\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/3-1024x42-1.png 1024w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/3-1024x42-1-300x12.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/3-1024x42-1-768x32.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Fig. 3 Selenium example \u2013 FluentWait<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wait in Cypress<\/strong><\/h2>\n\n\n\n<p>Cypress, by default, uses dynamic wait for elements or actions available on the web page used in our automated test. We can distinguish the following ways to handle waits.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Default timeouts<\/strong><\/h3>\n\n\n\n<p>In Cypress there are 6 default timeouts available. Thanks to the built-in re-try mechanism, they perform checks in a defined by us, or preset time, similarly to the explicit wait previously described:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>defaultCommandTimeout \u2013 it is the time, in which Cypress tries to get to the element or action while executing most of the commands on the DOM.<\/li>\n\n\n\n<li>execTimeout &#8211; a timeout that defines how long to wait for the system to complete the operations during the cy.exec() command.<\/li>\n\n\n\n<li>taskTimeout &#8211; the maximum time, in which we wait for a task completion during the cy.task() command.<\/li>\n\n\n\n<li>pageLoadTimeout &#8211; waits for the &#8220;page transition event&#8221;. This event occurs when a user visits or leaves a particular web page. This default timeout also waits for the cy.visit(), cy.go(), cy.reload() commands to execute load events. They are triggered when the entire page and all its contents, i.e. style sheet, scripts, iframes and images are loaded.<\/li>\n\n\n\n<li>requestTimeout &#8211; the maximum time we wait for cy.wait() execution.<\/li>\n\n\n\n<li>responseTimeout &#8211; waits for the execution of cy.request(), cy.wait(), cy.fixture(), cy.getCookie(), cy.getCookies(), cy.setCookie(), cy.clearCookie(), cy.clearCookies() and cy.screenshot() methods.<\/li>\n<\/ul>\n\n\n\n<p>If we want to overwrite the values for timeouts, we do it in the cypress.json file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"407\" height=\"145\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/4.png\" alt=\"\" class=\"wp-image-85\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/4.png 407w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/4-300x107.png 300w\" sizes=\"(max-width: 407px) 100vw, 407px\" \/><figcaption class=\"wp-element-caption\">Fig. 4 Cypress \u2013 cypress.json set value defaultCommandTimeout<\/figcaption><\/figure>\n\n\n\n<p>We can also change these times for a given action chain or the method itself by sending the object with an expected time:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"683\" height=\"36\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/5.png\" alt=\"\" class=\"wp-image-87\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/5.png 683w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/5-300x16.png 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><figcaption class=\"wp-element-caption\">Fig. 5 Cypress \u2013 implicit subject used and overwriting defaultCommandTimeout by sending object to the get method<\/figcaption><\/figure>\n\n\n\n<p>In the code above we used implicit subject to create assertion with the .should() method. First, Cypress tries to find the button element within the 20 seconds defined in the object sent {timeout: 20000}, and then performs assertion on that button, to check if it contains the text \u201cSearch in Google\u201d. Here, again, waits up to 20 seconds for the text to appear. We can obtain the timeout while executing the cy.get() and should() method, which will negate the entire test.<\/p>\n\n\n\n<p>For the get(), find(), cointains() methods, from my experience, I recommend using a timeout on the action chain in case the wait for an item or its properties is extended. Whereas, the timeout set in cypress.json should be limited to a reasonable minimum to avoid unnecessary lengthening of the tests in case we receive a fail.<\/p>\n\n\n\n<p>In Cypress, we have the possibility to make a similar assertion with an explicit subject by using the .then() method and making an assertion on a JQuery element:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"564\" height=\"72\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/6.png\" alt=\"\" class=\"wp-image-89\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/6.png 564w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/6-300x38.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/6-555x72.png 555w\" sizes=\"(max-width: 564px) 100vw, 564px\" \/><figcaption class=\"wp-element-caption\">Fig. 6 Cypress example \u2013 assertion with explicit subject<\/figcaption><\/figure>\n\n\n\n<p>In this case, Cypress first waits up to 20 seconds for the .get() method, and then immediately makes an assertion on the element, omitting the defined defaultCommandTimeout.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Built-in Wait<\/strong><\/h3>\n\n\n\n<p>Cypress has its own implementation of the wait method, which takes up to two arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>One of the first values is a numeric value given in milliseconds. This is the value of time, which elapses between the previous and the next command in the Cypress action chain.<\/li>\n\n\n\n<li>The next value we can send in place of time is an alias or an alias table. Aliases are a tremendous construct in Cypress that has many uses and a separate article could be written about it. However, for us, in the waits concept, the most important thing is to focus on the possibility to assign an alias to the API call. We do it through the cy.intercept() and the .as() method, where the as method saves an alias, to which we have access with the use of the @ prefix.<\/li>\n\n\n\n<li>The last, optional, value is the option object, which allows us to overwrite the previously defined default times for requestTimeout and responseTimeout. Additionally, it pro {log: true\/false} object.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"451\" height=\"178\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/7.png\" alt=\"\" class=\"wp-image-91\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/7.png 451w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/7-300x118.png 300w\" sizes=\"(max-width: 451px) 100vw, 451px\" \/><figcaption class=\"wp-element-caption\">Fig. 7 Cypress \u2013 ways of cy.wait() implementation<\/figcaption><\/figure>\n\n\n\n<p>This code shows the Cypress wait implementation. This method allows us to wait in a specific place in the code for a given time or until an appropriate alias appears.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Creating an alias<\/strong><\/h3>\n\n\n\n<p>In order to properly create a wait for an alias, we need that alias precisely. One method to create it is to look at the queries made by the browser on our test page. Then, we select the last query or the last few queries made, which, with high probability, will show us that the page is loaded.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"856\" height=\"186\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/8.png\" alt=\"\" class=\"wp-image-95\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/8.png 856w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/8-300x65.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/8-768x167.png 768w\" sizes=\"(max-width: 856px) 100vw, 856px\" \/><figcaption class=\"wp-element-caption\">Fig. 8 The list of API queries on the www.google.pl page<\/figcaption><\/figure>\n\n\n\n<p>and manage requests and responses in the network. It allows us to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mock data<\/li>\n\n\n\n<li>Validate API requests<\/li>\n\n\n\n<li>And thanks to the combination with cy.wait(), wait for the end of the given API query.<\/li>\n<\/ul>\n\n\n\n<p>Then, with the .as() method, we can save the tracked request as an alias.<\/p>\n\n\n\n<p><strong><strong>Intercept implementation<\/strong><\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"542\" height=\"94\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/9.png\" alt=\"\" class=\"wp-image-97\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/9.png 542w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/9-300x52.png 300w\" sizes=\"(max-width: 542px) 100vw, 542px\" \/><figcaption class=\"wp-element-caption\">Fig. 9 Cypress example \u2013 implementation of the cy.intercept() method<\/figcaption><\/figure>\n\n\n\n<p>The intercept implementation, which we subsequently use in the test, is shown above. Its task is to:<\/p>\n\n\n\n<ol class=\"wp-block-list\" style=\"list-style-type:1\">\n<li>Visit google.pl webpage.<\/li>\n\n\n\n<li>Accept cookies.<\/li>\n\n\n\n<li>Enter \u201cSii\u201d in the search bar and click on the Enter button.<\/li>\n\n\n\n<li>Wait for the @finishedGoogleSearch alias.<\/li>\n\n\n\n<li>Check whether the text \u201cOko\u0142o\u201d is visible on the loaded page.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"564\" height=\"195\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/10.png\" alt=\"\" class=\"wp-image-99\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/10.png 564w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/10-300x104.png 300w\" sizes=\"(max-width: 564px) 100vw, 564px\" \/><figcaption class=\"wp-element-caption\">Fig. 10 Cypress example \u2013 test code using the wait for alias method<\/figcaption><\/figure>\n\n\n\n<p><strong>I advise avoiding waits for a given time and focus on waiting for aliases.<\/strong> It will make our tests shorter and the code will be more optimized and significantly free of unexpected exceptions.<\/p>\n\n\n\n<p>One of the additional packages for the ESLint is the Cypress ESLint Plugin, which allows us to define the rule &#8220;cypress\/no-unnecessary-waiting&#8221;: &#8220;error&#8221; and detect these waits while creating automated tests.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Custom waits implementation<\/strong><\/h3>\n\n\n\n<p>In case we need a custom wait, that doesn&#8217;t qualify for the previously described cy.wait(), we can use a recursive wait with a condition check with every reference.<\/p>\n\n\n\n<p><strong>Recursion is the reference of a function or definition to itself.<\/strong> It occurs in mathematics (Euclid&#8217;s algorithm, Fibonacci sequence), programming and even art (a picture within a picture or placing two mirrors opposite each other &#8211; that&#8217;s exactly when we get a reflection within a reflection).<\/p>\n\n\n\n<p>But let&#8217;s get back to programming and our example. We want to write a wait, which will wait for the expected item to appear on the page.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"846\" height=\"643\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/11.png\" alt=\"\" class=\"wp-image-101\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/11.png 846w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/11-300x228.png 300w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/11-768x584.png 768w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><figcaption class=\"wp-element-caption\">Fig. 11 Cypress example \u2013 recursive wait implementation for an element to appear<\/figcaption><\/figure>\n\n\n\n<p>Wait performs this task in the following order:<\/p>\n\n\n\n<ol class=\"wp-block-list\" style=\"list-style-type:1\">\n<li>Retrieving the contents of the body with the .get() method.<\/li>\n\n\n\n<li>Then, changing this object into a JQuery object, calling the .find(locator) method on it and finally .length, which returns 0 if the element is not in the body.<\/li>\n\n\n\n<li>Waiting in the split time &#8211; that is the time after which we want to make another check whether the element meets the given condition.<\/li>\n\n\n\n<li>Defining totalTime and starting to increase it by a given break time (split) with each subsequent recursive call.<\/li>\n\n\n\n<li>Checking if totalTime is less than or equal to the timeout. Depending on the result of the condition, it recursively calls the checkForElement() function, or calls cy.get(resultText) to negate the test.<\/li>\n\n\n\n<li>Finally, calling cy.get(resultsText) when the condition body.find(elementID).length === 0 is not met, which closes the recursion.<\/li>\n<\/ol>\n\n\n\n<p>It is not a perfect solution of that problem and <strong>should be used as a last resort<\/strong>, because we are dealing with a difficulty of code readability and maintainability.<\/p>\n\n\n\n<p>The code above is very hard to debug in Cypress and incompetent use of recursion or loops may result in falling into an infinite loop. endless loop. There is a possibility of its occurrence when mixing synchronous and asynchronous code or when the increment conditions are incorrectly controlled. Eventually, the infinite loop will cause the test error and the browser will stop responding.<\/p>\n\n\n\n<p>It is not a perfect solution of that problem and <strong>should be used as a last resort<\/strong>, because we are dealing with a difficulty of code readability and maintainability.<\/p>\n\n\n\n<p>The code above is very hard to debug in Cypress and incompetent use of recursion or loops may result in falling into an infinite loop. endless loop. There is a possibility of its occurrence when mixing synchronous and asynchronous code or when the increment conditions are incorrectly controlled. Eventually, the infinite loop will cause the test error and the browser will stop responding.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"660\" height=\"159\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/12-1.png\" alt=\"\" class=\"wp-image-103\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/12-1.png 660w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/12-1-300x72.png 300w\" sizes=\"(max-width: 660px) 100vw, 660px\" \/><figcaption class=\"wp-element-caption\">Fig. 12 Cypress \u2013 exemplary implementation of cypress-wait-until<\/figcaption><\/figure>\n\n\n\n<p>cypress-recurse \u2013 the package provides a recursive wait until the expected codition returns a True value. In this case, our expected condition is expect(button).to.have.value(\u2018Szukaj w Google\u2019)}. The method will negate the test if within 30 seconds this condition will not return the True value. The condition itself will be checked with the frequency of 0.5 seconds. Default values for the method are: timeout=4000, limit=15, delay=800.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"455\" height=\"313\" src=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/13.png\" alt=\"\" class=\"wp-image-105\" style=\"object-fit:cover\" srcset=\"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/13.png 455w, https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/13-300x206.png 300w\" sizes=\"(max-width: 455px) 100vw, 455px\" \/><figcaption class=\"wp-element-caption\">Fig. 13 Cypress \u2013 exemplary implementation of cypress-recurse<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Selenium vs. Cypress waits<\/strong><\/h2>\n\n\n\n<p>So let\u2019s look for <strong>similarities<\/strong> between Selenium waits and Cypress waits.<\/p>\n\n\n\n<p>Let\u2019s start with the implicit wait. We can observe a similar behavior in Cypress &#8211; by controlling &#8220;defaultCommandTimeout&#8221; or the timeout itself, we can wait for an element to appear on the page with the use of the cy.get() method in the time we specify.<\/p>\n\n\n\n<p>Explicit wait in Cypress is quite a controversial topic, because it is supposed to check a condition. Cypress .should(&#8216;be.visible&#8217;) method can be treated as the equivalent of the expected condition in Selenium elementIsVisible(element).<\/p>\n\n\n\n<p>However: is the assertion a wait? If we assume that it is, then we can treat all .should() assertions as an explicit wait. I am sure that  opinions on this theory are divided, so I leave the answer to this question to your own interpretation \ud83d\ude42<\/p>\n\n\n\n<p>Let&#8217;s not forget the cy.wait(@alias). It is this wait that can be <strong>considered a full-fledged explicit<\/strong>. The presented cypress-wait-until-until and cypress-recurse external packages are closer to an explicit, or even a fluent wait, due to the possibility to control the interval according to which the condition is checked.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Summary<\/strong><\/h2>\n\n\n\n<p>In this article, I have presented the available ways of waiting for elements in Selenium and Cypress &#8211; waits, which allow you to work freely on most elements. I have presented the difference in time with Cypress assertions. I have prepared a sample code with my own wait and have gone over two external packages that we can work with in Cypress, depending on our needs.<\/p>\n\n\n\n<p>If you are starting your adventure with Cypress, it is worth acquiring knowledge of the cy.wait(&#8216;@Alias&#8217;) area from the beginning. It is a basic functionality of the tool, which increases the quality of the code in our automated tests and eliminates the need to wait for the element to load. Good luck! <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.selenium.dev\/documentation\/webdriver\/waits\/\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Selenium \u2013 Documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.cypress.io\/guides\/overview\/why-cypress\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Why Cypress?<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/cypress-io\/eslint-plugin-cypress\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >GitHub \u2013 Cypress ESLint Plugin<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/NoriSte\/cypress-wait-until\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >GitHub \u2013 Cypress wait until<\/a><\/li>\n\n\n\n<li><a aria-label=\" (opens in a new tab)\" class=\"ek-link\" href=\"https:\/\/github.com\/bahmutov\/cypress-recurse\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >GitHub \u2013 Cypress recurse<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;119&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;2&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5&quot;,&quot;size&quot;:&quot;30&quot;,&quot;title&quot;:&quot;Automated tests: Cypress waits until\u2026 \u2013 introduction to waits&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/5&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 2px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 24px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the work of an automation tester, one of the key tasks is the correct handling of waits for the &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.ua\/blog\/en\/automated-tests-cypress-waits-until-introduction-to-waits\/\">Continued<\/a><\/p>\n","protected":false},"author":17,"featured_media":996,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[33,31,34,35,30],"class_list":["post-119","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-automatisation","tag-cypress","tag-selenium","tag-test-automation","tag-wait"],"acf":[],"aioseo_notices":[],"featured_media_url":"https:\/\/sii.ua\/blog\/wp-content\/uploads\/2024\/01\/Automated-tests-Cypress.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/119"}],"collection":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/comments?post=119"}],"version-history":[{"count":29,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/119\/revisions"}],"predecessor-version":[{"id":1023,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/posts\/119\/revisions\/1023"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/media\/996"}],"wp:attachment":[{"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/media?parent=119"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/categories?post=119"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.ua\/blog\/en\/wp-json\/wp\/v2\/tags?post=119"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}