0
# Waiting & Synchronization
1
2
Powerful waiting mechanisms with built-in asserters for handling dynamic content and asynchronous operations in web applications.
3
4
## Capabilities
5
6
### General Waiting
7
8
Wait for custom conditions using asserter functions.
9
10
```javascript { .api }
11
/**
12
* Wait for a condition to be satisfied using an asserter
13
* @param asserter - Asserter function or object
14
* @param timeout - Maximum wait time in milliseconds (default: 1000)
15
* @param pollFreq - Polling frequency in milliseconds (default: 200)
16
* @param cb - Callback receiving (err, value)
17
*/
18
waitFor(asserter: Asserter, timeout?: number, pollFreq?: number, cb?: callback): any;
19
20
/**
21
* Base asserter class for creating custom wait conditions
22
*/
23
class Asserter {
24
constructor(assertFunction: (target: any, callback: function) => void);
25
}
26
```
27
28
**Usage Examples:**
29
30
```javascript
31
const wd = require('wd');
32
33
// Wait for element to have non-empty text
34
browser.elementById('status-message', function(err, element) {
35
browser.waitFor(wd.asserters.nonEmptyText, 5000, function(err, value) {
36
console.log('Element now has text:', value);
37
});
38
});
39
40
// Custom asserter
41
const customAsserter = new wd.Asserter(function(target, callback) {
42
target.text(function(err, text) {
43
if (err) return callback(err);
44
const satisfied = text.includes('Success');
45
callback(null, satisfied, text);
46
});
47
});
48
49
browser.elementById('result', function(err, element) {
50
browser.waitFor(customAsserter, 10000, function(err, text) {
51
console.log('Success message appeared:', text);
52
});
53
});
54
```
55
56
### Element Waiting
57
58
Wait for elements to exist, be visible, or meet other conditions.
59
60
```javascript { .api }
61
/**
62
* Wait for element to exist in DOM
63
* @param using - Selector strategy
64
* @param value - Selector value
65
* @param timeout - Maximum wait time in milliseconds
66
* @param cb - Callback receiving (err, element)
67
*/
68
waitForElement(using: string, value: string, timeout?: number, cb?: callback): Element;
69
70
/**
71
* Wait for multiple elements to exist
72
* @param using - Selector strategy
73
* @param value - Selector value
74
* @param timeout - Maximum wait time in milliseconds
75
* @param cb - Callback receiving (err, elements)
76
*/
77
waitForElements(using: string, value: string, timeout?: number, cb?: callback): Element[];
78
79
/**
80
* Wait for element to be visible
81
* @param using - Selector strategy
82
* @param value - Selector value
83
* @param timeout - Maximum wait time in milliseconds
84
* @param pollFreq - Polling frequency in milliseconds
85
* @param cb - Callback receiving (err, element)
86
*/
87
waitForVisible(using: string, value: string, timeout?: number, pollFreq?: number, cb?: callback): Element;
88
89
/**
90
* Wait for element by ID
91
* @param id - Element ID
92
* @param timeout - Maximum wait time in milliseconds
93
* @param cb - Callback receiving (err, element)
94
*/
95
waitForElementById(id: string, timeout?: number, cb?: callback): Element;
96
97
/**
98
* Wait for element by CSS selector
99
* @param selector - CSS selector
100
* @param timeout - Maximum wait time in milliseconds
101
* @param cb - Callback receiving (err, element)
102
*/
103
waitForElementByCss(selector: string, timeout?: number, cb?: callback): Element;
104
```
105
106
**Usage Examples:**
107
108
```javascript
109
// Wait for dynamically loaded element
110
browser.waitForElementById('dynamic-content', 10000, function(err, element) {
111
if (err) {
112
console.log('Element did not appear within 10 seconds');
113
return;
114
}
115
console.log('Dynamic content loaded');
116
element.text(function(err, text) {
117
console.log('Content:', text);
118
});
119
});
120
121
// Wait for AJAX-loaded elements
122
browser.waitForElementsByCss('.search-result', 15000, function(err, results) {
123
console.log('Found', results.length, 'search results');
124
});
125
126
// Wait for element to be visible (not just present in DOM)
127
browser.waitForVisible('css selector', '.modal-dialog', 5000, function(err, modal) {
128
console.log('Modal dialog is now visible');
129
});
130
131
// Promise chain waiting
132
browser
133
.elementById('search-button')
134
.click()
135
.waitForElementsByCss('.search-result', 10000)
136
.then(results => {
137
console.log('Search completed with', results.length, 'results');
138
});
139
```
140
141
### JavaScript Condition Waiting
142
143
Wait for JavaScript expressions to evaluate to true.
144
145
```javascript { .api }
146
/**
147
* Wait for JavaScript condition to be true
148
* @param jsCondition - JavaScript expression as string
149
* @param timeout - Maximum wait time in milliseconds
150
* @param pollFreq - Polling frequency in milliseconds
151
* @param cb - Callback receiving (err, value)
152
*/
153
waitForJsCondition(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;
154
155
/**
156
* Alias for waitForJsCondition
157
*/
158
waitForCondition(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;
159
160
/**
161
* Wait for JavaScript condition evaluated in browser context
162
* @param jsCondition - JavaScript expression as string
163
* @param timeout - Maximum wait time in milliseconds
164
* @param pollFreq - Polling frequency in milliseconds
165
* @param cb - Callback receiving (err, value)
166
*/
167
waitForConditionInBrowser(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;
168
```
169
170
**Usage Examples:**
171
172
```javascript
173
// Wait for AJAX request to complete
174
browser.waitForJsCondition('window.ajaxInProgress === false', 10000, function(err) {
175
console.log('AJAX requests completed');
176
});
177
178
// Wait for JavaScript library to load
179
browser.waitForCondition('typeof jQuery !== "undefined"', 5000, function(err) {
180
console.log('jQuery library loaded');
181
});
182
183
// Wait for custom application state
184
browser.waitForConditionInBrowser('window.app && window.app.isReady', 15000, function(err) {
185
console.log('Application is ready');
186
});
187
188
// Wait for element count condition
189
browser.waitForJsCondition(
190
'document.querySelectorAll(".item").length >= 5',
191
8000,
192
function(err) {
193
console.log('At least 5 items are now present');
194
}
195
);
196
197
// Promise chain JS condition waiting
198
browser
199
.elementById('load-more')
200
.click()
201
.waitForCondition('document.querySelector(".loading") === null', 10000)
202
.then(() => {
203
console.log('Loading spinner disappeared');
204
});
205
```
206
207
### Built-in Asserters
208
209
Pre-built asserter functions for common waiting scenarios.
210
211
```javascript { .api }
212
const asserters: {
213
/**
214
* Assert element has non-empty text content
215
*/
216
nonEmptyText: Asserter;
217
218
/**
219
* Assert element text includes specific content
220
* @param content - Text content to look for
221
*/
222
textInclude(content: string): Asserter;
223
224
/**
225
* Assert element is displayed (visible)
226
*/
227
isDisplayed: Asserter;
228
229
/**
230
* Assert element is not displayed (hidden)
231
*/
232
isNotDisplayed: Asserter;
233
234
/**
235
* Assert JavaScript condition evaluates to true
236
* @param jsExpr - JavaScript expression
237
* @param safe - Use safe execution (default: true)
238
*/
239
jsCondition(jsExpr: string, safe?: boolean): Asserter;
240
241
// Deprecated asserters (use alternatives above)
242
isVisible: Asserter; // Use isDisplayed
243
isHidden: Asserter; // Use isNotDisplayed
244
};
245
```
246
247
**Usage Examples:**
248
249
```javascript
250
const wd = require('wd');
251
252
// Wait for element to have text
253
browser.elementById('message', function(err, element) {
254
browser.waitFor(wd.asserters.nonEmptyText, 5000, function(err, text) {
255
console.log('Message appeared:', text);
256
});
257
});
258
259
// Wait for specific text content
260
browser.elementById('status', function(err, element) {
261
const successAsserter = wd.asserters.textInclude('Success');
262
browser.waitFor(successAsserter, 10000, function(err, text) {
263
console.log('Success status confirmed:', text);
264
});
265
});
266
267
// Wait for element to become visible
268
browser.elementByCss('.hidden-initially', function(err, element) {
269
browser.waitFor(wd.asserters.isDisplayed, 3000, function(err) {
270
console.log('Element is now visible');
271
});
272
});
273
274
// Wait for element to be hidden
275
browser.elementById('loading-spinner', function(err, element) {
276
browser.waitFor(wd.asserters.isNotDisplayed, 15000, function(err) {
277
console.log('Loading spinner is now hidden');
278
});
279
});
280
281
// Wait for JavaScript condition
282
const jsAsserter = wd.asserters.jsCondition('window.dataLoaded === true');
283
browser.waitFor(jsAsserter, 8000, function(err) {
284
console.log('Data loading completed');
285
});
286
```
287
288
### Advanced Waiting Patterns
289
290
Complex waiting scenarios combining multiple conditions.
291
292
**Usage Examples:**
293
294
```javascript
295
// Wait for multiple conditions in sequence
296
browser
297
.elementById('submit-form')
298
.click()
299
.waitFor(wd.asserters.jsCondition('document.querySelector(".loading")'), 1000) // Loading appears
300
.waitFor(wd.asserters.jsCondition('!document.querySelector(".loading")'), 10000) // Loading disappears
301
.waitForElementById('success-message', 5000)
302
.text()
303
.then(message => console.log('Form submitted:', message));
304
305
// Custom asserter for complex conditions
306
const complexAsserter = new wd.Asserter(function(browser, callback) {
307
browser.elementsByCss('.item', function(err, items) {
308
if (err) return callback(err);
309
310
if (items.length < 3) {
311
return callback(null, false); // Not satisfied yet
312
}
313
314
// Check if all items are visible
315
let visibleCount = 0;
316
let completed = 0;
317
318
items.forEach((item, index) => {
319
item.isDisplayed(function(err, visible) {
320
if (visible) visibleCount++;
321
completed++;
322
323
if (completed === items.length) {
324
const satisfied = visibleCount >= 3;
325
callback(null, satisfied, visibleCount);
326
}
327
});
328
});
329
});
330
});
331
332
browser.waitFor(complexAsserter, 10000, function(err, visibleCount) {
333
console.log('At least 3 items are visible:', visibleCount);
334
});
335
336
// Timeout handling
337
browser.waitForElementById('slow-element', 5000, function(err, element) {
338
if (err && err.message.includes('timeout')) {
339
console.log('Element did not appear within timeout, continuing with fallback');
340
// Implement fallback behavior
341
} else if (err) {
342
throw err;
343
} else {
344
console.log('Element found:', element);
345
}
346
});
347
```
348
349
### Simple Sleep
350
351
Basic sleep functionality for fixed delays.
352
353
```javascript { .api }
354
/**
355
* Sleep for specified duration
356
* @param ms - Duration in milliseconds
357
* @param cb - Callback receiving (err)
358
*/
359
sleep(ms: number, cb?: callback): void;
360
```
361
362
**Usage Examples:**
363
364
```javascript
365
// Simple delay
366
browser.sleep(2000, function() {
367
console.log('Waited 2 seconds');
368
});
369
370
// Promise chain with sleep
371
browser
372
.elementById('animate-button')
373
.click()
374
.sleep(1000) // Wait for animation
375
.elementByCss('.animated-element')
376
.isDisplayed()
377
.then(visible => console.log('Animation completed:', visible));
378
```