browsertime 26.3.2 → 27.0.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/CHANGELOG.md +72 -0
- package/README.md +1 -1
- package/browserscripts/timings/softNavigations.js +94 -0
- package/lib/chrome/har.js +36 -5
- package/lib/chrome/settings/chromeAndroidOptions.js +2 -1
- package/lib/chrome/webdriver/chromium.js +40 -1
- package/lib/chrome/webdriver/setupChromiumOptions.js +86 -31
- package/lib/core/engine/collector.js +340 -317
- package/lib/core/engine/command/addText.js +93 -12
- package/lib/core/engine/command/click.js +268 -139
- package/lib/core/engine/command/commandHelper.js +45 -0
- package/lib/core/engine/command/cookie.js +85 -0
- package/lib/core/engine/command/element.js +37 -2
- package/lib/core/engine/command/javaScript.js +14 -24
- package/lib/core/engine/command/measure/screenshots.js +114 -0
- package/lib/core/engine/command/measure/video.js +85 -0
- package/lib/core/engine/command/measure.js +104 -180
- package/lib/core/engine/command/mouse/clickAndHold.js +6 -3
- package/lib/core/engine/command/mouse/contextClick.js +56 -4
- package/lib/core/engine/command/mouse/doubleClick.js +49 -1
- package/lib/core/engine/command/mouse/mouseMove.js +50 -1
- package/lib/core/engine/command/mouse/singleClick.js +165 -129
- package/lib/core/engine/command/navigation.js +6 -6
- package/lib/core/engine/command/select.js +95 -3
- package/lib/core/engine/command/selectorParser.js +58 -0
- package/lib/core/engine/command/set.js +55 -1
- package/lib/core/engine/command/wait.js +41 -2
- package/lib/core/engine/commands.js +550 -42
- package/lib/core/engine/index.js +206 -150
- package/lib/core/engine/iteration.js +277 -137
- package/lib/firefox/networkManager.js +22 -30
- package/lib/firefox/webdriver/builder.js +14 -0
- package/lib/safari/har.js +131 -0
- package/lib/safari/native/ios-capture +0 -0
- package/lib/safari/native/ios-capture.m +340 -0
- package/lib/safari/safariInspectorClient.js +322 -0
- package/lib/safari/webdriver/safari.js +303 -13
- package/lib/safari/webkitToCdpAdapter.js +241 -0
- package/lib/support/cli.js +13 -0
- package/lib/support/engineUtils.js +16 -5
- package/lib/support/getViewPort.js +5 -0
- package/lib/support/har/index.js +41 -3
- package/lib/support/usbPower.js +2 -3
- package/lib/video/postprocessing/finetune/addTextToVideo.js +4 -0
- package/lib/video/postprocessing/finetune/getFont.js +3 -3
- package/lib/video/postprocessing/finetune/getTimingMetrics.js +7 -0
- package/lib/video/postprocessing/finetune/index.js +26 -9
- package/lib/video/screenRecording/ios/iosDeviceRecorder.js +109 -0
- package/lib/video/screenRecording/recorder.js +2 -2
- package/lib/video/screenRecording/setOrangeBackground.js +3 -0
- package/package.json +11 -11
- package/types/core/engine/command/addText.d.ts +35 -6
- package/types/core/engine/command/addText.d.ts.map +1 -1
- package/types/core/engine/command/click.d.ts +87 -16
- package/types/core/engine/command/click.d.ts.map +1 -1
- package/types/core/engine/command/commandHelper.d.ts +16 -0
- package/types/core/engine/command/commandHelper.d.ts.map +1 -0
- package/types/core/engine/command/cookie.d.ts +65 -0
- package/types/core/engine/command/cookie.d.ts.map +1 -0
- package/types/core/engine/command/element.d.ts +19 -1
- package/types/core/engine/command/element.d.ts.map +1 -1
- package/types/core/engine/command/javaScript.d.ts +4 -0
- package/types/core/engine/command/javaScript.d.ts.map +1 -1
- package/types/core/engine/command/measure/screenshots.d.ts +15 -0
- package/types/core/engine/command/measure/screenshots.d.ts.map +1 -0
- package/types/core/engine/command/measure/video.d.ts +26 -0
- package/types/core/engine/command/measure/video.d.ts.map +1 -0
- package/types/core/engine/command/measure.d.ts +59 -33
- package/types/core/engine/command/measure.d.ts.map +1 -1
- package/types/core/engine/command/mouse/clickAndHold.d.ts.map +1 -1
- package/types/core/engine/command/mouse/contextClick.d.ts +28 -4
- package/types/core/engine/command/mouse/contextClick.d.ts.map +1 -1
- package/types/core/engine/command/mouse/doubleClick.d.ts +24 -4
- package/types/core/engine/command/mouse/doubleClick.d.ts.map +1 -1
- package/types/core/engine/command/mouse/mouseMove.d.ts +30 -5
- package/types/core/engine/command/mouse/mouseMove.d.ts.map +1 -1
- package/types/core/engine/command/mouse/singleClick.d.ts +50 -13
- package/types/core/engine/command/mouse/singleClick.d.ts.map +1 -1
- package/types/core/engine/command/navigation.d.ts +3 -3
- package/types/core/engine/command/select.d.ts +45 -8
- package/types/core/engine/command/select.d.ts.map +1 -1
- package/types/core/engine/command/selectorParser.d.ts +20 -0
- package/types/core/engine/command/selectorParser.d.ts.map +1 -0
- package/types/core/engine/command/set.d.ts +34 -7
- package/types/core/engine/command/set.d.ts.map +1 -1
- package/types/core/engine/command/wait.d.ts +29 -6
- package/types/core/engine/command/wait.d.ts.map +1 -1
- package/types/core/engine/commands.d.ts +296 -28
- package/types/core/engine/commands.d.ts.map +1 -1
- package/types/support/engineUtils.d.ts.map +1 -1
- package/types/support/getViewPort.d.ts.map +1 -1
- package/types/support/usbPower.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/addTextToVideo.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/getTimingMetrics.d.ts.map +1 -1
- package/types/video/postprocessing/finetune/index.d.ts.map +1 -1
- package/types/video/screenRecording/ios/iosDeviceRecorder.d.ts +28 -0
- package/types/video/screenRecording/ios/iosDeviceRecorder.d.ts.map +1 -0
- package/types/video/screenRecording/recorder.d.ts +2 -2
- package/types/video/screenRecording/recorder.d.ts.map +1 -1
- package/types/video/screenRecording/setOrangeBackground.d.ts.map +1 -1
- package/types/video/video.d.ts +1 -1
- package/types/video/video.d.ts.map +1 -1
- package/visualmetrics/visualmetrics-portable.py +136 -136
- package/lib/video/screenRecording/ios/convertToMp4.js +0 -22
- package/lib/video/screenRecording/ios/iosRecorder.js +0 -68
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import webdriver from 'selenium-webdriver';
|
|
1
2
|
import { getLogger } from '@sitespeed.io/log';
|
|
3
|
+
import { executeCommand } from './commandHelper.js';
|
|
4
|
+
import { parseSelector } from './selectorParser.js';
|
|
2
5
|
const log = getLogger('browsertime.command.select');
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -8,17 +11,100 @@ const log = getLogger('browsertime.command.select');
|
|
|
8
11
|
* @hideconstructor
|
|
9
12
|
*/
|
|
10
13
|
export class Select {
|
|
11
|
-
constructor(browser) {
|
|
14
|
+
constructor(browser, options) {
|
|
12
15
|
/**
|
|
13
16
|
* @private
|
|
14
17
|
*/
|
|
15
18
|
this.browser = browser;
|
|
19
|
+
/**
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
async _waitForElement(driver, locator) {
|
|
29
|
+
const timeout = this.options?.timeouts?.elementWait ?? 0;
|
|
30
|
+
if (timeout > 0) {
|
|
31
|
+
await driver.wait(webdriver.until.elementLocated(locator), timeout);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Selects an option in a select element using a unified selector string and a value.
|
|
37
|
+
* Supports CSS selectors (default), and prefix-based strategies:
|
|
38
|
+
* 'id:mySelect', 'name:country', 'class:dropdown'.
|
|
39
|
+
*
|
|
40
|
+
* @async
|
|
41
|
+
* @param {string} selector - The selector string for the select element.
|
|
42
|
+
* @param {string} value - The value of the option to select.
|
|
43
|
+
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
44
|
+
* @throws {Error} Throws an error if the select element is not found.
|
|
45
|
+
*/
|
|
46
|
+
async run(selector, value) {
|
|
47
|
+
const { locator, description } = parseSelector(selector);
|
|
48
|
+
return executeCommand(
|
|
49
|
+
log,
|
|
50
|
+
'Could not select value for %s',
|
|
51
|
+
description,
|
|
52
|
+
async () => {
|
|
53
|
+
const driver = this.browser.getDriver();
|
|
54
|
+
await this._waitForElement(driver, locator);
|
|
55
|
+
const element = await driver.findElement(locator);
|
|
56
|
+
await driver.executeScript(
|
|
57
|
+
`arguments[0].value = '${value}'; arguments[0].dispatchEvent(new Event('change'));`,
|
|
58
|
+
element
|
|
59
|
+
);
|
|
60
|
+
},
|
|
61
|
+
this.browser
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Selects an option in a select element by its visible text using a unified selector string.
|
|
67
|
+
*
|
|
68
|
+
* @async
|
|
69
|
+
* @param {string} selector - The selector string for the select element.
|
|
70
|
+
* @param {string} text - The visible text of the option to select.
|
|
71
|
+
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
72
|
+
* @throws {Error} Throws an error if the select element or option is not found.
|
|
73
|
+
*/
|
|
74
|
+
async runByText(selector, text) {
|
|
75
|
+
const { locator, description } = parseSelector(selector);
|
|
76
|
+
return executeCommand(
|
|
77
|
+
log,
|
|
78
|
+
'Could not select option by text for %s',
|
|
79
|
+
description,
|
|
80
|
+
async () => {
|
|
81
|
+
const driver = this.browser.getDriver();
|
|
82
|
+
await this._waitForElement(driver, locator);
|
|
83
|
+
const element = await driver.findElement(locator);
|
|
84
|
+
await driver.executeScript(
|
|
85
|
+
`const select = arguments[0];
|
|
86
|
+
const text = arguments[1];
|
|
87
|
+
for (const option of select.options) {
|
|
88
|
+
if (option.text === text || option.textContent.trim() === text) {
|
|
89
|
+
select.value = option.value;
|
|
90
|
+
select.dispatchEvent(new Event('change'));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
throw new Error('Option with text "' + text + '" not found');`,
|
|
95
|
+
element,
|
|
96
|
+
text
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
this.browser
|
|
100
|
+
);
|
|
16
101
|
}
|
|
17
102
|
|
|
18
103
|
/**
|
|
19
104
|
* Selects an option in a `<select>` element by its ID and the value of the option.
|
|
20
105
|
*
|
|
21
106
|
* @async
|
|
107
|
+
* @private
|
|
22
108
|
* @param {string} selectId - The ID of the `<select>` element.
|
|
23
109
|
* @param {string} value - The value of the option to select.
|
|
24
110
|
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
@@ -39,6 +125,7 @@ export class Select {
|
|
|
39
125
|
* Selects an option in a `<select>` element by its name and the value of the option.
|
|
40
126
|
*
|
|
41
127
|
* @async
|
|
128
|
+
* @private
|
|
42
129
|
* @param {string} selectName - The name of the `<select>` element.
|
|
43
130
|
* @param {string} value - The value of the option to select.
|
|
44
131
|
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
@@ -61,6 +148,7 @@ export class Select {
|
|
|
61
148
|
* Selects an option in a `<select>` element by its ID and the index of the option.
|
|
62
149
|
*
|
|
63
150
|
* @async
|
|
151
|
+
* @private
|
|
64
152
|
* @param {string} selectId - The ID of the `<select>` element.
|
|
65
153
|
* @param {number} index - The index of the option to select.
|
|
66
154
|
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
@@ -85,6 +173,7 @@ export class Select {
|
|
|
85
173
|
* Selects an option in a `<select>` element by its name and the index of the option.
|
|
86
174
|
*
|
|
87
175
|
* @async
|
|
176
|
+
* @private
|
|
88
177
|
* @param {string} selectName - The name of the `<select>` element.
|
|
89
178
|
* @param {number} index - The index of the option to select.
|
|
90
179
|
* @returns {Promise<void>} A promise that resolves when the option is selected.
|
|
@@ -109,6 +198,7 @@ export class Select {
|
|
|
109
198
|
* Deselects all options in a `<select>` element by its ID.
|
|
110
199
|
*
|
|
111
200
|
* @async
|
|
201
|
+
* @private
|
|
112
202
|
* @param {string} selectId - The ID of the `<select>` element.
|
|
113
203
|
* @returns {Promise<void>} A promise that resolves when all options are deselected.
|
|
114
204
|
* @throws {Error} Throws an error if the `<select>` element is not found.
|
|
@@ -119,9 +209,9 @@ export class Select {
|
|
|
119
209
|
const value = await this.browser.runScript(script, 'CUSTOM');
|
|
120
210
|
return value;
|
|
121
211
|
} catch (error) {
|
|
122
|
-
log.error('Could not
|
|
212
|
+
log.error('Could not deselect by select id %s', selectId);
|
|
123
213
|
log.verbose(error);
|
|
124
|
-
throw new Error(`Could not
|
|
214
|
+
throw new Error(`Could not deselect by select id ${selectId}`);
|
|
125
215
|
}
|
|
126
216
|
}
|
|
127
217
|
|
|
@@ -129,6 +219,7 @@ export class Select {
|
|
|
129
219
|
* Retrieves all option values in a `<select>` element by its ID.
|
|
130
220
|
*
|
|
131
221
|
* @async
|
|
222
|
+
* @private
|
|
132
223
|
* @param {string} selectId - The ID of the `<select>` element.
|
|
133
224
|
* @returns {Promise<string[]>} A promise that resolves with an array of the values of the options.
|
|
134
225
|
* @throws {Error} Throws an error if the `<select>` element is not found.
|
|
@@ -156,6 +247,7 @@ export class Select {
|
|
|
156
247
|
* Retrieves the value of the selected option in a `<select>` element by its ID.
|
|
157
248
|
*
|
|
158
249
|
* @async
|
|
250
|
+
* @private
|
|
159
251
|
* @param {string} selectId - The ID of the `<select>` element.
|
|
160
252
|
* @returns {Promise<string>} A promise that resolves with the value of the selected option.
|
|
161
253
|
* @throws {Error} Throws an error if the `<select>` element is not found.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { By } from 'selenium-webdriver';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses a selector string into a Selenium By locator.
|
|
5
|
+
* Supports prefix-based strategies:
|
|
6
|
+
* - 'id:value' -> By.id('value')
|
|
7
|
+
* - 'xpath:expression' -> By.xpath('expression')
|
|
8
|
+
* - 'name:value' -> By.name('value')
|
|
9
|
+
* - 'text:value' -> By.xpath('//*[normalize-space(text())="value"]')
|
|
10
|
+
* - 'link:value' -> By.xpath('//a[text()="value"]')
|
|
11
|
+
* - 'class:value' -> By.className('value')
|
|
12
|
+
* - No prefix -> By.css(selector) (CSS selector is the default)
|
|
13
|
+
*
|
|
14
|
+
* @param {string} selector - The selector string to parse.
|
|
15
|
+
* @returns {{ locator: By, description: string }} The parsed locator and a human-readable description.
|
|
16
|
+
*/
|
|
17
|
+
export function parseSelector(selector) {
|
|
18
|
+
const colonIndex = selector.indexOf(':');
|
|
19
|
+
if (colonIndex > 0) {
|
|
20
|
+
const prefix = selector.slice(0, colonIndex).toLowerCase();
|
|
21
|
+
const value = selector.slice(colonIndex + 1);
|
|
22
|
+
switch (prefix) {
|
|
23
|
+
case 'id': {
|
|
24
|
+
return { locator: By.id(value), description: `id ${value}` };
|
|
25
|
+
}
|
|
26
|
+
case 'xpath': {
|
|
27
|
+
return { locator: By.xpath(value), description: `xpath ${value}` };
|
|
28
|
+
}
|
|
29
|
+
case 'name': {
|
|
30
|
+
return { locator: By.name(value), description: `name ${value}` };
|
|
31
|
+
}
|
|
32
|
+
case 'text': {
|
|
33
|
+
return {
|
|
34
|
+
locator: By.xpath(`//*[normalize-space(text())='${value}']`),
|
|
35
|
+
description: `text ${value}`
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
case 'link': {
|
|
39
|
+
return {
|
|
40
|
+
locator: By.xpath(`//a[text()='${value}']`),
|
|
41
|
+
description: `link text ${value}`
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
case 'class': {
|
|
45
|
+
return {
|
|
46
|
+
locator: By.className(value),
|
|
47
|
+
description: `class ${value}`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
default: {
|
|
51
|
+
// Unknown prefix — treat entire string as CSS selector
|
|
52
|
+
return { locator: By.css(selector), description: `css ${selector}` };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// No prefix — CSS selector
|
|
57
|
+
return { locator: By.css(selector), description: `css ${selector}` };
|
|
58
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import webdriver from 'selenium-webdriver';
|
|
1
2
|
import { getLogger } from '@sitespeed.io/log';
|
|
3
|
+
import { executeCommand } from './commandHelper.js';
|
|
4
|
+
import { parseSelector } from './selectorParser.js';
|
|
2
5
|
const log = getLogger('browsertime.command.set');
|
|
3
6
|
|
|
4
7
|
/**
|
|
@@ -8,17 +11,63 @@ const log = getLogger('browsertime.command.set');
|
|
|
8
11
|
* @hideconstructor
|
|
9
12
|
*/
|
|
10
13
|
export class Set {
|
|
11
|
-
constructor(browser) {
|
|
14
|
+
constructor(browser, options) {
|
|
12
15
|
/**
|
|
13
16
|
* @private
|
|
14
17
|
*/
|
|
15
18
|
this.browser = browser;
|
|
19
|
+
/**
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
async _waitForElement(driver, locator) {
|
|
29
|
+
const timeout = this.options?.timeouts?.elementWait ?? 0;
|
|
30
|
+
if (timeout > 0) {
|
|
31
|
+
await driver.wait(webdriver.until.elementLocated(locator), timeout);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Sets a property on an element using a unified selector string.
|
|
37
|
+
* Supports CSS selectors (default), and prefix-based strategies:
|
|
38
|
+
* 'id:myId', 'xpath://input', 'name:field', 'class:input-field'.
|
|
39
|
+
*
|
|
40
|
+
* @async
|
|
41
|
+
* @param {string} selector - The selector string for the element.
|
|
42
|
+
* @param {string} value - The value to set.
|
|
43
|
+
* @param {string} [property='value'] - The property to set: 'value', 'innerText', or 'innerHTML'.
|
|
44
|
+
* @returns {Promise<void>} A promise that resolves when the property is set.
|
|
45
|
+
* @throws {Error} Throws an error if the element is not found.
|
|
46
|
+
*/
|
|
47
|
+
async run(selector, value, property = 'value') {
|
|
48
|
+
const { locator, description } = parseSelector(selector);
|
|
49
|
+
return executeCommand(
|
|
50
|
+
log,
|
|
51
|
+
`Could not set ${property} on %s`,
|
|
52
|
+
description,
|
|
53
|
+
async () => {
|
|
54
|
+
const driver = this.browser.getDriver();
|
|
55
|
+
await this._waitForElement(driver, locator);
|
|
56
|
+
const element = await driver.findElement(locator);
|
|
57
|
+
await driver.executeScript(
|
|
58
|
+
`arguments[0].${property} = '${value}';`,
|
|
59
|
+
element
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
this.browser
|
|
63
|
+
);
|
|
16
64
|
}
|
|
17
65
|
|
|
18
66
|
/**
|
|
19
67
|
* Sets the innerHTML of an element using a CSS selector.
|
|
20
68
|
*
|
|
21
69
|
* @async
|
|
70
|
+
* @private
|
|
22
71
|
* @param {string} html - The HTML string to set as innerHTML.
|
|
23
72
|
* @param {string} selector - The CSS selector of the element.
|
|
24
73
|
* @returns {Promise<void>} A promise that resolves when the innerHTML is set.
|
|
@@ -41,6 +90,7 @@ export class Set {
|
|
|
41
90
|
* Sets the innerHTML of an element using its ID.
|
|
42
91
|
*
|
|
43
92
|
* @async
|
|
93
|
+
* @private
|
|
44
94
|
* @param {string} html - The HTML string to set as innerHTML.
|
|
45
95
|
* @param {string} id - The ID of the element.
|
|
46
96
|
* @returns {Promise<void>} A promise that resolves when the innerHTML is set.
|
|
@@ -61,6 +111,7 @@ export class Set {
|
|
|
61
111
|
* Sets the innerText of an element using a CSS selector.
|
|
62
112
|
*
|
|
63
113
|
* @async
|
|
114
|
+
* @private
|
|
64
115
|
* @param {string} text - The text to set as innerText.
|
|
65
116
|
* @param {string} selector - The CSS selector of the element.
|
|
66
117
|
* @returns {Promise<void>} A promise that resolves when the innerText is set.
|
|
@@ -83,6 +134,7 @@ export class Set {
|
|
|
83
134
|
* Sets the innerText of an element using its ID.
|
|
84
135
|
*
|
|
85
136
|
* @async
|
|
137
|
+
* @private
|
|
86
138
|
* @param {string} text - The text to set as innerText.
|
|
87
139
|
* @param {string} id - The ID of the element.
|
|
88
140
|
* @returns {Promise<void>} A promise that resolves when the innerText is set.
|
|
@@ -103,6 +155,7 @@ export class Set {
|
|
|
103
155
|
* Sets the value of an element using a CSS selector.
|
|
104
156
|
*
|
|
105
157
|
* @async
|
|
158
|
+
* @private
|
|
106
159
|
* @param {string} value - The value to set on the element.
|
|
107
160
|
* @param {string} selector - The CSS selector of the element.
|
|
108
161
|
* @returns {Promise<void>} A promise that resolves when the value is set.
|
|
@@ -123,6 +176,7 @@ export class Set {
|
|
|
123
176
|
* Sets the value of an element using its ID.
|
|
124
177
|
*
|
|
125
178
|
* @async
|
|
179
|
+
* @private
|
|
126
180
|
* @param {string} value - The value to set on the element.
|
|
127
181
|
* @param {string} id - The ID of the element.
|
|
128
182
|
* @returns {Promise<void>} A promise that resolves when the value is set.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import webdriver from 'selenium-webdriver';
|
|
2
2
|
import { getLogger } from '@sitespeed.io/log';
|
|
3
|
+
import { executeCommand } from './commandHelper.js';
|
|
4
|
+
import { parseSelector } from './selectorParser.js';
|
|
3
5
|
const log = getLogger('browsertime.command.wait');
|
|
4
6
|
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
5
7
|
|
|
@@ -25,6 +27,7 @@ export class Wait {
|
|
|
25
27
|
* Waits for an element with a specific ID to be located within a maximum time.
|
|
26
28
|
*
|
|
27
29
|
* @async
|
|
30
|
+
* @private
|
|
28
31
|
* @param {string} id - The ID of the element to wait for.
|
|
29
32
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
30
33
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -50,6 +53,7 @@ export class Wait {
|
|
|
50
53
|
* Waits for an element with a specific ID to be located and visible within a maximum time.
|
|
51
54
|
*
|
|
52
55
|
* @async
|
|
56
|
+
* @private
|
|
53
57
|
* @param {string} id - The ID of the element to wait for.
|
|
54
58
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
55
59
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -59,7 +63,6 @@ export class Wait {
|
|
|
59
63
|
const driver = this.browser.getDriver();
|
|
60
64
|
await this.byId(id, maxTime);
|
|
61
65
|
try {
|
|
62
|
-
driver.findElement;
|
|
63
66
|
await driver.wait(
|
|
64
67
|
webdriver.until.elementIsVisible(
|
|
65
68
|
driver.findElement(webdriver.By.id(id))
|
|
@@ -77,6 +80,7 @@ export class Wait {
|
|
|
77
80
|
* Waits for an element located by XPath to appear within a maximum time.
|
|
78
81
|
*
|
|
79
82
|
* @async
|
|
83
|
+
* @private
|
|
80
84
|
* @param {string} xpath - The XPath of the element to wait for.
|
|
81
85
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
82
86
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -104,6 +108,7 @@ export class Wait {
|
|
|
104
108
|
* Waits for an element located by XPath to appear and visible within a maximum time.
|
|
105
109
|
*
|
|
106
110
|
* @async
|
|
111
|
+
* @private
|
|
107
112
|
* @param {string} xpath - The XPath of the element to wait for.
|
|
108
113
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
109
114
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -113,7 +118,6 @@ export class Wait {
|
|
|
113
118
|
const driver = this.browser.getDriver();
|
|
114
119
|
await this.byXpath(xpath, maxTime);
|
|
115
120
|
try {
|
|
116
|
-
driver.findElement;
|
|
117
121
|
await driver.wait(
|
|
118
122
|
webdriver.until.elementIsVisible(
|
|
119
123
|
driver.findElement(webdriver.By.xpath(xpath))
|
|
@@ -133,6 +137,7 @@ export class Wait {
|
|
|
133
137
|
* Waits for an element located by a CSS selector to appear within a maximum time.
|
|
134
138
|
*
|
|
135
139
|
* @async
|
|
140
|
+
* @private
|
|
136
141
|
* @param {string} selector - The CSS selector of the element to wait for.
|
|
137
142
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
138
143
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -164,6 +169,7 @@ export class Wait {
|
|
|
164
169
|
* Waits for an element located by a CSS selector to be visible within a maximum time.
|
|
165
170
|
*
|
|
166
171
|
* @async
|
|
172
|
+
* @private
|
|
167
173
|
* @param {string} selector - The CSS selector of the element to wait for.
|
|
168
174
|
* @param {number} maxTime - Maximum time to wait in milliseconds.
|
|
169
175
|
* @returns {Promise<void>} A promise that resolves when the element is found or the time times out.
|
|
@@ -214,6 +220,39 @@ export class Wait {
|
|
|
214
220
|
return this.browser.extraWait(this.pageCompleteCheck);
|
|
215
221
|
}
|
|
216
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Waits for an element using a unified selector string to appear within a maximum time.
|
|
225
|
+
* Supports CSS selectors (default), and prefix-based strategies:
|
|
226
|
+
* 'id:myId', 'xpath://div', 'name:field', 'class:loaded'.
|
|
227
|
+
*
|
|
228
|
+
* @async
|
|
229
|
+
* @param {string} selector - The selector string. CSS by default, or use a prefix.
|
|
230
|
+
* @param {Object} [options] - Options for waiting.
|
|
231
|
+
* @param {number} [options.timeout=6000] - Maximum time to wait in milliseconds.
|
|
232
|
+
* @param {boolean} [options.visible=false] - If true, waits for the element to be visible, not just present.
|
|
233
|
+
* @returns {Promise<void>} A promise that resolves when the element is found.
|
|
234
|
+
* @throws {Error} Throws an error if the element is not found within the timeout.
|
|
235
|
+
*/
|
|
236
|
+
async run(selector, options = {}) {
|
|
237
|
+
const timeout = options.timeout ?? 6000;
|
|
238
|
+
const visible = options.visible ?? false;
|
|
239
|
+
const { locator, description } = parseSelector(selector);
|
|
240
|
+
return executeCommand(
|
|
241
|
+
log,
|
|
242
|
+
'Element %s was not located in ' + timeout + ' ms',
|
|
243
|
+
description,
|
|
244
|
+
async () => {
|
|
245
|
+
const driver = this.browser.getDriver();
|
|
246
|
+
await driver.wait(webdriver.until.elementLocated(locator), timeout);
|
|
247
|
+
if (visible) {
|
|
248
|
+
const element = await driver.findElement(locator);
|
|
249
|
+
await driver.wait(webdriver.until.elementIsVisible(element), timeout);
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
this.browser
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
217
256
|
/**
|
|
218
257
|
* Waits for a JavaScript condition to return a truthy value within a maximum time.
|
|
219
258
|
*
|