{"id":19362,"date":"2023-02-07T05:00:00","date_gmt":"2023-02-07T04:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/testy-automatyczne-cypress-czeka-az-wprowadzenie-do-waitow\/?category=hard-development"},"modified":"2024-12-05T11:18:34","modified_gmt":"2024-12-05T10:18:34","slug":"automated-tests-cypress-waits-until-introduction-to-waits","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/automated-tests-cypress-waits-until-introduction-to-waits\/","title":{"rendered":"Automated tests: Cypress waits until&#8230; \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<p>Previously on our blog appeared an <a href=\"https:\/\/sii.pl\/blog\/cypress-dlaczego-warto-zainteresowac-sie-tym-frameworkiem\/?category=testowanie&amp;tag=cypress,poradnik,zalety-i-wady\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">introductory article on Cypress<\/a> (only PL). I encourage you to read it to learn about the rest of the tool&#8217;s features.<\/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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/1-1.png\"><img decoding=\"async\" width=\"769\" height=\"140\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/1-1.png\" alt=\"Selenium example \u2013 Implicit wait\" class=\"wp-image-18854\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/1-1.png 769w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/1-1-300x55.png 300w\" sizes=\"(max-width: 769px) 100vw, 769px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2-1.png\"><img decoding=\"async\" width=\"908\" height=\"52\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2-1.png\" alt=\"Selenium example \u2013 Explicit wait\" class=\"wp-image-18857\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2-1.png 908w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2-1-300x17.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2-1-768x44.png 768w\" sizes=\"(max-width: 908px) 100vw, 908px\" \/><\/a><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 href=\"https:\/\/www.selenium.dev\/selenium\/docs\/api\/javascript\/module\/selenium-webdriver\/lib\/until.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" 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-large\"><img decoding=\"async\" width=\"1024\" height=\"42\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/3-1024x42.png\" alt=\"Selenium example \u2013 FluentWait\" class=\"wp-image-18859\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/3-1024x42.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/3-300x12.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/3-768x32.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/3.png 1159w\" 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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/4.png\"><img decoding=\"async\" width=\"407\" height=\"145\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/4.png\" alt=\"Cypress \u2013 cypress.json set value defaultCommandTimeout\" class=\"wp-image-18862\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/4.png 407w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/4-300x107.png 300w\" sizes=\"(max-width: 407px) 100vw, 407px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/5.png\"><img decoding=\"async\" width=\"683\" height=\"36\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/5.png\" alt=\"Cypress \u2013 implicit subject used and overwriting defaultCommandTimeout by sending object to the get method\" class=\"wp-image-18864\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/5.png 683w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/5-300x16.png 300w\" sizes=\"(max-width: 683px) 100vw, 683px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/6.png\"><img decoding=\"async\" width=\"564\" height=\"72\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/6.png\" alt=\"Przyk\u0142ad Cypress \u2013 asercja z explicit subject\" class=\"wp-image-18866\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/6.png 564w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/6-300x38.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/6-555x72.png 555w\" sizes=\"(max-width: 564px) 100vw, 564px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/7.png\"><img decoding=\"async\" width=\"451\" height=\"178\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/7.png\" alt=\"Cypress \u2013 ways of cy.wait() implementation\" class=\"wp-image-18868\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/7.png 451w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/7-300x118.png 300w\" sizes=\"(max-width: 451px) 100vw, 451px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/8.png\"><img decoding=\"async\" width=\"856\" height=\"186\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/8.png\" alt=\"The list of API queries on the www.google.pl page\" class=\"wp-image-18870\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/8.png 856w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/8-300x65.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/8-768x167.png 768w\" sizes=\"(max-width: 856px) 100vw, 856px\" \/><\/a><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>Once we find the query of interest, all we need to do is use the cy.intercept() method. It allows us to track 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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/9.png\"><img decoding=\"async\" width=\"542\" height=\"94\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/9.png\" alt=\"Cypress example \u2013 implementation of the cy.intercept() method\" class=\"wp-image-18872\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/9.png 542w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/9-300x52.png 300w\" sizes=\"(max-width: 542px) 100vw, 542px\" \/><\/a><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\">\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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/10.png\"><img decoding=\"async\" width=\"564\" height=\"195\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/10.png\" alt=\"Cypress example \u2013 test code using the wait for alias method\" class=\"wp-image-18874\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/10.png 564w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/10-300x104.png 300w\" sizes=\"(max-width: 564px) 100vw, 564px\" \/><\/a><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 aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/11.png\"><img decoding=\"async\" width=\"846\" height=\"643\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/11.png\" alt=\"Cypress example \u2013 recursive wait implementation for an element to appear\" class=\"wp-image-18877\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/11.png 846w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/11-300x228.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/11-768x584.png 768w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><\/a><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\">\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<h2 class=\"wp-block-heading\"><strong><strong>External wait packages available<\/strong><\/strong><\/h2>\n\n\n\n<p>In this chapter, I will go over two packages, that I know of, which we can use in our tests.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>cypress-wait-until \u2013 it allows waiting for everything that the cy.wait() method is not waiting for. The cy.waitUntil() method takes two arguments. The first one is a function that executes a Cypress method, methods or a whole chain of actions. The next argument is an option object, which allows controlling the timeout and interval. The code tries to access the browser field for three seconds with a one second interval. By editing the default values, we can freely control the timeout and interval values. The default values for this wait are timeout=5000, interval=200.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/12.png\"><img decoding=\"async\" width=\"660\" height=\"159\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/12.png\" alt=\"\" class=\"wp-image-18880\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/12.png 660w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/12-300x72.png 300w\" sizes=\"(max-width: 660px) 100vw, 660px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 12 Cypress \u2013 exemplary implementation of cypress-wait-until<\/figcaption><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>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.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/13.png\"><img decoding=\"async\" width=\"455\" height=\"313\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/13.png\" alt=\"Cypress \u2013 przyk\u0142adowa implementacja cypress-recurse\" class=\"wp-image-18885\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/13.png 455w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/13-300x206.png 300w\" sizes=\"(max-width: 455px) 100vw, 455px\" \/><\/a><figcaption class=\"wp-element-caption\">Fig. 13 Cypress \u2013 exemplary implementation of cypress-recurse<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/en\/job-ads\/all\/it-testing-qa\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" width=\"737\" height=\"170\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/praca-k-EN-4.jpg\" alt=\"job offer\" class=\"wp-image-29817\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/praca-k-EN-4.jpg 737w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2024\/12\/praca-k-EN-4-300x69.jpg 300w\" sizes=\"(max-width: 737px) 100vw, 737px\" \/><\/a><\/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\ude0a<\/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 href=\"https:\/\/www.selenium.dev\/documentation\/webdriver\/waits\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" 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 href=\"https:\/\/github.com\/bahmutov\/cypress-recurse\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >GitHub \u2013 Cypress recurse<\/a><\/li>\n<\/ul>\n\n\n\n<p>***<\/p>\n\n\n\n<p>If you are interested in the topic of Cypress, Selenium or test automation, we encourage you to check out <a href=\"https:\/\/sii.pl\/blog\/en\/testing\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">other articles by our experts<\/a>.<\/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;19362&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;47&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.8&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.8\\\/5 ( votes: 47)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Automated tests: Cypress waits until... \u2013 introduction to waits&quot;,&quot;width&quot;:&quot;133.7&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&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: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 133.7px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.8\/5 ( votes: 47)    <\/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.pl\/blog\/en\/automated-tests-cypress-waits-until-introduction-to-waits\/\">Continued<\/a><\/p>\n","protected":false},"author":460,"featured_media":19761,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":10,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1321],"tags":[1618,1619,1328,1440,1459],"class_list":["post-19362","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testing","tag-wait-en","tag-cypress-en","tag-automatisation-en","tag-selenium-en","tag-test-automation-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/Testy-automatyczne-Cypress-czeka-az\u2026-\u2013-wprowadzenie-do-waitow.jpg","category_names":["Testing"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/19362"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/460"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=19362"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/19362\/revisions"}],"predecessor-version":[{"id":29819,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/19362\/revisions\/29819"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/19761"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=19362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=19362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=19362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}