Skip to content

Commit 2bf63c1

Browse files
committed
Simplified the await chapter
1 parent 717c39f commit 2bf63c1

File tree

1 file changed

+8
-219
lines changed

1 file changed

+8
-219
lines changed

sections/generic-best-practices/await-dont-sleep.md

Lines changed: 8 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -41,69 +41,30 @@ Waitings fall in four main categories
4141
allows you to understand that the page is interactive
4242
- **[content waitings](#content-waitings)**: waiting for DOM element that matches a selector
4343
- **[XHR request waitings](#xhr-request-waitings)**: waiting for an XHR request start or the corresponding response received
44-
- **[custom waitings](#custom-waitings)**: waiting for everything strictly related to the app that does not fall into
45-
the above categories
4644

47-
Every UI testing tool manages waitings in different ways, sometimes automatically and
48-
sometimes manually. Below you can find some examples
49-
of implementing the listed waitings.
45+
All the following examples are based on Cypress.
5046

5147
<br/><br/>
5248

5349
## Page load waitings
5450

55-
Every tool manages the page load waiting in a different way (in terms of what is waited before
56-
considering the page loaded).
57-
58-
Cypress
59-
6051
```javascript
52+
// Cypress code
6153
cy.visit('http://localhost:3000')
6254
```
6355

64-
<details><summary>Puppeteer (and Playwright)</summary>
65-
66-
```javascript
67-
await page.goto('http://localhost:3000')
68-
```
69-
70-
</details>
71-
72-
<details><summary>Selenium</summary>
73-
74-
```javascript
75-
driver.get('http://localhost:3000')
76-
driver.wait(function () {
77-
return driver.executeScript('return document.readyState').then(function (readyState) {
78-
return readyState === 'complete'
79-
})
80-
})
81-
```
82-
83-
</details>
84-
85-
<details><summary>TestCafé</summary>
86-
87-
```javascript
88-
fixture`Page Load`.page`http://localhost:3000`
89-
```
90-
91-
</details>
92-
93-
<br/><br/>
94-
9556
## Content waitings
9657

9758
Take a look at the following examples to see how waiting for a DOM element could be implemented in
9859
the available tools.
9960

10061
### Code Examples
10162

102-
Cypress
103-
10463
- waiting for an element:
10564

10665
```javascript
66+
// Cypress code
67+
10768
// it waits up to 4 seconds by default
10869
cy.get('#form-feedback')
10970
// the timeout can be customized
@@ -113,99 +74,20 @@ cy.get('#form-feedback', { timeout: 5000 })
11374
- waiting for an element with specific content
11475

11576
```javascript
116-
cy.get('#form-feedback').contains('Success')
117-
```
118-
119-
<details><summary>Puppeteer (and Playwright)</summary>
120-
121-
- waiting for an element:
122-
123-
```javascript
124-
// it waits up to 30 seconds by default
125-
await page.waitForSelector('#form-feedback')
126-
// the timeout can be customized
127-
await page.waitForSelector('#form-feedback', { timeout: 5000 })
128-
```
129-
130-
- waiting for an element with specific content
131-
132-
```javascript
133-
await page.waitForFunction(
134-
(selector) => {
135-
const el = document.querySelector(selector)
136-
return el && el.innerText === 'Success'
137-
},
138-
{},
139-
'#form-feedback'
140-
)
141-
```
142-
143-
</details>
144-
145-
<details><summary>Selenium</summary>
146-
147-
- waiting for an element:
148-
149-
```javascript
150-
driver.wait(until.elementLocated(By.id('#form-feedback')), 4000)
151-
```
152-
153-
- waiting for an element with specific content
154-
155-
```javascript
156-
const el = driver.wait(until.elementLocated(By.id('#form-feedback')), 4000)
157-
wait.until(ExpectedConditions.textToBePresentInElement(el, 'Success'))
158-
```
159-
160-
</details>
161-
162-
<details><summary>TestCafé</summary>
163-
164-
- waiting for an element:
165-
166-
```javascript
167-
// it waits up to 10 seconds by default
168-
await Selector('#form-feedback')
169-
// the timeout can be customized
170-
await Selector('#form-feedback').with({ timeout: 4000 })
171-
```
172-
173-
- waiting for an element with specific content
174-
175-
```javascript
176-
await Selector('#form-feedback').withText('Success')
177-
```
178-
179-
</details>
77+
// Cypress code
18078

181-
<details><summary>DOM Testing Library<sup> <a href="#footnote1">1</a></sup></summary>
182-
183-
- waiting for an element:
184-
185-
```javascript
186-
await findByTestId(document.body, 'form-feedback')
187-
```
188-
189-
- waiting for an element with specific content
190-
191-
```javascript
192-
const container = await findByTestId(document.body, 'form-feedback')
193-
await findByText(container, 'Success')
79+
cy.get('#form-feedback').contains('Success')
19480
```
19581

196-
</details>
197-
198-
<br/><br/>
199-
20082
## XHR request waitings
20183

20284
### Code Examples
20385

204-
Cypress
205-
20686
- waiting for an XHR request/response
20787

20888
```javascript
89+
// Cypress code
90+
20991
cy.intercept('http://dummy.restapiexample.com/api/v1/employees').as('employees')
21092
cy.wait('@employees')
21193
.its('response.body')
@@ -214,99 +96,6 @@ cy.wait('@employees')
21496
})
21597
```
21698

217-
<details><summary>Puppeteer (and Playwright)</summary>
218-
219-
- waiting for an XHR request
220-
221-
```javascript
222-
await page.waitForRequest('http://dummy.restapiexample.com/api/v1/employees')
223-
```
224-
225-
- waiting for an XHR response
226-
227-
```javascript
228-
const response = await page.waitForResponse('http://dummy.restapiexample.com/api/v1/employees')
229-
const body = response.json()
230-
```
231-
232-
</details>
233-
234-
<br />
235-
Even if it's a really important point, at the time of writing (May, 2019) it seems that waiting for XHR requests and responses is not so
236-
common. With exceptions for Cypress and Puppeteer, other tools/frameworks force you to look for
237-
something in the DOM that reflects the XHR result instead of looking for the XHR request itself. You can read more about th topic:
238-
239-
- Selenium WebDriver: [5 Ways to Test AJAX Calls in Selenium WebDriver](https://www.blazemeter.com/blog/five-ways-to-test-ajax-calls-with-selenium-webdriver)
240-
- TestCafé: [Wait Mechanism for XHR and Fetch Requests](https://devexpress.github.io/testcafe/documentation/test-api/built-in-waiting-mechanisms.html#wait-mechanism-for-xhr-and-fetch-requests)
241-
- DOM Testing Library: [await API](https://testing-library.com/docs/dom-testing-library/api-async#wait)
242-
243-
<br /><br />
244-
245-
## Custom waitings
246-
247-
The various UI testing tools/frameworks have built-in solutions to perform a lot of checks, but let's
248-
concentrate on writing a custom waiting. Since UI testing is 100% asynchronous, a custom waiting
249-
should face recursive promises, a concept not so handy to manage at the beginning.
250-
251-
Luckily, there are some handy solutions and plugins to help us with that. Consider if we want to
252-
wait until a global variable (`foo`) is assigned with a particular value (`bar`): below you are going to
253-
find some examples.
254-
255-
### Code Examples
256-
257-
Cypress
258-
259-
Thanks to the [cypress-wait-until plugin](https://github.com/NoriSte/cypress-wait-until) you can do:
260-
261-
```javascript
262-
cy.waitUntil(() => cy.window().then((win) => win.foo === 'bar'))
263-
```
264-
265-
<details><summary>Puppeteer (and Playwright)</summary>
266-
267-
```javascript
268-
await page.waitForFunction('window.foo === "bar"')
269-
```
270-
271-
</details>
272-
273-
<details><summary>Selenium</summary>
274-
275-
```javascript
276-
browser.executeAsyncScript(`
277-
window.setTimeout(function(){
278-
if(window.foo === "bar") {
279-
arguments[arguments.length - 1]();
280-
}
281-
}, 300);
282-
`)
283-
```
284-
285-
</details>
286-
287-
<details><summary>TestCafé</summary>
288-
289-
```javascript
290-
const waiting = ClientFunction(() => window.foo === 'bar')
291-
await t.expect(waiting()).ok({ timeout: 5000 })
292-
```
293-
294-
</details>
295-
296-
<details><summary>DOM Testing Library<sup> <a href="#footnote1">1</a></sup></summary>
297-
298-
```javascript
299-
await wait(() => global.foo === 'bar')
300-
```
301-
302-
</details>
303-
304-
<br />
305-
<a id="footnote1">1</a>: unlike Cypress, Puppeteer, etc. DOM Testing Library is quite a different tool, that's why the examples are not available for every single part.
306-
307-
[//]: <> (useful https://www.freecodecamp.org/news/how-to-write-reliable-browser-tests-using-selenium-and-node-js-c3fdafdca2a9/)
308-
[//]: <> (useful https://testcafe-discuss.devexpress.com/t/how-do-i-make-a-selector-wait-for-element-to-exist/569/2)
309-
31099
<br /><br />
311100

312101
_Crossposted by [NoriSte](https://github.com/NoriSte) on [dev.to](https://dev.to/noriste/await-do-not-make-your-e2e-tests-sleep-4g1o) and [Medium](https://medium.com/@NoriSte/react-hooks-memorandum-bf1c2758a672)._

0 commit comments

Comments
 (0)