@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
|
@@ -24,29 +24,154 @@ const VIEWPORT_SCRIPT = function (element) {
|
|
|
24
24
|
}
|
|
25
25
|
return false;
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Expected Conditions (EC) - factory methods for creating wait conditions.
|
|
29
|
+
*
|
|
30
|
+
* Provides a collection of commonly used wait conditions for element states.
|
|
31
|
+
* These conditions are designed to work with {@link WebApp.wait} and {@link WebApp.waitSafely}.
|
|
32
|
+
*
|
|
33
|
+
* **All conditions automatically handle:**
|
|
34
|
+
* - Elements that don't exist yet
|
|
35
|
+
* - Stale element references
|
|
36
|
+
* - Timing issues
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Wait for element to be visible
|
|
41
|
+
* await app.wait(EC.isVisible('#modal'));
|
|
42
|
+
*
|
|
43
|
+
* // Wait for element to have specific text
|
|
44
|
+
* await app.wait(EC.hasText(element, 'Success'));
|
|
45
|
+
*
|
|
46
|
+
* // Wait for element to have focus
|
|
47
|
+
* await app.wait(EC.hasFocus(inputElement));
|
|
48
|
+
*
|
|
49
|
+
* // Check condition without throwing error
|
|
50
|
+
* const isVisible = await app.waitSafely(EC.isVisible('.optional-banner'));
|
|
51
|
+
* if (isVisible) {
|
|
52
|
+
* await app.click('.banner-close');
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
27
56
|
class EC {
|
|
57
|
+
/**
|
|
58
|
+
* Creates a condition that waits for an element to have specific text.
|
|
59
|
+
*
|
|
60
|
+
* Compares the element's visible text content (via getText()) with the expected text.
|
|
61
|
+
* Match must be exact.
|
|
62
|
+
*
|
|
63
|
+
* @param element - WebElement to check text of
|
|
64
|
+
* @param text - Exact text to wait for
|
|
65
|
+
* @returns Condition function for use with wait()
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const message = await app.find('#message');
|
|
70
|
+
* await app.wait(EC.hasText(message, 'Operation completed'));
|
|
71
|
+
*
|
|
72
|
+
* // Or check without waiting
|
|
73
|
+
* const hasCorrectText = await app.hasText('#status', 'Active');
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
28
76
|
static hasText(element, text) {
|
|
29
77
|
return () => element.getText().then(result => {
|
|
30
78
|
return result === text;
|
|
31
79
|
});
|
|
32
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Creates a condition that waits for an input element to have a specific value.
|
|
83
|
+
*
|
|
84
|
+
* Checks the 'value' attribute of form inputs. Perfect for validating input fields
|
|
85
|
+
* after auto-fill, dynamic updates, or user interaction.
|
|
86
|
+
*
|
|
87
|
+
* @param element - Input WebElement to check
|
|
88
|
+
* @param value - Expected value
|
|
89
|
+
* @returns Condition function for use with wait()
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const input = await app.find('#username');
|
|
94
|
+
* await app.type(input, 'testuser');
|
|
95
|
+
* await app.wait(EC.hasValue(input, 'testuser'));
|
|
96
|
+
*
|
|
97
|
+
* // Wait for auto-filled value
|
|
98
|
+
* await app.wait(EC.hasValue(await app.find('#email'), 'user@example.com'));
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
33
101
|
static hasValue(element, value) {
|
|
34
102
|
return () => element.getAttribute("value").then(result => {
|
|
35
103
|
return result === value;
|
|
36
104
|
});
|
|
37
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Creates a condition that waits for an element to have keyboard focus.
|
|
108
|
+
*
|
|
109
|
+
* Checks if the element is the currently active (focused) element in the document.
|
|
110
|
+
* Useful for testing keyboard navigation and focus management.
|
|
111
|
+
*
|
|
112
|
+
* @param element - WebElement to check for focus
|
|
113
|
+
* @returns Condition function for use with wait()
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const input = await app.find('#search');
|
|
118
|
+
* await app.click(input);
|
|
119
|
+
* await app.wait(EC.hasFocus(input));
|
|
120
|
+
*
|
|
121
|
+
* // Verify focus moved after Tab key
|
|
122
|
+
* await app.sendKey(Key.TAB);
|
|
123
|
+
* const nextInput = await app.find('#next-field');
|
|
124
|
+
* await app.wait(EC.hasFocus(nextInput));
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
38
127
|
static hasFocus(element) {
|
|
39
128
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
40
129
|
const focused = yield driver.switchTo().activeElement();
|
|
41
130
|
return (yield element.getId()) === (yield focused.getId());
|
|
42
131
|
});
|
|
43
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Creates a condition that waits for an element to lose keyboard focus.
|
|
135
|
+
*
|
|
136
|
+
* Opposite of {@link hasFocus}. Useful for testing blur events and focus movement.
|
|
137
|
+
*
|
|
138
|
+
* @param element - WebElement to check for lack of focus
|
|
139
|
+
* @returns Condition function for use with wait()
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const input = await app.find('#field');
|
|
144
|
+
* await app.focus(input);
|
|
145
|
+
* await app.sendKey(Key.TAB); // Move focus away
|
|
146
|
+
* await app.wait(EC.hasNoFocus(input));
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
44
149
|
static hasNoFocus(element) {
|
|
45
150
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
46
151
|
const focused = yield driver.switchTo().activeElement();
|
|
47
152
|
return (yield element.getId()) !== (yield focused.getId());
|
|
48
153
|
});
|
|
49
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Creates a condition that waits for an element to have at least one child matching a locator.
|
|
157
|
+
*
|
|
158
|
+
* Checks if the parent element contains any child elements matching the selector.
|
|
159
|
+
* Useful for waiting for dynamic content to load within a container.
|
|
160
|
+
*
|
|
161
|
+
* @param element - Parent WebElement to search within
|
|
162
|
+
* @param locator - Child element selector (By locator or CSS selector string)
|
|
163
|
+
* @returns Condition function for use with wait()
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const list = await app.find('ul#results');
|
|
168
|
+
* await app.wait(EC.hasChild(list, 'li'));
|
|
169
|
+
*
|
|
170
|
+
* // Wait for specific child
|
|
171
|
+
* const table = await app.find('#data-table');
|
|
172
|
+
* await app.wait(EC.hasChild(table, '.loaded-row'));
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
50
175
|
static hasChild(element, locator) {
|
|
51
176
|
return () => __awaiter(this, void 0, void 0, function* () {
|
|
52
177
|
return (locator instanceof selenium_webdriver_1.By)
|
|
@@ -54,6 +179,32 @@ class EC {
|
|
|
54
179
|
: element.findElements(selenium_webdriver_1.By.css(locator)).then(result => { return result.length > 0; });
|
|
55
180
|
});
|
|
56
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Creates a condition that waits for an element to have a specific attribute value.
|
|
184
|
+
*
|
|
185
|
+
* Can check for exact match or partial match (contains). Useful for validating
|
|
186
|
+
* data attributes, ARIA attributes, disabled state, etc.
|
|
187
|
+
*
|
|
188
|
+
* @param element - WebElement to check
|
|
189
|
+
* @param attribute - Attribute name (e.g., 'disabled', 'data-id', 'aria-label')
|
|
190
|
+
* @param value - Expected value
|
|
191
|
+
* @param exactMatch - If true, value must match exactly; if false, attribute must contain value (default: true)
|
|
192
|
+
* @returns Condition function for use with wait()
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const button = await app.find('#submit');
|
|
197
|
+
*
|
|
198
|
+
* // Wait for button to become disabled
|
|
199
|
+
* await app.wait(EC.hasAttribute(button, 'disabled', 'true'));
|
|
200
|
+
*
|
|
201
|
+
* // Wait for data attribute (partial match)
|
|
202
|
+
* await app.wait(EC.hasAttribute(button, 'data-state', 'loading', false));
|
|
203
|
+
*
|
|
204
|
+
* // Check ARIA label
|
|
205
|
+
* await app.wait(EC.hasAttribute(button, 'aria-label', 'Submit form'));
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
57
208
|
static hasAttribute(element, attribute, value, exactMatch = true) {
|
|
58
209
|
return () => element.getAttribute(attribute).then(result => {
|
|
59
210
|
if (exactMatch) {
|
|
@@ -64,9 +215,56 @@ class EC {
|
|
|
64
215
|
}
|
|
65
216
|
});
|
|
66
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Creates a condition that waits for an element to have a specific CSS class.
|
|
220
|
+
*
|
|
221
|
+
* Convenience method that checks the 'class' attribute. Can do exact or partial match.
|
|
222
|
+
* Perfect for waiting for state changes reflected in CSS classes.
|
|
223
|
+
*
|
|
224
|
+
* @param element - WebElement to check
|
|
225
|
+
* @param value - Class name to wait for
|
|
226
|
+
* @param exactMatch - If true, class attribute must match exactly; if false, must contain the class (default: false)
|
|
227
|
+
* @returns Condition function for use with wait()
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* const button = await app.find('#submit');
|
|
232
|
+
*
|
|
233
|
+
* // Wait for class to be added (partial match)
|
|
234
|
+
* await app.wait(EC.hasClass(button, 'active'));
|
|
235
|
+
*
|
|
236
|
+
* // Wait for exact class attribute
|
|
237
|
+
* await app.wait(EC.hasClass(button, 'btn btn-primary', true));
|
|
238
|
+
*
|
|
239
|
+
* // Wait for loading class
|
|
240
|
+
* await app.wait(EC.hasClass(await app.find('.spinner'), 'loading'));
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
67
243
|
static hasClass(element, value, exactMatch = false) {
|
|
68
244
|
return this.hasAttribute(element, "class", value, exactMatch);
|
|
69
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Creates a condition that waits for an element to be visible.
|
|
248
|
+
*
|
|
249
|
+
* Element must be present in DOM and have display style that makes it visible.
|
|
250
|
+
* Accepts WebElement, By locator, or CSS selector string.
|
|
251
|
+
*
|
|
252
|
+
* @param element - Element to check visibility of (WebElement, By locator, or CSS selector)
|
|
253
|
+
* @returns Condition function for use with wait()
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* // Wait for modal to appear
|
|
258
|
+
* await app.wait(EC.isVisible('#modal'));
|
|
259
|
+
*
|
|
260
|
+
* // Wait for element after click
|
|
261
|
+
* await app.click('#show-details');
|
|
262
|
+
* await app.wait(EC.isVisible('.details-panel'));
|
|
263
|
+
*
|
|
264
|
+
* // With By locator
|
|
265
|
+
* await app.wait(EC.isVisible(By.css('[data-test="banner"]')));
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
70
268
|
static isVisible(element) {
|
|
71
269
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
72
270
|
try {
|
|
@@ -82,6 +280,25 @@ class EC {
|
|
|
82
280
|
}
|
|
83
281
|
});
|
|
84
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Creates a condition that waits for an element to become hidden or not present.
|
|
285
|
+
*
|
|
286
|
+
* Element is considered not visible if it's either not in DOM or has display:none or similar.
|
|
287
|
+
* Opposite of {@link isVisible}.
|
|
288
|
+
*
|
|
289
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
290
|
+
* @returns Condition function for use with wait()
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```typescript
|
|
294
|
+
* // Wait for loading spinner to disappear
|
|
295
|
+
* await app.wait(EC.notVisible('.spinner'));
|
|
296
|
+
*
|
|
297
|
+
* // Wait for modal to close
|
|
298
|
+
* await app.click('.modal .close');
|
|
299
|
+
* await app.wait(EC.notVisible('.modal'));
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
85
302
|
static notVisible(element) {
|
|
86
303
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
87
304
|
try {
|
|
@@ -97,6 +314,25 @@ class EC {
|
|
|
97
314
|
}
|
|
98
315
|
});
|
|
99
316
|
}
|
|
317
|
+
/**
|
|
318
|
+
* Creates a condition that waits for an element to be in the visible viewport.
|
|
319
|
+
*
|
|
320
|
+
* Checks if the center point of the element is actually visible in the viewport and not
|
|
321
|
+
* covered by other elements. Stricter than {@link isVisible} - element must be scrolled into view.
|
|
322
|
+
*
|
|
323
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
324
|
+
* @returns Condition function for use with wait()
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```typescript
|
|
328
|
+
* // Wait for element to scroll into view
|
|
329
|
+
* await app.wait(EC.isInViewport('.footer-content'));
|
|
330
|
+
*
|
|
331
|
+
* // Verify element is actually visible to user
|
|
332
|
+
* await app.scrollIntoView('#target');
|
|
333
|
+
* await app.wait(EC.isInViewport('#target'));
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
100
336
|
static isInViewport(element) {
|
|
101
337
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
102
338
|
try {
|
|
@@ -113,6 +349,21 @@ class EC {
|
|
|
113
349
|
}
|
|
114
350
|
});
|
|
115
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Creates a condition that waits for an element to be outside the visible viewport.
|
|
354
|
+
*
|
|
355
|
+
* Checks if the element is scrolled out of view or covered. Opposite of {@link isInViewport}.
|
|
356
|
+
*
|
|
357
|
+
* @param element - Element to check (WebElement, By locator, or CSS selector)
|
|
358
|
+
* @returns Condition function for use with wait()
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* // Wait for element to scroll out of view
|
|
363
|
+
* await app.scrollIntoView('#bottom-element');
|
|
364
|
+
* await app.wait(EC.notInViewport('#top-element'));
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
116
367
|
static notInViewport(element) {
|
|
117
368
|
return (driver) => __awaiter(this, void 0, void 0, function* () {
|
|
118
369
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditions.js","sourceRoot":"","sources":["../../src/selenium/conditions.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2DAA+D;
|
|
1
|
+
{"version":3,"file":"conditions.js","sourceRoot":"","sources":["../../src/selenium/conditions.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,11 @@ import { Options as ChromeOptions } from "selenium-webdriver/chrome";
|
|
|
3
3
|
import { Options as EdgeOptions } from "selenium-webdriver/edge";
|
|
4
4
|
import { Options as FirefoxOptions } from "selenium-webdriver/firefox";
|
|
5
5
|
import { Options as SafariOptions } from "selenium-webdriver/safari";
|
|
6
|
+
/**
|
|
7
|
+
* Options for configuring WebDriver instances.
|
|
8
|
+
*/
|
|
6
9
|
export interface DriverOptions {
|
|
10
|
+
/** Mobile device emulation settings */
|
|
7
11
|
mobileEmulation?: {
|
|
8
12
|
deviceName: string;
|
|
9
13
|
} | {
|
|
@@ -11,12 +15,131 @@ export interface DriverOptions {
|
|
|
11
15
|
height: number;
|
|
12
16
|
pixelRatio: number;
|
|
13
17
|
} | any;
|
|
18
|
+
/** Enable BiDi (Bidirectional communication) protocol */
|
|
14
19
|
enableBidi?: boolean;
|
|
15
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Factory class for creating and configuring Selenium WebDriver instances.
|
|
23
|
+
*
|
|
24
|
+
* Handles browser-specific configuration and provides pre-configured drivers for different browsers.
|
|
25
|
+
* Automatically applies settings from environment variables and Settings class.
|
|
26
|
+
*
|
|
27
|
+
* **Supported browsers:**
|
|
28
|
+
* - Chrome (with mobile emulation and BiDi support)
|
|
29
|
+
* - Edge
|
|
30
|
+
* - Firefox
|
|
31
|
+
* - Safari
|
|
32
|
+
* - BrowserStack (cloud testing)
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Get default driver (from Settings.browserName)
|
|
37
|
+
* const manager = new DriverManager();
|
|
38
|
+
* const driver = manager.getDriver();
|
|
39
|
+
*
|
|
40
|
+
* // Get driver with mobile emulation
|
|
41
|
+
* const mobileDriver = manager.getDriver({
|
|
42
|
+
* mobileEmulation: { deviceName: 'iPhone 14 Pro Max' }
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Get driver with BiDi enabled
|
|
46
|
+
* const bidiDriver = manager.getDriver({ enableBidi: true });
|
|
47
|
+
*
|
|
48
|
+
* // Get specific browser driver
|
|
49
|
+
* const chromeDriver = manager.getChromeDriver();
|
|
50
|
+
* const firefoxDriver = manager.getFirefoxDriver();
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
16
53
|
export declare class DriverManager {
|
|
54
|
+
/**
|
|
55
|
+
* Default command-line arguments for Chromium-based browsers (Chrome, Edge).
|
|
56
|
+
*
|
|
57
|
+
* These options ensure consistent test behavior:
|
|
58
|
+
* - Fixed window size and scale factor for consistent screenshots
|
|
59
|
+
* - Disabled extensions and notifications to avoid interference
|
|
60
|
+
* - Reduced logging noise
|
|
61
|
+
* - Certificate error handling
|
|
62
|
+
* - Disabled search engine choice screen
|
|
63
|
+
*/
|
|
17
64
|
DEFAULT_CHROMIUM_OPTIONS: string[];
|
|
65
|
+
/**
|
|
66
|
+
* Creates a WebDriver instance based on Settings.browserName.
|
|
67
|
+
*
|
|
68
|
+
* Automatically selects the appropriate browser driver based on configuration.
|
|
69
|
+
* Supports mobile emulation and BiDi protocol for Chrome.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Optional driver configuration
|
|
72
|
+
* @param options.mobileEmulation - Mobile device emulation settings (Chrome only)
|
|
73
|
+
* @param options.enableBidi - Enable BiDi protocol for advanced features (Chrome only)
|
|
74
|
+
* @returns Configured WebDriver instance
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const manager = new DriverManager();
|
|
79
|
+
*
|
|
80
|
+
* // Basic driver
|
|
81
|
+
* const driver = manager.getDriver();
|
|
82
|
+
*
|
|
83
|
+
* // With mobile emulation
|
|
84
|
+
* const mobile = manager.getDriver({
|
|
85
|
+
* mobileEmulation: { deviceName: 'Pixel 5' }
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* // With BiDi for CDP features
|
|
89
|
+
* const advanced = manager.getDriver({ enableBidi: true });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
18
92
|
getDriver(options?: DriverOptions): ThenableWebDriver;
|
|
93
|
+
/**
|
|
94
|
+
* Creates Chrome-specific options with custom arguments and settings.
|
|
95
|
+
*
|
|
96
|
+
* Configures Chrome with optimal settings for testing, including headless mode
|
|
97
|
+
* support, Docker compatibility, mobile emulation, and BiDi protocol.
|
|
98
|
+
*
|
|
99
|
+
* @param args - Command-line arguments for Chrome (default: DEFAULT_CHROMIUM_OPTIONS)
|
|
100
|
+
* @param options - Driver configuration options
|
|
101
|
+
* @returns Configured ChromeOptions instance
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const manager = new DriverManager();
|
|
106
|
+
*
|
|
107
|
+
* // Get default options
|
|
108
|
+
* const options = manager.getChromeOptions();
|
|
109
|
+
*
|
|
110
|
+
* // Custom arguments
|
|
111
|
+
* const customOptions = manager.getChromeOptions([
|
|
112
|
+
* '--window-size=1920,1080',
|
|
113
|
+
* '--disable-gpu'
|
|
114
|
+
* ]);
|
|
115
|
+
*
|
|
116
|
+
* // With mobile emulation
|
|
117
|
+
* const mobileOptions = manager.getChromeOptions(
|
|
118
|
+
* manager.DEFAULT_CHROMIUM_OPTIONS,
|
|
119
|
+
* { mobileEmulation: { deviceName: 'iPhone 12' } }
|
|
120
|
+
* );
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
19
123
|
getChromeOptions(args?: string[], options?: DriverOptions): ChromeOptions;
|
|
124
|
+
/**
|
|
125
|
+
* Creates a Chrome WebDriver instance.
|
|
126
|
+
*
|
|
127
|
+
* @param options - Either pre-configured ChromeOptions or DriverOptions
|
|
128
|
+
* @returns Chrome WebDriver instance
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const manager = new DriverManager();
|
|
133
|
+
*
|
|
134
|
+
* // Basic Chrome driver
|
|
135
|
+
* const driver = manager.getChromeDriver();
|
|
136
|
+
*
|
|
137
|
+
* // With custom options
|
|
138
|
+
* const options = manager.getChromeOptions();
|
|
139
|
+
* options.addArguments('--start-maximized');
|
|
140
|
+
* const driver = manager.getChromeDriver(options);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
20
143
|
getChromeDriver(options?: ChromeOptions | DriverOptions): ThenableWebDriver;
|
|
21
144
|
getEdgeOptions(args?: string[]): EdgeOptions;
|
|
22
145
|
getEdgeDriver(options?: EdgeOptions): ThenableWebDriver;
|
|
@@ -8,8 +8,50 @@ const firefox_1 = require("selenium-webdriver/firefox");
|
|
|
8
8
|
const safari_1 = require("selenium-webdriver/safari");
|
|
9
9
|
const browserstack_settings_1 = require("../settings/browserstack-settings");
|
|
10
10
|
const settings_1 = require("../settings/settings");
|
|
11
|
+
/**
|
|
12
|
+
* Factory class for creating and configuring Selenium WebDriver instances.
|
|
13
|
+
*
|
|
14
|
+
* Handles browser-specific configuration and provides pre-configured drivers for different browsers.
|
|
15
|
+
* Automatically applies settings from environment variables and Settings class.
|
|
16
|
+
*
|
|
17
|
+
* **Supported browsers:**
|
|
18
|
+
* - Chrome (with mobile emulation and BiDi support)
|
|
19
|
+
* - Edge
|
|
20
|
+
* - Firefox
|
|
21
|
+
* - Safari
|
|
22
|
+
* - BrowserStack (cloud testing)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // Get default driver (from Settings.browserName)
|
|
27
|
+
* const manager = new DriverManager();
|
|
28
|
+
* const driver = manager.getDriver();
|
|
29
|
+
*
|
|
30
|
+
* // Get driver with mobile emulation
|
|
31
|
+
* const mobileDriver = manager.getDriver({
|
|
32
|
+
* mobileEmulation: { deviceName: 'iPhone 14 Pro Max' }
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Get driver with BiDi enabled
|
|
36
|
+
* const bidiDriver = manager.getDriver({ enableBidi: true });
|
|
37
|
+
*
|
|
38
|
+
* // Get specific browser driver
|
|
39
|
+
* const chromeDriver = manager.getChromeDriver();
|
|
40
|
+
* const firefoxDriver = manager.getFirefoxDriver();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
11
43
|
class DriverManager {
|
|
12
44
|
constructor() {
|
|
45
|
+
/**
|
|
46
|
+
* Default command-line arguments for Chromium-based browsers (Chrome, Edge).
|
|
47
|
+
*
|
|
48
|
+
* These options ensure consistent test behavior:
|
|
49
|
+
* - Fixed window size and scale factor for consistent screenshots
|
|
50
|
+
* - Disabled extensions and notifications to avoid interference
|
|
51
|
+
* - Reduced logging noise
|
|
52
|
+
* - Certificate error handling
|
|
53
|
+
* - Disabled search engine choice screen
|
|
54
|
+
*/
|
|
13
55
|
this.DEFAULT_CHROMIUM_OPTIONS = [
|
|
14
56
|
`--window-size=${settings_1.Settings.browserWidth},${settings_1.Settings.browserHeight}`,
|
|
15
57
|
'--force-device-scale-factor=1',
|
|
@@ -20,6 +62,33 @@ class DriverManager {
|
|
|
20
62
|
'--ignore-certificate-errors'
|
|
21
63
|
];
|
|
22
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Creates a WebDriver instance based on Settings.browserName.
|
|
67
|
+
*
|
|
68
|
+
* Automatically selects the appropriate browser driver based on configuration.
|
|
69
|
+
* Supports mobile emulation and BiDi protocol for Chrome.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Optional driver configuration
|
|
72
|
+
* @param options.mobileEmulation - Mobile device emulation settings (Chrome only)
|
|
73
|
+
* @param options.enableBidi - Enable BiDi protocol for advanced features (Chrome only)
|
|
74
|
+
* @returns Configured WebDriver instance
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const manager = new DriverManager();
|
|
79
|
+
*
|
|
80
|
+
* // Basic driver
|
|
81
|
+
* const driver = manager.getDriver();
|
|
82
|
+
*
|
|
83
|
+
* // With mobile emulation
|
|
84
|
+
* const mobile = manager.getDriver({
|
|
85
|
+
* mobileEmulation: { deviceName: 'Pixel 5' }
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* // With BiDi for CDP features
|
|
89
|
+
* const advanced = manager.getDriver({ enableBidi: true });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
23
92
|
getDriver(options = {}) {
|
|
24
93
|
switch (settings_1.Settings.browserName) {
|
|
25
94
|
case selenium_webdriver_1.Browser.CHROME: {
|
|
@@ -40,6 +109,36 @@ class DriverManager {
|
|
|
40
109
|
}
|
|
41
110
|
}
|
|
42
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Creates Chrome-specific options with custom arguments and settings.
|
|
114
|
+
*
|
|
115
|
+
* Configures Chrome with optimal settings for testing, including headless mode
|
|
116
|
+
* support, Docker compatibility, mobile emulation, and BiDi protocol.
|
|
117
|
+
*
|
|
118
|
+
* @param args - Command-line arguments for Chrome (default: DEFAULT_CHROMIUM_OPTIONS)
|
|
119
|
+
* @param options - Driver configuration options
|
|
120
|
+
* @returns Configured ChromeOptions instance
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const manager = new DriverManager();
|
|
125
|
+
*
|
|
126
|
+
* // Get default options
|
|
127
|
+
* const options = manager.getChromeOptions();
|
|
128
|
+
*
|
|
129
|
+
* // Custom arguments
|
|
130
|
+
* const customOptions = manager.getChromeOptions([
|
|
131
|
+
* '--window-size=1920,1080',
|
|
132
|
+
* '--disable-gpu'
|
|
133
|
+
* ]);
|
|
134
|
+
*
|
|
135
|
+
* // With mobile emulation
|
|
136
|
+
* const mobileOptions = manager.getChromeOptions(
|
|
137
|
+
* manager.DEFAULT_CHROMIUM_OPTIONS,
|
|
138
|
+
* { mobileEmulation: { deviceName: 'iPhone 12' } }
|
|
139
|
+
* );
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
43
142
|
getChromeOptions(args = this.DEFAULT_CHROMIUM_OPTIONS, options = {}) {
|
|
44
143
|
const chromeOptions = new chrome_1.Options();
|
|
45
144
|
args.forEach(argument => {
|
|
@@ -65,6 +164,25 @@ class DriverManager {
|
|
|
65
164
|
}
|
|
66
165
|
return chromeOptions;
|
|
67
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Creates a Chrome WebDriver instance.
|
|
169
|
+
*
|
|
170
|
+
* @param options - Either pre-configured ChromeOptions or DriverOptions
|
|
171
|
+
* @returns Chrome WebDriver instance
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const manager = new DriverManager();
|
|
176
|
+
*
|
|
177
|
+
* // Basic Chrome driver
|
|
178
|
+
* const driver = manager.getChromeDriver();
|
|
179
|
+
*
|
|
180
|
+
* // With custom options
|
|
181
|
+
* const options = manager.getChromeOptions();
|
|
182
|
+
* options.addArguments('--start-maximized');
|
|
183
|
+
* const driver = manager.getChromeDriver(options);
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
68
186
|
getChromeDriver(options) {
|
|
69
187
|
let chromeOptions;
|
|
70
188
|
if (options instanceof chrome_1.Options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver-manager.js","sourceRoot":"","sources":["../../src/selenium/driver-manager.ts"],"names":[],"mappings":";;;AAAA,2DAAkF;AAClF,sDAAqE;AACrE,kDAAiE;AACjE,wDAAgH;AAChH,sDAAqE;AACrE,6EAA6E;AAC7E,mDAAgD;
|
|
1
|
+
{"version":3,"file":"driver-manager.js","sourceRoot":"","sources":["../../src/selenium/driver-manager.ts"],"names":[],"mappings":"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"}
|