@progress/kendo-e2e 4.11.3 → 4.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -111
- package/dist/selenium/browser.d.ts +245 -4
- package/dist/selenium/browser.js +245 -4
- package/dist/selenium/browser.js.map +1 -1
- package/dist/selenium/conditions.d.ts +255 -0
- package/dist/selenium/conditions.js +251 -0
- package/dist/selenium/conditions.js.map +1 -1
- package/dist/selenium/driver-manager.d.ts +123 -0
- package/dist/selenium/driver-manager.js +118 -0
- package/dist/selenium/driver-manager.js.map +1 -1
- package/dist/selenium/electron-app.d.ts +32 -2
- package/dist/selenium/electron-app.js +32 -2
- package/dist/selenium/electron-app.js.map +1 -1
- package/dist/selenium/expect.d.ts +227 -0
- package/dist/selenium/expect.js +22 -0
- package/dist/selenium/expect.js.map +1 -1
- package/dist/selenium/web-app.d.ts +779 -9
- package/dist/selenium/web-app.js +778 -9
- package/dist/selenium/web-app.js.map +1 -1
- package/docs/API_REFERENCE.md +1309 -0
- package/docs/GETTING_STARTED.md +337 -0
- package/docs/PATTERNS.md +629 -0
- package/package.json +4 -5
package/dist/selenium/browser.js
CHANGED
|
@@ -28,10 +28,46 @@ function isDriver(obj) {
|
|
|
28
28
|
return obj && typeof obj.getSession === 'function';
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* and
|
|
31
|
+
* Browser automation class with automatic waiting and modern web testing features.
|
|
32
|
+
*
|
|
33
|
+
* Extends {@link WebApp} with browser-specific capabilities like navigation, window management,
|
|
34
|
+
* accessibility testing, and console log monitoring. Perfect for testing web applications in
|
|
35
|
+
* real browsers (Chrome, Firefox, Safari, Edge).
|
|
36
|
+
*
|
|
37
|
+
* **Key features:**
|
|
38
|
+
* - Browser navigation and URL management
|
|
39
|
+
* - Window resizing and iframe handling
|
|
40
|
+
* - Mobile device emulation
|
|
41
|
+
* - Accessibility (a11y) testing with axe-core
|
|
42
|
+
* - Console error detection
|
|
43
|
+
* - BiDi protocol support
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* // Basic browser test
|
|
48
|
+
* const browser = new Browser();
|
|
49
|
+
* await browser.navigateTo('https://example.com');
|
|
50
|
+
* await browser.click('#login-button');
|
|
51
|
+
* await browser.expect('.welcome-message').toBeVisible();
|
|
52
|
+
* await browser.close();
|
|
53
|
+
*
|
|
54
|
+
* // Mobile emulation
|
|
55
|
+
* const mobile = new Browser({ mobileEmulation: { deviceName: 'iPhone 14 Pro Max' } });
|
|
56
|
+
* await mobile.navigateTo('https://example.com');
|
|
57
|
+
*
|
|
58
|
+
* // With BiDi for advanced features
|
|
59
|
+
* const browser = new Browser({ enableBidi: true });
|
|
60
|
+
*
|
|
61
|
+
* // Check for console errors
|
|
62
|
+
* await browser.clearLogs();
|
|
63
|
+
* await browser.click('#trigger-error');
|
|
64
|
+
* const errors = await browser.getErrorLogs();
|
|
65
|
+
* expect(errors).toHaveLength(0);
|
|
66
|
+
*
|
|
67
|
+
* // Accessibility testing
|
|
68
|
+
* const violations = await browser.getAccessibilityViolations();
|
|
69
|
+
* expect(violations).toHaveLength(0);
|
|
70
|
+
* ```
|
|
35
71
|
*/
|
|
36
72
|
class Browser extends web_app_1.WebApp {
|
|
37
73
|
/**
|
|
@@ -99,11 +135,51 @@ class Browser extends web_app_1.WebApp {
|
|
|
99
135
|
}
|
|
100
136
|
super(driver);
|
|
101
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Closes the browser and ends the WebDriver session.
|
|
140
|
+
*
|
|
141
|
+
* Should be called at the end of each test to clean up resources.
|
|
142
|
+
* Closes all browser windows and terminates the driver.
|
|
143
|
+
*
|
|
144
|
+
* @returns Promise that resolves when browser is closed
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const browser = new Browser();
|
|
149
|
+
* try {
|
|
150
|
+
* await browser.navigateTo('https://example.com');
|
|
151
|
+
* // ... test code ...
|
|
152
|
+
* } finally {
|
|
153
|
+
* await browser.close(); // Always close to free resources
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
102
157
|
close() {
|
|
103
158
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
159
|
yield this.driver.quit();
|
|
105
160
|
});
|
|
106
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Navigates the browser to a specified URL.
|
|
164
|
+
*
|
|
165
|
+
* Opens the URL in the current browser window. Waits for the page to load before
|
|
166
|
+
* the promise resolves.
|
|
167
|
+
*
|
|
168
|
+
* @param url - The URL to navigate to (must include protocol: http:// or https://)
|
|
169
|
+
* @returns Promise that resolves when navigation completes
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* // Navigate to a website
|
|
174
|
+
* await browser.navigateTo('https://example.com');
|
|
175
|
+
*
|
|
176
|
+
* // Navigate to local development server
|
|
177
|
+
* await browser.navigateTo('http://localhost:3000');
|
|
178
|
+
*
|
|
179
|
+
* // Navigate to specific page
|
|
180
|
+
* await browser.navigateTo('https://example.com/products/123');
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
107
183
|
navigateTo(url) {
|
|
108
184
|
return __awaiter(this, void 0, void 0, function* () {
|
|
109
185
|
yield this.driver.navigate().to(url);
|
|
@@ -160,22 +236,115 @@ class Browser extends web_app_1.WebApp {
|
|
|
160
236
|
}
|
|
161
237
|
});
|
|
162
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Refreshes the current page (like pressing F5 or clicking browser refresh).
|
|
241
|
+
*
|
|
242
|
+
* Reloads the page from the server, resetting all JavaScript state.
|
|
243
|
+
*
|
|
244
|
+
* @returns Promise that resolves when page reload completes
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* // Refresh after making changes
|
|
249
|
+
* await browser.click('#update-settings');
|
|
250
|
+
* await browser.refresh();
|
|
251
|
+
*
|
|
252
|
+
* // Verify data persists after refresh
|
|
253
|
+
* await browser.type('#input', 'test');
|
|
254
|
+
* await browser.click('#save');
|
|
255
|
+
* await browser.refresh();
|
|
256
|
+
* const value = await browser.getAttribute('#input', 'value');
|
|
257
|
+
* expect(value).toBe('test');
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
163
260
|
refresh() {
|
|
164
261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
165
262
|
yield this.driver.navigate().refresh();
|
|
166
263
|
});
|
|
167
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Switches the WebDriver context to an iframe.
|
|
267
|
+
*
|
|
268
|
+
* After calling this, all subsequent commands will target elements within the iframe.
|
|
269
|
+
* To switch back to the main page, use `driver.switchTo().defaultContent()`.
|
|
270
|
+
*
|
|
271
|
+
* @param elementLocator - By locator for the iframe element
|
|
272
|
+
* @returns Promise that resolves when context is switched
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* // Switch to iframe and interact with its content
|
|
277
|
+
* await browser.switchToIFrame(By.css('#my-iframe'));
|
|
278
|
+
* await browser.click('#button-inside-iframe');
|
|
279
|
+
*
|
|
280
|
+
* // Switch back to main page
|
|
281
|
+
* await browser.driver.switchTo().defaultContent();
|
|
282
|
+
* await browser.click('#button-on-main-page');
|
|
283
|
+
*
|
|
284
|
+
* // Work with nested iframes
|
|
285
|
+
* await browser.switchToIFrame(By.css('#outer-frame'));
|
|
286
|
+
* await browser.switchToIFrame(By.css('#inner-frame'));
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
168
289
|
switchToIFrame(elementLocator) {
|
|
169
290
|
return __awaiter(this, void 0, void 0, function* () {
|
|
170
291
|
const iframe = yield this.find(elementLocator);
|
|
171
292
|
yield this.driver.switchTo().frame(iframe);
|
|
172
293
|
});
|
|
173
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Gets the current URL of the browser.
|
|
297
|
+
*
|
|
298
|
+
* Returns the complete URL including protocol, domain, path, and query parameters.
|
|
299
|
+
*
|
|
300
|
+
* @returns Promise resolving to the current URL string
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* // Verify navigation occurred
|
|
305
|
+
* await browser.click('#products-link');
|
|
306
|
+
* const url = await browser.getCurrentUrl();
|
|
307
|
+
* expect(url).toContain('/products');
|
|
308
|
+
*
|
|
309
|
+
* // Check URL parameters
|
|
310
|
+
* const currentUrl = await browser.getCurrentUrl();
|
|
311
|
+
* expect(currentUrl).toContain('?filter=active');
|
|
312
|
+
*
|
|
313
|
+
* // Verify redirect
|
|
314
|
+
* await browser.navigateTo('http://example.com/old-page');
|
|
315
|
+
* const redirectedUrl = await browser.getCurrentUrl();
|
|
316
|
+
* expect(redirectedUrl).toBe('http://example.com/new-page');
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
174
319
|
getCurrentUrl() {
|
|
175
320
|
return __awaiter(this, void 0, void 0, function* () {
|
|
176
321
|
return yield this.driver.getCurrentUrl();
|
|
177
322
|
});
|
|
178
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Gets the name of the current browser.
|
|
326
|
+
*
|
|
327
|
+
* Returns lowercase browser name: 'chrome', 'firefox', 'safari', 'edge', etc.
|
|
328
|
+
* Useful for browser-specific test logic.
|
|
329
|
+
*
|
|
330
|
+
* @returns Promise resolving to lowercase browser name
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* const browserName = await browser.getBrowserName();
|
|
335
|
+
*
|
|
336
|
+
* if (browserName === 'safari') {
|
|
337
|
+
* // Skip Safari-incompatible test
|
|
338
|
+
* console.log('Skipping on Safari');
|
|
339
|
+
* return;
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* // Browser-specific assertions
|
|
343
|
+
* if (browserName === 'firefox') {
|
|
344
|
+
* // Firefox-specific validation
|
|
345
|
+
* }
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
179
348
|
getBrowserName() {
|
|
180
349
|
return __awaiter(this, void 0, void 0, function* () {
|
|
181
350
|
const capabilities = (yield (yield this.driver).getCapabilities());
|
|
@@ -183,6 +352,35 @@ class Browser extends web_app_1.WebApp {
|
|
|
183
352
|
return browserName;
|
|
184
353
|
});
|
|
185
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Runs accessibility (a11y) tests using axe-core and returns violations.
|
|
357
|
+
*
|
|
358
|
+
* Scans the page for accessibility issues like missing alt text, insufficient color contrast,
|
|
359
|
+
* missing ARIA labels, etc. Returns an array of violations that should be addressed.
|
|
360
|
+
*
|
|
361
|
+
* @param cssSelector - CSS selector to limit scanning scope (default: 'html' for full page)
|
|
362
|
+
* @param disableRules - Array of axe rule IDs to disable (default: ['color-contrast'])
|
|
363
|
+
* @returns Promise resolving to array of accessibility violations
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* // Scan entire page
|
|
368
|
+
* const violations = await browser.getAccessibilityViolations();
|
|
369
|
+
* expect(violations).toHaveLength(0);
|
|
370
|
+
*
|
|
371
|
+
* // Scan specific component
|
|
372
|
+
* const formViolations = await browser.getAccessibilityViolations('#login-form');
|
|
373
|
+
*
|
|
374
|
+
* // Enable all rules including color contrast
|
|
375
|
+
* const allViolations = await browser.getAccessibilityViolations('html', []);
|
|
376
|
+
*
|
|
377
|
+
* // Disable specific rules
|
|
378
|
+
* const violations = await browser.getAccessibilityViolations('html', [
|
|
379
|
+
* 'color-contrast',
|
|
380
|
+
* 'landmark-one-main'
|
|
381
|
+
* ]);
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
186
384
|
getAccessibilityViolations() {
|
|
187
385
|
return __awaiter(this, arguments, void 0, function* (cssSelector = "html", disableRules = ["color-contrast"]) {
|
|
188
386
|
yield this.find(selenium_webdriver_1.By.css(cssSelector));
|
|
@@ -193,11 +391,54 @@ class Browser extends web_app_1.WebApp {
|
|
|
193
391
|
return result.violations;
|
|
194
392
|
});
|
|
195
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Clears the browser console logs.
|
|
396
|
+
*
|
|
397
|
+
* Call this before performing actions to get a clean slate for error detection.
|
|
398
|
+
* Useful when you want to check if a specific action causes console errors.
|
|
399
|
+
*
|
|
400
|
+
* @returns Promise that resolves when logs are cleared
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* // Clear logs before action
|
|
405
|
+
* await browser.clearLogs();
|
|
406
|
+
* await browser.click('#potential-error-button');
|
|
407
|
+
* const errors = await browser.getErrorLogs();
|
|
408
|
+
* ```
|
|
409
|
+
*/
|
|
196
410
|
clearLogs() {
|
|
197
411
|
return __awaiter(this, void 0, void 0, function* () {
|
|
198
412
|
yield this.driver.manage().logs().get(logging_1.Type.BROWSER);
|
|
199
413
|
});
|
|
200
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Gets console errors from the browser (Chrome only).
|
|
417
|
+
*
|
|
418
|
+
* Retrieves console errors logged by the browser. Only works in Chrome on desktop platforms.
|
|
419
|
+
* Firefox and mobile platforms don't support log retrieval.
|
|
420
|
+
*
|
|
421
|
+
* @param excludeList - Array of strings to filter out from errors (default: ['favicon.ico'])
|
|
422
|
+
* @param logLevel - Minimum log level to collect (default: Level.SEVERE for errors)
|
|
423
|
+
* @returns Promise resolving to array of error message strings
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```typescript
|
|
427
|
+
* // Check for any console errors
|
|
428
|
+
* const errors = await browser.getErrorLogs();
|
|
429
|
+
* expect(errors.length).toBe(0);
|
|
430
|
+
*
|
|
431
|
+
* // Exclude known non-critical errors
|
|
432
|
+
* const errors = await browser.getErrorLogs(['favicon', 'analytics']);
|
|
433
|
+
*
|
|
434
|
+
* // Get all warnings and errors
|
|
435
|
+
* const logs = await browser.getErrorLogs([], Level.WARNING);
|
|
436
|
+
*
|
|
437
|
+
* // Check for specific error
|
|
438
|
+
* const errors = await browser.getErrorLogs();
|
|
439
|
+
* expect(errors.some(e => e.includes('TypeError'))).toBe(false);
|
|
440
|
+
* ```
|
|
441
|
+
*/
|
|
201
442
|
getErrorLogs() {
|
|
202
443
|
return __awaiter(this, arguments, void 0, function* (excludeList = ["favicon.ico"], logLevel = logging_1.Level.SEVERE) {
|
|
203
444
|
const errors = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/selenium/browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,wEAA+C;AAC/C,2DAAuE;AACvE,4DAA6D;AAC7D,qDAAiD;AACjD,uCAAmC;AAEnC,yDAAwG;AAA/F,wGAAA,EAAE,OAAA;AAAE,yGAAA,GAAG,OAAA;AAAqB,2GAAA,KAAK,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,yHAAA,mBAAmB,OAAA;AAQ3E,SAAS,QAAQ,CAAC,GAAQ;IACtB,OAAO,GAAG,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC;AACvD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/selenium/browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,270 @@
|
|
|
1
1
|
import { By, WebDriver, WebElement } from "selenium-webdriver";
|
|
2
|
+
/**
|
|
3
|
+
* A function that checks a condition and returns whether it's met.
|
|
4
|
+
* Used with WebApp.wait() and WebApp.waitSafely() methods.
|
|
5
|
+
*/
|
|
2
6
|
export type WaitCondition = (driver: WebDriver) => Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Expected Conditions (EC) - factory methods for creating wait conditions.
|
|
9
|
+
*
|
|
10
|
+
* Provides a collection of commonly used wait conditions for element states.
|
|
11
|
+
* These conditions are designed to work with {@link WebApp.wait} and {@link WebApp.waitSafely}.
|
|
12
|
+
*
|
|
13
|
+
* **All conditions automatically handle:**
|
|
14
|
+
* - Elements that don't exist yet
|
|
15
|
+
* - Stale element references
|
|
16
|
+
* - Timing issues
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Wait for element to be visible
|
|
21
|
+
* await app.wait(EC.isVisible('#modal'));
|
|
22
|
+
*
|
|
23
|
+
* // Wait for element to have specific text
|
|
24
|
+
* await app.wait(EC.hasText(element, 'Success'));
|
|
25
|
+
*
|
|
26
|
+
* // Wait for element to have focus
|
|
27
|
+
* await app.wait(EC.hasFocus(inputElement));
|
|
28
|
+
*
|
|
29
|
+
* // Check condition without throwing error
|
|
30
|
+
* const isVisible = await app.waitSafely(EC.isVisible('.optional-banner'));
|
|
31
|
+
* if (isVisible) {
|
|
32
|
+
* await app.click('.banner-close');
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
3
36
|
export declare class EC {
|
|
37
|
+
/**
|
|
38
|
+
* Creates a condition that waits for an element to have specific text.
|
|
39
|
+
*
|
|
40
|
+
* Compares the element's visible text content (via getText()) with the expected text.
|
|
41
|
+
* Match must be exact.
|
|
42
|
+
*
|
|
43
|
+
* @param element - WebElement to check text of
|
|
44
|
+
* @param text - Exact text to wait for
|
|
45
|
+
* @returns Condition function for use with wait()
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const message = await app.find('#message');
|
|
50
|
+
* await app.wait(EC.hasText(message, 'Operation completed'));
|
|
51
|
+
*
|
|
52
|
+
* // Or check without waiting
|
|
53
|
+
* const hasCorrectText = await app.hasText('#status', 'Active');
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
4
56
|
static hasText(element: WebElement, text: string): (driver: WebDriver) => Promise<boolean>;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a condition that waits for an input element to have a specific value.
|
|
59
|
+
*
|
|
60
|
+
* Checks the 'value' attribute of form inputs. Perfect for validating input fields
|
|
61
|
+
* after auto-fill, dynamic updates, or user interaction.
|
|
62
|
+
*
|
|
63
|
+
* @param element - Input WebElement to check
|
|
64
|
+
* @param value - Expected value
|
|
65
|
+
* @returns Condition function for use with wait()
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const input = await app.find('#username');
|
|
70
|
+
* await app.type(input, 'testuser');
|
|
71
|
+
* await app.wait(EC.hasValue(input, 'testuser'));
|
|
72
|
+
*
|
|
73
|
+
* // Wait for auto-filled value
|
|
74
|
+
* await app.wait(EC.hasValue(await app.find('#email'), 'user@example.com'));
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
5
77
|
static hasValue(element: WebElement, value: string): (driver: WebDriver) => Promise<boolean>;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a condition that waits for an element to have keyboard focus.
|
|
80
|
+
*
|
|
81
|
+
* Checks if the element is the currently active (focused) element in the document.
|
|
82
|
+
* Useful for testing keyboard navigation and focus management.
|
|
83
|
+
*
|
|
84
|
+
* @param element - WebElement to check for focus
|
|
85
|
+
* @returns Condition function for use with wait()
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const input = await app.find('#search');
|
|
90
|
+
* await app.click(input);
|
|
91
|
+
* await app.wait(EC.hasFocus(input));
|
|
92
|
+
*
|
|
93
|
+
* // Verify focus moved after Tab key
|
|
94
|
+
* await app.sendKey(Key.TAB);
|
|
95
|
+
* const nextInput = await app.find('#next-field');
|
|
96
|
+
* await app.wait(EC.hasFocus(nextInput));
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
6
99
|
static hasFocus(element: WebElement): (driver: WebDriver) => Promise<boolean>;
|
|
100
|
+
/**
|
|
101
|
+
* Creates a condition that waits for an element to lose keyboard focus.
|
|
102
|
+
*
|
|
103
|
+
* Opposite of {@link hasFocus}. Useful for testing blur events and focus movement.
|
|
104
|
+
*
|
|
105
|
+
* @param element - WebElement to check for lack of focus
|
|
106
|
+
* @returns Condition function for use with wait()
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const input = await app.find('#field');
|
|
111
|
+
* await app.focus(input);
|
|
112
|
+
* await app.sendKey(Key.TAB); // Move focus away
|
|
113
|
+
* await app.wait(EC.hasNoFocus(input));
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
7
116
|
static hasNoFocus(element: WebElement): (driver: WebDriver) => Promise<boolean>;
|
|
117
|
+
/**
|
|
118
|
+
* Creates a condition that waits for an element to have at least one child matching a locator.
|
|
119
|
+
*
|
|
120
|
+
* Checks if the parent element contains any child elements matching the selector.
|
|
121
|
+
* Useful for waiting for dynamic content to load within a container.
|
|
122
|
+
*
|
|
123
|
+
* @param element - Parent WebElement to search within
|
|
124
|
+
* @param locator - Child element selector (By locator or CSS selector string)
|
|
125
|
+
* @returns Condition function for use with wait()
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const list = await app.find('ul#results');
|
|
130
|
+
* await app.wait(EC.hasChild(list, 'li'));
|
|
131
|
+
*
|
|
132
|
+
* // Wait for specific child
|
|
133
|
+
* const table = await app.find('#data-table');
|
|
134
|
+
* await app.wait(EC.hasChild(table, '.loaded-row'));
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
8
137
|
static hasChild(element: WebElement, locator: By | string): () => Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* Creates a condition that waits for an element to have a specific attribute value.
|
|
140
|
+
*
|
|
141
|
+
* Can check for exact match or partial match (contains). Useful for validating
|
|
142
|
+
* data attributes, ARIA attributes, disabled state, etc.
|
|
143
|
+
*
|
|
144
|
+
* @param element - WebElement to check
|
|
145
|
+
* @param attribute - Attribute name (e.g., 'disabled', 'data-id', 'aria-label')
|
|
146
|
+
* @param value - Expected value
|
|
147
|
+
* @param exactMatch - If true, value must match exactly; if false, attribute must contain value (default: true)
|
|
148
|
+
* @returns Condition function for use with wait()
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* const button = await app.find('#submit');
|
|
153
|
+
*
|
|
154
|
+
* // Wait for button to become disabled
|
|
155
|
+
* await app.wait(EC.hasAttribute(button, 'disabled', 'true'));
|
|
156
|
+
*
|
|
157
|
+
* // Wait for data attribute (partial match)
|
|
158
|
+
* await app.wait(EC.hasAttribute(button, 'data-state', 'loading', false));
|
|
159
|
+
*
|
|
160
|
+
* // Check ARIA label
|
|
161
|
+
* await app.wait(EC.hasAttribute(button, 'aria-label', 'Submit form'));
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
9
164
|
static hasAttribute(element: WebElement, attribute: string, value: string, exactMatch?: boolean): (driver: WebDriver) => Promise<boolean>;
|
|
165
|
+
/**
|
|
166
|
+
* Creates a condition that waits for an element to have a specific CSS class.
|
|
167
|
+
*
|
|
168
|
+
* Convenience method that checks the 'class' attribute. Can do exact or partial match.
|
|
169
|
+
* Perfect for waiting for state changes reflected in CSS classes.
|
|
170
|
+
*
|
|
171
|
+
* @param element - WebElement to check
|
|
172
|
+
* @param value - Class name to wait for
|
|
173
|
+
* @param exactMatch - If true, class attribute must match exactly; if false, must contain the class (default: false)
|
|
174
|
+
* @returns Condition function for use with wait()
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* const button = await app.find('#submit');
|
|
179
|
+
*
|
|
180
|
+
* // Wait for class to be added (partial match)
|
|
181
|
+
* await app.wait(EC.hasClass(button, 'active'));
|
|
182
|
+
*
|
|
183
|
+
* // Wait for exact class attribute
|
|
184
|
+
* await app.wait(EC.hasClass(button, 'btn btn-primary', true));
|
|
185
|
+
*
|
|
186
|
+
* // Wait for loading class
|
|
187
|
+
* await app.wait(EC.hasClass(await app.find('.spinner'), 'loading'));
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
10
190
|
static hasClass(element: WebElement, value: string, exactMatch?: boolean): (driver: WebDriver) => Promise<boolean>;
|
|
191
|
+
/**
|
|
192
|
+
* Creates a condition that waits for an element to be visible.
|
|
193
|
+
*
|
|
194
|
+
* Element must be present in DOM and have display style that makes it visible.
|
|
195
|
+
* Accepts WebElement, By locator, or CSS selector string.
|
|
196
|
+
*
|
|
197
|
+
* @param element - Element to check visibility of (WebElement, By locator, or CSS selector)
|
|
198
|
+
* @returns Condition function for use with wait()
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* // Wait for modal to appear
|
|
203
|
+
* await app.wait(EC.isVisible('#modal'));
|
|
204
|
+
*
|
|
205
|
+
* // Wait for element after click
|
|
206
|
+
* await app.click('#show-details');
|
|
207
|
+
* await app.wait(EC.isVisible('.details-panel'));
|
|
208
|
+
*
|
|
209
|
+
* // With By locator
|
|
210
|
+
* await app.wait(EC.isVisible(By.css('[data-test="banner"]')));
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
11
213
|
static isVisible(element: WebElement | By | string): (driver: WebDriver) => Promise<boolean>;
|
|
214
|
+
/**
|
|
215
|
+
* Creates a condition that waits for an element to become hidden or not present.
|
|
216
|
+
*
|
|
217
|
+
* Element is considered not visible if it's either not in DOM or has display:none or similar.
|
|
218
|
+
* Opposite of {@link isVisible}.
|
|
219
|
+
*
|
|
220
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
221
|
+
* @returns Condition function for use with wait()
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* // Wait for loading spinner to disappear
|
|
226
|
+
* await app.wait(EC.notVisible('.spinner'));
|
|
227
|
+
*
|
|
228
|
+
* // Wait for modal to close
|
|
229
|
+
* await app.click('.modal .close');
|
|
230
|
+
* await app.wait(EC.notVisible('.modal'));
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
12
233
|
static notVisible(element: WebElement | By | string): (driver: WebDriver) => Promise<boolean>;
|
|
234
|
+
/**
|
|
235
|
+
* Creates a condition that waits for an element to be in the visible viewport.
|
|
236
|
+
*
|
|
237
|
+
* Checks if the center point of the element is actually visible in the viewport and not
|
|
238
|
+
* covered by other elements. Stricter than {@link isVisible} - element must be scrolled into view.
|
|
239
|
+
*
|
|
240
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
241
|
+
* @returns Condition function for use with wait()
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* // Wait for element to scroll into view
|
|
246
|
+
* await app.wait(EC.isInViewport('.footer-content'));
|
|
247
|
+
*
|
|
248
|
+
* // Verify element is actually visible to user
|
|
249
|
+
* await app.scrollIntoView('#target');
|
|
250
|
+
* await app.wait(EC.isInViewport('#target'));
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
13
253
|
static isInViewport(element: WebElement | By | string): (driver: WebDriver) => Promise<boolean>;
|
|
254
|
+
/**
|
|
255
|
+
* Creates a condition that waits for an element to be outside the visible viewport.
|
|
256
|
+
*
|
|
257
|
+
* Checks if the element is scrolled out of view or covered. Opposite of {@link isInViewport}.
|
|
258
|
+
*
|
|
259
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
260
|
+
* @returns Condition function for use with wait()
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* // Wait for element to scroll out of view
|
|
265
|
+
* await app.scrollIntoView('#bottom-element');
|
|
266
|
+
* await app.wait(EC.notInViewport('#top-element'));
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
14
269
|
static notInViewport(element: WebElement | By | string): (driver: WebDriver) => Promise<boolean>;
|
|
15
270
|
}
|