@progress/kendo-e2e 4.11.3 → 4.12.0
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 +3 -2
|
@@ -2,71 +2,612 @@ import { By, ThenableWebDriver, WebElement, WebElementCondition } from "selenium
|
|
|
2
2
|
import { WaitCondition } from "./conditions";
|
|
3
3
|
import { ExpectApi } from "./expect";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Core class that provides automatic waiting and simplified interaction with web elements.
|
|
6
|
+
*
|
|
7
|
+
* **Key Features:**
|
|
8
|
+
* - **Automatic waiting** - No need to add manual waits, all methods wait for elements automatically
|
|
9
|
+
* - **Smart element location** - Accepts CSS selectors, By locators, or WebElement instances
|
|
10
|
+
* - **Fluent API** - Chain methods for readable test code
|
|
11
|
+
* - **Built-in retry logic** - Handles timing issues that cause flaky tests
|
|
12
|
+
*
|
|
13
|
+
* This eliminates the common Selenium pitfalls of StaleElementReferenceException and timing issues.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const app = new WebApp(driver);
|
|
18
|
+
*
|
|
19
|
+
* // Simple element interaction with automatic waiting
|
|
20
|
+
* await app.click('#submit-button');
|
|
21
|
+
* await app.type('#username', 'testuser');
|
|
22
|
+
*
|
|
23
|
+
* // Find and interact with elements
|
|
24
|
+
* const header = await app.find('.page-header');
|
|
25
|
+
* const text = await app.getText(header);
|
|
26
|
+
*
|
|
27
|
+
* // Wait for conditions
|
|
28
|
+
* await app.wait(EC.isVisible('#success-message'));
|
|
29
|
+
*
|
|
30
|
+
* // Modern expect API with retry logic
|
|
31
|
+
* await app.expect('#result').toHaveText('Success');
|
|
32
|
+
* await app.expect('.modal').toBeVisible();
|
|
33
|
+
* ```
|
|
6
34
|
*/
|
|
7
35
|
export declare class WebApp {
|
|
36
|
+
/** The underlying Selenium WebDriver instance */
|
|
8
37
|
driver: ThenableWebDriver;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a WebApp instance wrapping a Selenium WebDriver.
|
|
40
|
+
*
|
|
41
|
+
* @param driver - Selenium WebDriver instance to wrap
|
|
42
|
+
*/
|
|
9
43
|
constructor(driver: ThenableWebDriver);
|
|
44
|
+
/**
|
|
45
|
+
* Finds a single element with automatic waiting.
|
|
46
|
+
*
|
|
47
|
+
* **Automatically waits** up to the specified timeout for the element to appear in the DOM.
|
|
48
|
+
* This eliminates the need for manual waits and handles dynamic content loading.
|
|
49
|
+
*
|
|
50
|
+
* @param locator - CSS selector string or Selenium By locator
|
|
51
|
+
* @param options - Optional configuration
|
|
52
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
53
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
54
|
+
* @returns Promise resolving to the WebElement
|
|
55
|
+
* @throws Error if element is not found within the timeout period
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Using CSS selector (recommended)
|
|
60
|
+
* const button = await app.find('#submit-btn');
|
|
61
|
+
* const firstItem = await app.find('.list-item');
|
|
62
|
+
*
|
|
63
|
+
* // Using Selenium By locator
|
|
64
|
+
* const element = await app.find(By.xpath('//div[@data-test="value"]'));
|
|
65
|
+
*
|
|
66
|
+
* // With custom timeout
|
|
67
|
+
* const slowElement = await app.find('#async-content', { timeout: 20000 });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
10
70
|
find(locator: By | string, { timeout, pollTimeout }?: {
|
|
11
71
|
timeout?: number;
|
|
12
72
|
pollTimeout?: number;
|
|
13
73
|
}): Promise<WebElement>;
|
|
74
|
+
/**
|
|
75
|
+
* Finds all matching elements without waiting.
|
|
76
|
+
*
|
|
77
|
+
* Returns an empty array if no elements are found. For scenarios where you need to wait
|
|
78
|
+
* for at least one element, use {@link findAllWithTimeout} instead.
|
|
79
|
+
*
|
|
80
|
+
* @param locator - CSS selector string or Selenium By locator
|
|
81
|
+
* @returns Promise resolving to array of WebElements (empty if none found)
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // Get all list items
|
|
86
|
+
* const items = await app.findAll('.list-item');
|
|
87
|
+
* console.log(`Found ${items.length} items`);
|
|
88
|
+
*
|
|
89
|
+
* // Iterate over elements
|
|
90
|
+
* for (const item of items) {
|
|
91
|
+
* const text = await item.getText();
|
|
92
|
+
* console.log(text);
|
|
93
|
+
* }
|
|
94
|
+
*
|
|
95
|
+
* // Using By locator
|
|
96
|
+
* const buttons = await app.findAll(By.css('button'));
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
14
99
|
findAll(locator: By | string): Promise<WebElement[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Finds all matching elements with automatic waiting for at least one element to appear.
|
|
102
|
+
*
|
|
103
|
+
* Waits until at least one element matching the locator appears, then returns all matching elements.
|
|
104
|
+
* Use this when you expect elements to load dynamically and need to ensure they're present.
|
|
105
|
+
*
|
|
106
|
+
* @param locator - CSS selector string or Selenium By locator
|
|
107
|
+
* @param options - Optional configuration
|
|
108
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
109
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
110
|
+
* @returns Promise resolving to array of WebElements
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* // Wait for search results to load
|
|
115
|
+
* const results = await app.findAllWithTimeout('.search-result');
|
|
116
|
+
*
|
|
117
|
+
* // With custom timeout for slow-loading content
|
|
118
|
+
* const items = await app.findAllWithTimeout('.async-item', { timeout: 15000 });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
15
121
|
findAllWithTimeout(locator: By | string, { timeout, pollTimeout }?: {
|
|
16
122
|
timeout?: number;
|
|
17
123
|
pollTimeout?: number;
|
|
18
124
|
}): Promise<WebElement[]>;
|
|
125
|
+
/**
|
|
126
|
+
* Finds a child element within a parent element with automatic waiting.
|
|
127
|
+
*
|
|
128
|
+
* Useful for scoped element searches within a specific container. Automatically waits
|
|
129
|
+
* for both the parent and child elements to appear.
|
|
130
|
+
*
|
|
131
|
+
* @param rootElement - Parent element (WebElement, By locator, or CSS selector)
|
|
132
|
+
* @param locator - Child element selector (By locator or CSS selector)
|
|
133
|
+
* @param options - Optional configuration
|
|
134
|
+
* @param options.waitForChild - Whether to wait for child to appear (default: true)
|
|
135
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
136
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
137
|
+
* @returns Promise resolving to the child WebElement
|
|
138
|
+
* @throws Error if child element is not found within the timeout period
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* // Find button within a specific dialog
|
|
143
|
+
* const dialog = await app.find('.modal-dialog');
|
|
144
|
+
* const closeBtn = await app.findChild(dialog, '.close-button');
|
|
145
|
+
*
|
|
146
|
+
* // Or find child directly using parent selector
|
|
147
|
+
* const button = await app.findChild('.modal-dialog', 'button.submit');
|
|
148
|
+
*
|
|
149
|
+
* // Without waiting for child (if you know it exists)
|
|
150
|
+
* const child = await app.findChild(parent, '.child', { waitForChild: false });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
19
153
|
findChild(rootElement: WebElement | By | string, locator: By | string, { waitForChild, timeout, pollTimeout }?: {
|
|
20
154
|
waitForChild?: boolean;
|
|
21
155
|
timeout?: number;
|
|
22
156
|
pollTimeout?: number;
|
|
23
157
|
}): Promise<WebElement>;
|
|
158
|
+
/**
|
|
159
|
+
* Finds all child elements within a parent element with automatic waiting.
|
|
160
|
+
*
|
|
161
|
+
* Similar to {@link findChild} but returns all matching children instead of just the first one.
|
|
162
|
+
* Waits for at least one child to appear before returning.
|
|
163
|
+
*
|
|
164
|
+
* @param rootElement - Parent element (WebElement, By locator, or CSS selector)
|
|
165
|
+
* @param locator - Child elements selector (By locator or CSS selector)
|
|
166
|
+
* @param options - Optional configuration
|
|
167
|
+
* @param options.waitForChild - Whether to wait for at least one child to appear (default: true)
|
|
168
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
169
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
170
|
+
* @returns Promise resolving to array of child WebElements
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* // Find all rows in a specific table
|
|
175
|
+
* const table = await app.find('#data-table');
|
|
176
|
+
* const rows = await app.findChildren(table, 'tr');
|
|
177
|
+
*
|
|
178
|
+
* // Or find children directly using parent selector
|
|
179
|
+
* const items = await app.findChildren('.dropdown-menu', 'li');
|
|
180
|
+
*
|
|
181
|
+
* // Process all children
|
|
182
|
+
* for (const row of rows) {
|
|
183
|
+
* const text = await row.getText();
|
|
184
|
+
* console.log(text);
|
|
185
|
+
* }
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
24
188
|
findChildren(rootElement: WebElement | By | string, locator: By | string, { waitForChild, timeout, pollTimeout }?: {
|
|
25
189
|
waitForChild?: boolean;
|
|
26
190
|
timeout?: number;
|
|
27
191
|
pollTimeout?: number;
|
|
28
192
|
}): Promise<WebElement[]>;
|
|
193
|
+
/**
|
|
194
|
+
* Clicks an element with automatic waiting and retry logic.
|
|
195
|
+
*
|
|
196
|
+
* **Handles common click issues automatically:**
|
|
197
|
+
* - Waits for element to appear in DOM
|
|
198
|
+
* - Waits for element to be visible
|
|
199
|
+
* - Waits for element to be enabled
|
|
200
|
+
* - Retries if click fails initially
|
|
201
|
+
*
|
|
202
|
+
* This eliminates flaky tests caused by timing issues.
|
|
203
|
+
*
|
|
204
|
+
* @param element - Element to click (WebElement, By locator, or CSS selector)
|
|
205
|
+
* @param options - Optional configuration
|
|
206
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
207
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
208
|
+
* @returns Promise that resolves when click succeeds
|
|
209
|
+
* @throws Error if element cannot be clicked within timeout
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* // Simple click using CSS selector
|
|
214
|
+
* await app.click('#submit-button');
|
|
215
|
+
*
|
|
216
|
+
* // Click with custom timeout
|
|
217
|
+
* await app.click('.slow-loading-btn', { timeout: 15000 });
|
|
218
|
+
*
|
|
219
|
+
* // Click using By locator
|
|
220
|
+
* await app.click(By.xpath('//button[text()="Submit"]'));
|
|
221
|
+
*
|
|
222
|
+
* // Click a previously found element
|
|
223
|
+
* const button = await app.find('#my-button');
|
|
224
|
+
* await app.click(button);
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
29
227
|
click(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
30
228
|
timeout?: number;
|
|
31
229
|
pollTimeout?: number;
|
|
32
230
|
}): Promise<void>;
|
|
231
|
+
/**
|
|
232
|
+
* Moves the mouse cursor over an element (hover action).
|
|
233
|
+
*
|
|
234
|
+
* Useful for testing hover states, tooltips, dropdown menus, and other hover-triggered UI.
|
|
235
|
+
* Automatically waits for the element to be present before hovering.
|
|
236
|
+
*
|
|
237
|
+
* @param element - Element to hover over (WebElement, By locator, or CSS selector)
|
|
238
|
+
* @param options - Optional configuration
|
|
239
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
240
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
241
|
+
* @returns Promise that resolves when hover completes
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* // Hover to reveal dropdown menu
|
|
246
|
+
* await app.hover('.menu-item');
|
|
247
|
+
* await app.click('.submenu-option');
|
|
248
|
+
*
|
|
249
|
+
* // Hover to show tooltip
|
|
250
|
+
* await app.hover('#info-icon');
|
|
251
|
+
* const tooltip = await app.find('.tooltip');
|
|
252
|
+
* const text = await app.getText(tooltip);
|
|
253
|
+
*
|
|
254
|
+
* // Hover on element found with By locator
|
|
255
|
+
* await app.hover(By.css('[data-test="hover-target"]'));
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
33
258
|
hover(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
34
259
|
timeout?: number;
|
|
35
260
|
pollTimeout?: number;
|
|
36
261
|
}): Promise<void>;
|
|
262
|
+
/**
|
|
263
|
+
* Sets focus on an element programmatically.
|
|
264
|
+
*
|
|
265
|
+
* Directly focuses the element using JavaScript, which is more reliable than clicking for focus.
|
|
266
|
+
* Useful for testing keyboard interactions, input fields, and focus-dependent behaviors.
|
|
267
|
+
*
|
|
268
|
+
* @param element - Element to focus (WebElement, By locator, or CSS selector)
|
|
269
|
+
* @param options - Optional configuration
|
|
270
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
271
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
272
|
+
* @returns Promise that resolves when focus is set
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* // Focus an input field
|
|
277
|
+
* await app.focus('#username');
|
|
278
|
+
* await app.sendKey(Key.CONTROL, 'a'); // Select all
|
|
279
|
+
*
|
|
280
|
+
* // Focus before typing
|
|
281
|
+
* await app.focus('#search-box');
|
|
282
|
+
* await app.type('#search-box', 'test query');
|
|
283
|
+
*
|
|
284
|
+
* // Test focus-dependent behavior
|
|
285
|
+
* await app.focus('#email');
|
|
286
|
+
* await app.expect('.validation-hint').toBeVisible();
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
37
289
|
focus(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
38
290
|
timeout?: number;
|
|
39
291
|
pollTimeout?: number;
|
|
40
292
|
}): Promise<void>;
|
|
293
|
+
/**
|
|
294
|
+
* Performs a right-click (context menu click) on an element.
|
|
295
|
+
*
|
|
296
|
+
* Opens the context menu for the element, allowing you to test right-click menus and actions.
|
|
297
|
+
*
|
|
298
|
+
* @param element - Element to right-click (WebElement, By locator, or CSS selector)
|
|
299
|
+
* @param options - Optional configuration
|
|
300
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
301
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
302
|
+
* @returns Promise that resolves when right-click completes
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```typescript
|
|
306
|
+
* // Open context menu and select option
|
|
307
|
+
* await app.contextClick('.file-item');
|
|
308
|
+
* await app.click('.context-menu-delete');
|
|
309
|
+
*
|
|
310
|
+
* // Right-click on canvas element
|
|
311
|
+
* await app.contextClick('#drawing-canvas');
|
|
312
|
+
* await app.expect('.context-menu').toBeVisible();
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
41
315
|
contextClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
42
316
|
timeout?: number;
|
|
43
317
|
pollTimeout?: number;
|
|
44
318
|
}): Promise<void>;
|
|
319
|
+
/**
|
|
320
|
+
* Performs a double-click on an element.
|
|
321
|
+
*
|
|
322
|
+
* Useful for testing double-click interactions like selecting text, opening files, or
|
|
323
|
+
* triggering double-click-specific behaviors in your application.
|
|
324
|
+
*
|
|
325
|
+
* @param element - Element to double-click (WebElement, By locator, or CSS selector)
|
|
326
|
+
* @param options - Optional configuration
|
|
327
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
328
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
329
|
+
* @returns Promise that resolves when double-click completes
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```typescript
|
|
333
|
+
* // Double-click to open file
|
|
334
|
+
* await app.doubleClick('.file-icon');
|
|
335
|
+
*
|
|
336
|
+
* // Double-click to select word
|
|
337
|
+
* await app.doubleClick('.text-content');
|
|
338
|
+
*
|
|
339
|
+
* // Double-click with custom wait
|
|
340
|
+
* await app.doubleClick('#expandable-item', { timeout: 5000 });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
45
343
|
doubleClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
46
344
|
timeout?: number;
|
|
47
345
|
pollTimeout?: number;
|
|
48
346
|
}): Promise<void>;
|
|
347
|
+
/**
|
|
348
|
+
* Waits for an element to stop animating, then clicks it.
|
|
349
|
+
*
|
|
350
|
+
* Perfect for clicking elements that are animating into view (slides, fades, etc.).
|
|
351
|
+
* Prevents clicks during animation which can cause missed clicks or wrong targets.
|
|
352
|
+
*
|
|
353
|
+
* @param element - Element to wait for and click (WebElement, By locator, or CSS selector)
|
|
354
|
+
* @param options - Optional configuration
|
|
355
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
356
|
+
* @param options.pollTimeout - Interval between animation checks in milliseconds (default: 50)
|
|
357
|
+
* @returns Promise that resolves when element is stable and clicked
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```typescript
|
|
361
|
+
* // Click button that slides into view
|
|
362
|
+
* await app.waitForAnimationAndClick('.animated-button');
|
|
363
|
+
*
|
|
364
|
+
* // Click element in animated modal
|
|
365
|
+
* await app.waitForAnimationAndClick('.modal .submit-btn', { timeout: 5000 });
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
49
368
|
waitForAnimationAndClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
50
369
|
timeout?: number;
|
|
51
370
|
pollTimeout?: number;
|
|
52
371
|
}): Promise<void>;
|
|
372
|
+
/**
|
|
373
|
+
* Scrolls element into view and then clicks it.
|
|
374
|
+
*
|
|
375
|
+
* Handles elements that are not initially in viewport. Scrolls the element to the center
|
|
376
|
+
* of the viewport before clicking, ensuring reliable clicks on off-screen elements.
|
|
377
|
+
*
|
|
378
|
+
* @param element - Element to scroll to and click (WebElement, By locator, or CSS selector)
|
|
379
|
+
* @param options - Optional configuration
|
|
380
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
381
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
382
|
+
* @returns Promise that resolves when element is scrolled into view and clicked
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* // Click element at bottom of page
|
|
387
|
+
* await app.scrollAndClick('#footer-button');
|
|
388
|
+
*
|
|
389
|
+
* // Scroll and click in long form
|
|
390
|
+
* await app.scrollAndClick('.form-submit', { timeout: 5000 });
|
|
391
|
+
*
|
|
392
|
+
* // Click element in scrollable container
|
|
393
|
+
* await app.scrollAndClick('.list-item:last-child');
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
53
396
|
scrollAndClick(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
54
397
|
timeout?: number;
|
|
55
398
|
pollTimeout?: number;
|
|
56
399
|
}): Promise<void>;
|
|
400
|
+
/**
|
|
401
|
+
* Scrolls an element into the viewport without clicking it.
|
|
402
|
+
*
|
|
403
|
+
* Useful when you need an element visible for screenshots, visibility checks, or
|
|
404
|
+
* before performing other actions. Centers the element in the viewport.
|
|
405
|
+
*
|
|
406
|
+
* @param locator - Element to scroll to (By locator or CSS selector)
|
|
407
|
+
* @param options - Optional configuration
|
|
408
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
409
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
410
|
+
* @returns Promise that resolves when element is scrolled into view
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* // Scroll to element for screenshot
|
|
415
|
+
* await app.scrollIntoView('#chart');
|
|
416
|
+
* const screenshot = await app.getScreenshot();
|
|
417
|
+
*
|
|
418
|
+
* // Scroll before checking visibility
|
|
419
|
+
* await app.scrollIntoView('.lazy-load-content');
|
|
420
|
+
* await app.expect('.lazy-load-content').toBeVisible();
|
|
421
|
+
* ```
|
|
422
|
+
*/
|
|
57
423
|
scrollIntoView(locator: By | string, { timeout, pollTimeout }?: {
|
|
58
424
|
timeout?: number;
|
|
59
425
|
pollTimeout?: number;
|
|
60
426
|
}): Promise<void>;
|
|
427
|
+
/**
|
|
428
|
+
* Drags a source element and drops it onto a target element.
|
|
429
|
+
*
|
|
430
|
+
* Performs a complete drag-and-drop operation, useful for testing sortable lists,
|
|
431
|
+
* drag-and-drop file uploads, kanban boards, and similar interactions.
|
|
432
|
+
*
|
|
433
|
+
* @param source - Element to drag (WebElement or By locator)
|
|
434
|
+
* @param target - Element to drop onto (WebElement or By locator)
|
|
435
|
+
* @returns Promise that resolves when drag-and-drop completes
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```typescript
|
|
439
|
+
* // Drag list item to reorder
|
|
440
|
+
* await app.dragTo(
|
|
441
|
+
* By.css('.list-item:nth-child(1)'),
|
|
442
|
+
* By.css('.list-item:nth-child(3)')
|
|
443
|
+
* );
|
|
444
|
+
*
|
|
445
|
+
* // Drag file to upload area
|
|
446
|
+
* const file = await app.find('.file-icon');
|
|
447
|
+
* const dropzone = await app.find('.upload-dropzone');
|
|
448
|
+
* await app.dragTo(file, dropzone);
|
|
449
|
+
*
|
|
450
|
+
* // Drag card between columns (kanban)
|
|
451
|
+
* await app.dragTo('#card-1', '#column-done');
|
|
452
|
+
* ```
|
|
453
|
+
*/
|
|
61
454
|
dragTo(source: WebElement | By, target: WebElement | By): Promise<void>;
|
|
455
|
+
/**
|
|
456
|
+
* Drags an element by a specified pixel offset.
|
|
457
|
+
*
|
|
458
|
+
* Moves an element by dragging it a specific number of pixels in X and Y directions.
|
|
459
|
+
* Useful for testing sliders, resizable panels, draggable windows, and custom drag interactions.
|
|
460
|
+
*
|
|
461
|
+
* @param element - Element to drag (WebElement, By locator, or CSS selector)
|
|
462
|
+
* @param offsetX - Horizontal offset in pixels (positive = right, negative = left)
|
|
463
|
+
* @param offsetY - Vertical offset in pixels (positive = down, negative = up)
|
|
464
|
+
* @returns Promise that resolves when drag completes
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```typescript
|
|
468
|
+
* // Drag slider to the right
|
|
469
|
+
* await app.dragByOffset('.slider-handle', 100, 0);
|
|
470
|
+
*
|
|
471
|
+
* // Drag element down and left
|
|
472
|
+
* await app.dragByOffset('.draggable-box', -50, 75);
|
|
473
|
+
*
|
|
474
|
+
* // Resize panel by dragging splitter
|
|
475
|
+
* await app.dragByOffset('.splitter', 0, -100);
|
|
476
|
+
* ```
|
|
477
|
+
*/
|
|
62
478
|
dragByOffset(element: WebElement | By | string, offsetX: number, offsetY: number): Promise<void>;
|
|
479
|
+
/**
|
|
480
|
+
* Types text into an input element.
|
|
481
|
+
*
|
|
482
|
+
* Automatically finds the element, optionally clears existing content, types the text,
|
|
483
|
+
* and can optionally press Enter after typing. Perfect for form filling and text input.
|
|
484
|
+
*
|
|
485
|
+
* @param element - Input element to type into (WebElement, By locator, or CSS selector)
|
|
486
|
+
* @param text - Text to type
|
|
487
|
+
* @param options - Optional configuration
|
|
488
|
+
* @param options.clear - Whether to clear existing content first (default: true)
|
|
489
|
+
* @param options.sendEnter - Whether to press Enter after typing (default: false)
|
|
490
|
+
* @returns Promise that resolves when typing completes
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```typescript
|
|
494
|
+
* // Type into input (clears existing text by default)
|
|
495
|
+
* await app.type('#username', 'testuser');
|
|
496
|
+
*
|
|
497
|
+
* // Type and submit with Enter
|
|
498
|
+
* await app.type('#search', 'search query', { sendEnter: true });
|
|
499
|
+
*
|
|
500
|
+
* // Type without clearing existing text
|
|
501
|
+
* await app.type('#notes', 'additional text', { clear: false });
|
|
502
|
+
*
|
|
503
|
+
* // Fill form fields
|
|
504
|
+
* await app.type('#email', 'user@example.com');
|
|
505
|
+
* await app.type('#password', 'secret123');
|
|
506
|
+
* await app.click('#login-button');
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
63
509
|
type(element: WebElement | By | string, text: string, { clear, sendEnter }?: {
|
|
64
510
|
clear?: boolean;
|
|
65
511
|
sendEnter?: boolean;
|
|
66
512
|
}): Promise<void>;
|
|
513
|
+
/**
|
|
514
|
+
* Sends a single keyboard key press.
|
|
515
|
+
*
|
|
516
|
+
* Simulates pressing a keyboard key. Use Selenium's Key constants for special keys.
|
|
517
|
+
*
|
|
518
|
+
* @param key - Key to press (use Key.ENTER, Key.TAB, Key.ESCAPE, etc.)
|
|
519
|
+
* @returns Promise that resolves when key press completes
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```typescript
|
|
523
|
+
* import { Key } from '@kendo/kendo-e2e';
|
|
524
|
+
*
|
|
525
|
+
* // Press Enter
|
|
526
|
+
* await app.sendKey(Key.ENTER);
|
|
527
|
+
*
|
|
528
|
+
* // Press Tab to move focus
|
|
529
|
+
* await app.sendKey(Key.TAB);
|
|
530
|
+
*
|
|
531
|
+
* // Press Escape to close modal
|
|
532
|
+
* await app.sendKey(Key.ESCAPE);
|
|
533
|
+
*
|
|
534
|
+
* // Press Arrow Down
|
|
535
|
+
* await app.sendKey(Key.ARROW_DOWN);
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
67
538
|
sendKey(key: string): Promise<void>;
|
|
539
|
+
/**
|
|
540
|
+
* Sends a two-key combination (e.g., Ctrl+C).
|
|
541
|
+
*
|
|
542
|
+
* Convenience method for common two-key combinations. For more keys, use {@link sendKeysCombination}.
|
|
543
|
+
*
|
|
544
|
+
* @param key1 - First key (typically a modifier like Key.CONTROL)
|
|
545
|
+
* @param key2 - Second key
|
|
546
|
+
* @returns Promise that resolves when key combination completes
|
|
547
|
+
*
|
|
548
|
+
* @example
|
|
549
|
+
* ```typescript
|
|
550
|
+
* import { Key } from '@kendo/kendo-e2e';
|
|
551
|
+
*
|
|
552
|
+
* // Copy text
|
|
553
|
+
* await app.sendKeyCombination(Key.CONTROL, 'c');
|
|
554
|
+
*
|
|
555
|
+
* // Paste text
|
|
556
|
+
* await app.sendKeyCombination(Key.CONTROL, 'v');
|
|
557
|
+
*
|
|
558
|
+
* // Open browser dev tools (F12 might not work in some contexts)
|
|
559
|
+
* await app.sendKeyCombination(Key.CONTROL, Key.SHIFT);
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
68
562
|
sendKeyCombination(key1: string, key2: string): Promise<void>;
|
|
563
|
+
/**
|
|
564
|
+
* Sends a combination of multiple keyboard keys simultaneously.
|
|
565
|
+
*
|
|
566
|
+
* Holds down all keys in order, then releases them in reverse order, simulating
|
|
567
|
+
* a realistic key combination press.
|
|
568
|
+
*
|
|
569
|
+
* @param keys - Array of keys to press together
|
|
570
|
+
* @returns Promise that resolves when key combination completes
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```typescript
|
|
574
|
+
* import { Key } from '@kendo/kendo-e2e';
|
|
575
|
+
*
|
|
576
|
+
* // Ctrl+Shift+Delete
|
|
577
|
+
* await app.sendKeysCombination([Key.CONTROL, Key.SHIFT, Key.DELETE]);
|
|
578
|
+
*
|
|
579
|
+
* // Select all (Ctrl+A)
|
|
580
|
+
* await app.sendKeysCombination([Key.CONTROL, 'a']);
|
|
581
|
+
*
|
|
582
|
+
* // Custom three-key combo
|
|
583
|
+
* await app.sendKeysCombination([Key.ALT, Key.SHIFT, 'F']);
|
|
584
|
+
* ```
|
|
585
|
+
*/
|
|
69
586
|
sendKeysCombination(keys: string[]): Promise<void>;
|
|
587
|
+
/**
|
|
588
|
+
* Sends Ctrl+key on Windows/Linux or Cmd+key on macOS automatically.
|
|
589
|
+
*
|
|
590
|
+
* Cross-platform helper that uses the appropriate modifier key for the current OS.
|
|
591
|
+
* Perfect for common shortcuts like copy, paste, save, etc.
|
|
592
|
+
*
|
|
593
|
+
* @param key - Key to combine with Ctrl/Cmd
|
|
594
|
+
* @returns Promise that resolves when key combination completes
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* ```typescript
|
|
598
|
+
* // Copy (Ctrl+C on Windows/Linux, Cmd+C on macOS)
|
|
599
|
+
* await app.sendControlKeyCombination('c');
|
|
600
|
+
*
|
|
601
|
+
* // Paste (cross-platform)
|
|
602
|
+
* await app.sendControlKeyCombination('v');
|
|
603
|
+
*
|
|
604
|
+
* // Select all (cross-platform)
|
|
605
|
+
* await app.sendControlKeyCombination('a');
|
|
606
|
+
*
|
|
607
|
+
* // Save (cross-platform)
|
|
608
|
+
* await app.sendControlKeyCombination('s');
|
|
609
|
+
* ```
|
|
610
|
+
*/
|
|
70
611
|
sendControlKeyCombination(key: string): Promise<void>;
|
|
71
612
|
isVisible(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
72
613
|
timeout?: number;
|
|
@@ -91,38 +632,267 @@ export declare class WebApp {
|
|
|
91
632
|
hasAttribute(element: WebElement | By | string, attribute: string, value: string, exactMatch?: boolean): Promise<boolean>;
|
|
92
633
|
hasClass(element: WebElement | By | string, value: string, exactMatch?: boolean): Promise<boolean>;
|
|
93
634
|
sleep(milliseconds: number): Promise<void>;
|
|
635
|
+
/**
|
|
636
|
+
* Waits for a condition to become true.
|
|
637
|
+
*
|
|
638
|
+
* Core waiting method that polls a condition until it returns true or timeout is reached.
|
|
639
|
+
* Use predefined conditions from {@link EC} class or create custom conditions.
|
|
640
|
+
*
|
|
641
|
+
* @param condition - Condition function or WebElementCondition to wait for
|
|
642
|
+
* @param options - Optional configuration
|
|
643
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
644
|
+
* @param options.message - Custom error message if condition times out (default: 'Failed to satisfy condition.')
|
|
645
|
+
* @param options.pollTimeout - Interval between condition checks in milliseconds (default: 25)
|
|
646
|
+
* @returns Promise that resolves when condition is met
|
|
647
|
+
* @throws Error with the specified message if condition is not met within timeout
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```typescript
|
|
651
|
+
* // Wait for element to be visible
|
|
652
|
+
* await app.wait(EC.isVisible('#modal'));
|
|
653
|
+
*
|
|
654
|
+
* // Wait with custom timeout and message
|
|
655
|
+
* await app.wait(EC.hasText(element, 'Success'), {
|
|
656
|
+
* timeout: 15000,
|
|
657
|
+
* message: 'Success message did not appear'
|
|
658
|
+
* });
|
|
659
|
+
*
|
|
660
|
+
* // Wait for custom condition
|
|
661
|
+
* await app.wait(async () => {
|
|
662
|
+
* const count = await app.findAll('.item');
|
|
663
|
+
* return count.length > 5;
|
|
664
|
+
* }, { message: 'Less than 5 items found' });
|
|
665
|
+
* ```
|
|
666
|
+
*/
|
|
94
667
|
wait(condition: WebElementCondition | WaitCondition, { timeout, message, pollTimeout }?: {
|
|
95
668
|
timeout?: number;
|
|
96
669
|
message?: string;
|
|
97
670
|
pollTimeout?: number;
|
|
98
671
|
}): Promise<void>;
|
|
672
|
+
/**
|
|
673
|
+
* Waits for a condition without throwing an error if it fails.
|
|
674
|
+
*
|
|
675
|
+
* Returns true if condition is met, false if timeout is reached. Perfect for conditional
|
|
676
|
+
* logic in tests where you want to check if something happened without failing the test.
|
|
677
|
+
*
|
|
678
|
+
* @param condition - Condition function or WebElementCondition to wait for
|
|
679
|
+
* @param options - Optional configuration
|
|
680
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
681
|
+
* @param options.pollTimeout - Interval between condition checks in milliseconds (default: 25)
|
|
682
|
+
* @returns Promise resolving to true if condition met, false if timeout reached
|
|
683
|
+
*
|
|
684
|
+
* @example
|
|
685
|
+
* ```typescript
|
|
686
|
+
* // Check if element appears (don't fail if it doesn't)
|
|
687
|
+
* const appeared = await app.waitSafely(EC.isVisible('.optional-message'));
|
|
688
|
+
* if (appeared) {
|
|
689
|
+
* console.log('Message was shown');
|
|
690
|
+
* }
|
|
691
|
+
*
|
|
692
|
+
* // Conditional test flow
|
|
693
|
+
* const hasModal = await app.waitSafely(EC.isVisible('.modal'), { timeout: 3000 });
|
|
694
|
+
* if (hasModal) {
|
|
695
|
+
* await app.click('.modal .close');
|
|
696
|
+
* }
|
|
697
|
+
*
|
|
698
|
+
* // Check if element has specific text
|
|
699
|
+
* const hasText = await app.waitSafely(EC.hasText('#status', 'Complete'));
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
99
702
|
waitSafely(condition: WebElementCondition | WaitCondition, { timeout, pollTimeout }?: {
|
|
100
703
|
timeout?: number;
|
|
101
704
|
pollTimeout?: number;
|
|
102
705
|
}): Promise<boolean>;
|
|
706
|
+
/**
|
|
707
|
+
* Waits for an element to stop moving or resizing (animation to complete).
|
|
708
|
+
*
|
|
709
|
+
* Monitors element position and size, waiting until they remain stable for a poll interval.
|
|
710
|
+
* Essential for reliable interaction with animated elements.
|
|
711
|
+
*
|
|
712
|
+
* @param element - Element to monitor (WebElement, By locator, or CSS selector)
|
|
713
|
+
* @param options - Optional configuration
|
|
714
|
+
* @param options.timeout - Maximum time to wait in milliseconds (default: 10000)
|
|
715
|
+
* @param options.pollTimeout - Interval between stability checks in milliseconds (default: 50)
|
|
716
|
+
* @returns Promise that resolves when element is stable
|
|
717
|
+
* @throws Error if element doesn't stabilize within timeout
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```typescript
|
|
721
|
+
* // Wait for sliding panel to stop
|
|
722
|
+
* await app.waitForAnimation('.slide-panel');
|
|
723
|
+
* await app.click('.slide-panel button');
|
|
724
|
+
*
|
|
725
|
+
* // Wait for expanding accordion
|
|
726
|
+
* await app.click('.accordion-header');
|
|
727
|
+
* await app.waitForAnimation('.accordion-content');
|
|
728
|
+
*
|
|
729
|
+
* // Use before taking screenshots of animated content
|
|
730
|
+
* await app.waitForAnimation('.chart');
|
|
731
|
+
* const screenshot = await app.getScreenshot();
|
|
732
|
+
* ```
|
|
733
|
+
*/
|
|
103
734
|
waitForAnimation(element: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
104
735
|
timeout?: number;
|
|
105
736
|
pollTimeout?: number;
|
|
106
737
|
}): Promise<void>;
|
|
107
738
|
getScreenshot(): Promise<string>;
|
|
739
|
+
/**
|
|
740
|
+
* @deprecated Use executeScript with proper types instead
|
|
741
|
+
* @internal
|
|
742
|
+
*/
|
|
108
743
|
executeScript(script: string | ((...args: unknown[]) => unknown)): Promise<unknown>;
|
|
744
|
+
/**
|
|
745
|
+
* Gets the visible text content of an element.
|
|
746
|
+
*
|
|
747
|
+
* Returns the text that would be visible to a user, excluding hidden elements.
|
|
748
|
+
* Automatically finds the element if a locator is provided.
|
|
749
|
+
*
|
|
750
|
+
* @param element - Element to get text from (WebElement, By locator, or CSS selector)
|
|
751
|
+
* @returns Promise resolving to the element's text, or undefined if element has no text
|
|
752
|
+
*
|
|
753
|
+
* @example
|
|
754
|
+
* ```typescript
|
|
755
|
+
* // Get button text
|
|
756
|
+
* const buttonText = await app.getText('#submit-btn');
|
|
757
|
+
* console.log(buttonText); // 'Submit Form'
|
|
758
|
+
*
|
|
759
|
+
* // Get paragraph content
|
|
760
|
+
* const message = await app.getText('.success-message');
|
|
761
|
+
*
|
|
762
|
+
* // Get text from found element
|
|
763
|
+
* const element = await app.find('.label');
|
|
764
|
+
* const text = await app.getText(element);
|
|
765
|
+
* ```
|
|
766
|
+
*/
|
|
109
767
|
getText(element: WebElement | By | string): Promise<string>;
|
|
768
|
+
/**
|
|
769
|
+
* Gets the value of an HTML attribute from an element.
|
|
770
|
+
*
|
|
771
|
+
* Retrieves attribute values like 'href', 'src', 'disabled', 'data-*', etc.
|
|
772
|
+
* Returns null if the attribute doesn't exist.
|
|
773
|
+
*
|
|
774
|
+
* @param element - Element to get attribute from (WebElement, By locator, or CSS selector)
|
|
775
|
+
* @param attribute - Name of the attribute to retrieve
|
|
776
|
+
* @returns Promise resolving to the attribute value or null
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```typescript
|
|
780
|
+
* // Get link href
|
|
781
|
+
* const url = await app.getAttribute('a.download', 'href');
|
|
782
|
+
*
|
|
783
|
+
* // Check if button is disabled
|
|
784
|
+
* const isDisabled = await app.getAttribute('#submit', 'disabled');
|
|
785
|
+
*
|
|
786
|
+
* // Get data attribute
|
|
787
|
+
* const userId = await app.getAttribute('.user', 'data-user-id');
|
|
788
|
+
*
|
|
789
|
+
* // Get input value
|
|
790
|
+
* const value = await app.getAttribute('#email', 'value');
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
110
793
|
getAttribute(element: WebElement | By | string, attribute: string): Promise<string>;
|
|
794
|
+
/**
|
|
795
|
+
* Gets a JavaScript property value from an element.
|
|
796
|
+
*
|
|
797
|
+
* Different from {@link getAttribute} - this gets DOM properties (like 'value', 'checked')
|
|
798
|
+
* which may differ from HTML attributes. Properties reflect the current state.
|
|
799
|
+
*
|
|
800
|
+
* @param element - Element to get property from (WebElement, By locator, or CSS selector)
|
|
801
|
+
* @param property - Name of the property to retrieve
|
|
802
|
+
* @returns Promise resolving to the property value
|
|
803
|
+
*
|
|
804
|
+
* @example
|
|
805
|
+
* ```typescript
|
|
806
|
+
* // Get checkbox checked state (property, not attribute)
|
|
807
|
+
* const isChecked = await app.getProperty('#agree', 'checked');
|
|
808
|
+
*
|
|
809
|
+
* // Get input value (current value, not initial)
|
|
810
|
+
* const currentValue = await app.getProperty('#username', 'value');
|
|
811
|
+
*
|
|
812
|
+
* // Get element's innerHTML
|
|
813
|
+
* const html = await app.getProperty('.container', 'innerHTML');
|
|
814
|
+
*
|
|
815
|
+
* // Get computed style property
|
|
816
|
+
* const display = await app.getProperty('#element', 'style');
|
|
817
|
+
* ```
|
|
818
|
+
*/
|
|
111
819
|
getProperty(element: WebElement | By | string, property: string): Promise<string>;
|
|
820
|
+
/**
|
|
821
|
+
* Gets the text color (color CSS property) of an element as hex value.
|
|
822
|
+
*
|
|
823
|
+
* Converts the color from any format (rgb, rgba, named) to hex format (#RRGGBB).
|
|
824
|
+
* Useful for visual testing and theme verification.
|
|
825
|
+
*
|
|
826
|
+
* @param element - Element to get color from (WebElement, By locator, or CSS selector)
|
|
827
|
+
* @returns Promise resolving to hex color string (e.g., '#ff0000')
|
|
828
|
+
*
|
|
829
|
+
* @example
|
|
830
|
+
* ```typescript
|
|
831
|
+
* // Check error message color
|
|
832
|
+
* const errorColor = await app.getColor('.error-message');
|
|
833
|
+
* expect(errorColor).toBe('#ff0000'); // red
|
|
834
|
+
*
|
|
835
|
+
* // Verify link color
|
|
836
|
+
* const linkColor = await app.getColor('a.primary');
|
|
837
|
+
*
|
|
838
|
+
* // Check themed text color
|
|
839
|
+
* const textColor = await app.getColor('.themed-text');
|
|
840
|
+
* ```
|
|
841
|
+
*/
|
|
112
842
|
getColor(element: WebElement | By | string): Promise<string>;
|
|
843
|
+
/**
|
|
844
|
+
* Gets the background color (background-color CSS property) of an element as hex value.
|
|
845
|
+
*
|
|
846
|
+
* Converts the background color from any format to hex format (#RRGGBB).
|
|
847
|
+
* Useful for verifying button states, highlights, and theme colors.
|
|
848
|
+
*
|
|
849
|
+
* @param element - Element to get background color from (WebElement, By locator, or CSS selector)
|
|
850
|
+
* @returns Promise resolving to hex color string (e.g., '#ffffff')
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* ```typescript
|
|
854
|
+
* // Check button background
|
|
855
|
+
* const btnBg = await app.getBackgroundColor('#primary-btn');
|
|
856
|
+
* expect(btnBg).toBe('#007bff'); // bootstrap primary
|
|
857
|
+
*
|
|
858
|
+
* // Verify selected item highlight
|
|
859
|
+
* const selectedBg = await app.getBackgroundColor('.selected');
|
|
860
|
+
*
|
|
861
|
+
* // Check alert background color
|
|
862
|
+
* const alertBg = await app.getBackgroundColor('.alert-warning');
|
|
863
|
+
* ```
|
|
864
|
+
*/
|
|
113
865
|
getBackgroundColor(element: WebElement | By | string): Promise<string>;
|
|
114
866
|
/**
|
|
115
|
-
* Hides the text caret
|
|
867
|
+
* Hides the text cursor/caret for cleaner screenshots.
|
|
116
868
|
*
|
|
117
|
-
* When
|
|
118
|
-
*
|
|
119
|
-
*
|
|
869
|
+
* When called without arguments, hides the cursor globally for all input/textarea elements.
|
|
870
|
+
* When called with an element, hides the cursor only for that specific element.
|
|
871
|
+
* Global hiding persists until page reload.
|
|
120
872
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
873
|
+
* @param element - Optional specific element to hide cursor for (WebElement, By locator, or CSS selector)
|
|
874
|
+
* @param options - Optional configuration
|
|
875
|
+
* @param options.timeout - Maximum time to wait for element in milliseconds (default: 10000)
|
|
876
|
+
* @param options.pollTimeout - Interval between retry attempts in milliseconds (default: 25)
|
|
877
|
+
* @returns Promise that resolves when cursor is hidden
|
|
878
|
+
*
|
|
879
|
+
* @example
|
|
880
|
+
* ```typescript
|
|
881
|
+
* // Hide cursor globally before screenshot
|
|
882
|
+
* await app.hideCursor();
|
|
883
|
+
* const screenshot = await app.getScreenshot();
|
|
884
|
+
*
|
|
885
|
+
* // Hide cursor for specific input
|
|
886
|
+
* await app.focus('#username');
|
|
887
|
+
* await app.hideCursor('#username');
|
|
888
|
+
* const inputScreenshot = await app.getScreenshot();
|
|
889
|
+
*
|
|
890
|
+
* // Hide cursor in focused field for visual test
|
|
891
|
+
* await app.type('#search', 'test');
|
|
892
|
+
* await app.hideCursor('#search');
|
|
893
|
+
* ```
|
|
123
894
|
*
|
|
124
|
-
* @
|
|
125
|
-
* @param options Optional timeout and pollTimeout for element location.
|
|
895
|
+
* @see For more details, see [hideCursor documentation](../../docs/hideCursor.md)
|
|
126
896
|
*/
|
|
127
897
|
hideCursor(element?: WebElement | By | string, { timeout, pollTimeout }?: {
|
|
128
898
|
timeout?: number;
|