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.
Files changed (105) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +1 -1
  3. package/browserscripts/timings/softNavigations.js +94 -0
  4. package/lib/chrome/har.js +36 -5
  5. package/lib/chrome/settings/chromeAndroidOptions.js +2 -1
  6. package/lib/chrome/webdriver/chromium.js +40 -1
  7. package/lib/chrome/webdriver/setupChromiumOptions.js +86 -31
  8. package/lib/core/engine/collector.js +340 -317
  9. package/lib/core/engine/command/addText.js +93 -12
  10. package/lib/core/engine/command/click.js +268 -139
  11. package/lib/core/engine/command/commandHelper.js +45 -0
  12. package/lib/core/engine/command/cookie.js +85 -0
  13. package/lib/core/engine/command/element.js +37 -2
  14. package/lib/core/engine/command/javaScript.js +14 -24
  15. package/lib/core/engine/command/measure/screenshots.js +114 -0
  16. package/lib/core/engine/command/measure/video.js +85 -0
  17. package/lib/core/engine/command/measure.js +104 -180
  18. package/lib/core/engine/command/mouse/clickAndHold.js +6 -3
  19. package/lib/core/engine/command/mouse/contextClick.js +56 -4
  20. package/lib/core/engine/command/mouse/doubleClick.js +49 -1
  21. package/lib/core/engine/command/mouse/mouseMove.js +50 -1
  22. package/lib/core/engine/command/mouse/singleClick.js +165 -129
  23. package/lib/core/engine/command/navigation.js +6 -6
  24. package/lib/core/engine/command/select.js +95 -3
  25. package/lib/core/engine/command/selectorParser.js +58 -0
  26. package/lib/core/engine/command/set.js +55 -1
  27. package/lib/core/engine/command/wait.js +41 -2
  28. package/lib/core/engine/commands.js +550 -42
  29. package/lib/core/engine/index.js +206 -150
  30. package/lib/core/engine/iteration.js +277 -137
  31. package/lib/firefox/networkManager.js +22 -30
  32. package/lib/firefox/webdriver/builder.js +14 -0
  33. package/lib/safari/har.js +131 -0
  34. package/lib/safari/native/ios-capture +0 -0
  35. package/lib/safari/native/ios-capture.m +340 -0
  36. package/lib/safari/safariInspectorClient.js +322 -0
  37. package/lib/safari/webdriver/safari.js +303 -13
  38. package/lib/safari/webkitToCdpAdapter.js +241 -0
  39. package/lib/support/cli.js +13 -0
  40. package/lib/support/engineUtils.js +16 -5
  41. package/lib/support/getViewPort.js +5 -0
  42. package/lib/support/har/index.js +41 -3
  43. package/lib/support/usbPower.js +2 -3
  44. package/lib/video/postprocessing/finetune/addTextToVideo.js +4 -0
  45. package/lib/video/postprocessing/finetune/getFont.js +3 -3
  46. package/lib/video/postprocessing/finetune/getTimingMetrics.js +7 -0
  47. package/lib/video/postprocessing/finetune/index.js +26 -9
  48. package/lib/video/screenRecording/ios/iosDeviceRecorder.js +109 -0
  49. package/lib/video/screenRecording/recorder.js +2 -2
  50. package/lib/video/screenRecording/setOrangeBackground.js +3 -0
  51. package/package.json +11 -11
  52. package/types/core/engine/command/addText.d.ts +35 -6
  53. package/types/core/engine/command/addText.d.ts.map +1 -1
  54. package/types/core/engine/command/click.d.ts +87 -16
  55. package/types/core/engine/command/click.d.ts.map +1 -1
  56. package/types/core/engine/command/commandHelper.d.ts +16 -0
  57. package/types/core/engine/command/commandHelper.d.ts.map +1 -0
  58. package/types/core/engine/command/cookie.d.ts +65 -0
  59. package/types/core/engine/command/cookie.d.ts.map +1 -0
  60. package/types/core/engine/command/element.d.ts +19 -1
  61. package/types/core/engine/command/element.d.ts.map +1 -1
  62. package/types/core/engine/command/javaScript.d.ts +4 -0
  63. package/types/core/engine/command/javaScript.d.ts.map +1 -1
  64. package/types/core/engine/command/measure/screenshots.d.ts +15 -0
  65. package/types/core/engine/command/measure/screenshots.d.ts.map +1 -0
  66. package/types/core/engine/command/measure/video.d.ts +26 -0
  67. package/types/core/engine/command/measure/video.d.ts.map +1 -0
  68. package/types/core/engine/command/measure.d.ts +59 -33
  69. package/types/core/engine/command/measure.d.ts.map +1 -1
  70. package/types/core/engine/command/mouse/clickAndHold.d.ts.map +1 -1
  71. package/types/core/engine/command/mouse/contextClick.d.ts +28 -4
  72. package/types/core/engine/command/mouse/contextClick.d.ts.map +1 -1
  73. package/types/core/engine/command/mouse/doubleClick.d.ts +24 -4
  74. package/types/core/engine/command/mouse/doubleClick.d.ts.map +1 -1
  75. package/types/core/engine/command/mouse/mouseMove.d.ts +30 -5
  76. package/types/core/engine/command/mouse/mouseMove.d.ts.map +1 -1
  77. package/types/core/engine/command/mouse/singleClick.d.ts +50 -13
  78. package/types/core/engine/command/mouse/singleClick.d.ts.map +1 -1
  79. package/types/core/engine/command/navigation.d.ts +3 -3
  80. package/types/core/engine/command/select.d.ts +45 -8
  81. package/types/core/engine/command/select.d.ts.map +1 -1
  82. package/types/core/engine/command/selectorParser.d.ts +20 -0
  83. package/types/core/engine/command/selectorParser.d.ts.map +1 -0
  84. package/types/core/engine/command/set.d.ts +34 -7
  85. package/types/core/engine/command/set.d.ts.map +1 -1
  86. package/types/core/engine/command/wait.d.ts +29 -6
  87. package/types/core/engine/command/wait.d.ts.map +1 -1
  88. package/types/core/engine/commands.d.ts +296 -28
  89. package/types/core/engine/commands.d.ts.map +1 -1
  90. package/types/support/engineUtils.d.ts.map +1 -1
  91. package/types/support/getViewPort.d.ts.map +1 -1
  92. package/types/support/usbPower.d.ts.map +1 -1
  93. package/types/video/postprocessing/finetune/addTextToVideo.d.ts.map +1 -1
  94. package/types/video/postprocessing/finetune/getTimingMetrics.d.ts.map +1 -1
  95. package/types/video/postprocessing/finetune/index.d.ts.map +1 -1
  96. package/types/video/screenRecording/ios/iosDeviceRecorder.d.ts +28 -0
  97. package/types/video/screenRecording/ios/iosDeviceRecorder.d.ts.map +1 -0
  98. package/types/video/screenRecording/recorder.d.ts +2 -2
  99. package/types/video/screenRecording/recorder.d.ts.map +1 -1
  100. package/types/video/screenRecording/setOrangeBackground.d.ts.map +1 -1
  101. package/types/video/video.d.ts +1 -1
  102. package/types/video/video.d.ts.map +1 -1
  103. package/visualmetrics/visualmetrics-portable.py +136 -136
  104. package/lib/video/screenRecording/ios/convertToMp4.js +0 -22
  105. package/lib/video/screenRecording/ios/iosRecorder.js +0 -68
@@ -1,5 +1,8 @@
1
1
  import { getLogger } from '@sitespeed.io/log';
2
2
  import { By, Origin } from 'selenium-webdriver';
3
+ import webdriver from 'selenium-webdriver';
4
+ import { executeCommand } from '../commandHelper.js';
5
+ import { parseSelector } from '../selectorParser.js';
3
6
  const log = getLogger('browsertime.command.mouse');
4
7
  /**
5
8
  * Provides functionality to move the mouse cursor to elements or specific positions on a web page.
@@ -8,7 +11,11 @@ const log = getLogger('browsertime.command.mouse');
8
11
  * @hideconstructor
9
12
  */
10
13
  export class MouseMove {
11
- constructor(browser) {
14
+ constructor(browser, options) {
15
+ /**
16
+ * @private
17
+ */
18
+ this.browser = browser;
12
19
  /**
13
20
  * @private
14
21
  */
@@ -17,9 +24,48 @@ export class MouseMove {
17
24
  * @private
18
25
  */
19
26
  this.actions = this.driver.actions({ async: true });
27
+ /**
28
+ * @private
29
+ */
30
+ this.options = options;
31
+ }
32
+
33
+ /**
34
+ * @private
35
+ */
36
+ async _waitForElement(driver, locator) {
37
+ const timeout = this.options?.timeouts?.elementWait ?? 0;
38
+ if (timeout > 0) {
39
+ await driver.wait(webdriver.until.elementLocated(locator), timeout);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Moves the mouse cursor to an element using a unified selector string.
45
+ *
46
+ * @async
47
+ * @param {string} selector - The selector string. CSS by default, or use a prefix.
48
+ * @returns {Promise<void>}
49
+ * @throws {Error} Throws an error if the element is not found.
50
+ */
51
+ async run(selector) {
52
+ const { locator, description } = parseSelector(selector);
53
+ return executeCommand(
54
+ log,
55
+ 'Could not move mouse to element %s',
56
+ description,
57
+ async () => {
58
+ const driver = this.browser.getDriver();
59
+ await this._waitForElement(driver, locator);
60
+ const element = await driver.findElement(locator);
61
+ return this.actions.move({ origin: element }).perform();
62
+ },
63
+ this.browser
64
+ );
20
65
  }
21
66
 
22
67
  /**
68
+ * @private
23
69
  * Moves the mouse cursor to an element that matches a given XPath selector.
24
70
  *
25
71
  * @async
@@ -39,6 +85,7 @@ export class MouseMove {
39
85
  }
40
86
 
41
87
  /**
88
+ * @private
42
89
  * Moves the mouse cursor to an element that matches a given CSS selector.
43
90
  *
44
91
  * @async
@@ -58,6 +105,7 @@ export class MouseMove {
58
105
  }
59
106
 
60
107
  /**
108
+ * @private
61
109
  * Moves the mouse cursor to a specific position on the screen.
62
110
  *
63
111
  * @async
@@ -77,6 +125,7 @@ export class MouseMove {
77
125
  }
78
126
 
79
127
  /**
128
+ * @private
80
129
  * Moves the mouse cursor by an offset from its current position.
81
130
  *
82
131
  * @async
@@ -1,5 +1,8 @@
1
1
  import { getLogger } from '@sitespeed.io/log';
2
2
  import { By } from 'selenium-webdriver';
3
+ import webdriver from 'selenium-webdriver';
4
+ import { executeCommand } from '../commandHelper.js';
5
+ import { parseSelector } from '../selectorParser.js';
3
6
  const log = getLogger('browsertime.command.mouse');
4
7
 
5
8
  /**
@@ -9,7 +12,7 @@ const log = getLogger('browsertime.command.mouse');
9
12
  * @class
10
13
  */
11
14
  export class SingleClick {
12
- constructor(browser, pageCompleteCheck) {
15
+ constructor(browser, pageCompleteCheck, options) {
13
16
  /**
14
17
  * @private
15
18
  */
@@ -22,9 +25,62 @@ export class SingleClick {
22
25
  * @private
23
26
  */
24
27
  this.pageCompleteCheck = pageCompleteCheck;
28
+ /**
29
+ * @private
30
+ */
31
+ this.options = options;
32
+ }
33
+
34
+ /**
35
+ * @private
36
+ */
37
+ async _waitForElement(driver, locator) {
38
+ const timeout = this.options?.timeouts?.elementWait ?? 0;
39
+ if (timeout > 0) {
40
+ await driver.wait(webdriver.until.elementLocated(locator), timeout);
41
+ }
25
42
  }
26
43
 
27
44
  /**
45
+ * Performs a single click on an element using a unified selector string.
46
+ *
47
+ * @async
48
+ * @param {string} selector - The selector string. CSS by default, or use a prefix.
49
+ * @param {Object} [options] - Options for the click action.
50
+ * @param {boolean} [options.waitForNavigation=false] - If true, waits for page complete check.
51
+ * @returns {Promise<void>}
52
+ * @throws {Error} Throws an error if the element is not found.
53
+ */
54
+ async run(selector, options = {}) {
55
+ const { locator, description } = parseSelector(selector);
56
+ return executeCommand(
57
+ log,
58
+ 'Could not single click on element %s',
59
+ description,
60
+ async () => {
61
+ const driver = this.browser.getDriver();
62
+ await this._waitForElement(driver, locator);
63
+ const element = await driver.findElement(locator);
64
+ await this.actions.click(element).perform();
65
+ await this.actions.clear();
66
+ if (options.waitForNavigation) {
67
+ await this.browser.extraWait(this.pageCompleteCheck);
68
+ }
69
+ },
70
+ this.browser
71
+ );
72
+ }
73
+
74
+ /**
75
+ * @private
76
+ */
77
+ async _andWait(baseMethod, ...args) {
78
+ await baseMethod.apply(this, args);
79
+ return this.browser.extraWait(this.pageCompleteCheck);
80
+ }
81
+
82
+ /**
83
+ * @private
28
84
  * Performs a single mouse click on an element matching a given XPath selector.
29
85
  *
30
86
  * @async
@@ -34,25 +90,29 @@ export class SingleClick {
34
90
  * @throws {Error} Throws an error if the element is not found.
35
91
  */
36
92
  async byXpath(xpath, options) {
37
- try {
38
- const element = await this.browser
39
- .getDriver()
40
- .findElement(By.xpath(xpath));
41
- await this.actions.click(element).perform();
42
- if (options && 'wait' in options && options.wait === true) {
43
- log.warn(
44
- 'Please use the byXpathAndWait method instead. We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
45
- );
46
- return this.browser.extraWait(this.pageCompleteCheck);
47
- }
48
- } catch (error) {
49
- log.error('Could not single click on element with xpath %s', xpath);
50
- log.verbose(error);
51
- throw new Error('Could not single click on element with xpath ' + xpath);
52
- }
93
+ return executeCommand(
94
+ log,
95
+ 'Could not single click on element with xpath %s',
96
+ xpath,
97
+ async () => {
98
+ const element = await this.browser
99
+ .getDriver()
100
+ .findElement(By.xpath(xpath));
101
+ await this.actions.click(element).perform();
102
+ await this.actions.clear();
103
+ if (options && 'wait' in options && options.wait === true) {
104
+ log.warn(
105
+ 'Please use the byXpathAndWait method instead. We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
106
+ );
107
+ return this.browser.extraWait(this.pageCompleteCheck);
108
+ }
109
+ },
110
+ this.browser
111
+ );
53
112
  }
54
113
 
55
114
  /**
115
+ * @private
56
116
  * Performs a single mouse click on an element matching a given XPath selector and wait for page complete check.
57
117
  *
58
118
  * @async
@@ -61,20 +121,11 @@ export class SingleClick {
61
121
  * @throws {Error} Throws an error if the element is not found.
62
122
  */
63
123
  async byXpathAndWait(xpath) {
64
- try {
65
- const element = await this.browser
66
- .getDriver()
67
- .findElement(By.xpath(xpath));
68
- await this.actions.click(element).perform();
69
- return this.browser.extraWait(this.pageCompleteCheck);
70
- } catch (error) {
71
- log.error('Could not single click on element with xpath %s', xpath);
72
- log.verbose(error);
73
- throw new Error('Could not single click on element with xpath ' + xpath);
74
- }
124
+ return this._andWait(this.byXpath, xpath);
75
125
  }
76
126
 
77
127
  /**
128
+ * @private
78
129
  * Performs a single mouse click on an element matching a given CSS selector.
79
130
  *
80
131
  * @async
@@ -84,27 +135,29 @@ export class SingleClick {
84
135
  * @throws {Error} Throws an error if the element is not found.
85
136
  */
86
137
  async bySelector(selector, options) {
87
- try {
88
- const element = await this.browser
89
- .getDriver()
90
- .findElement(By.css(selector));
91
- await this.actions.click(element).perform();
92
- if (options && 'wait' in options && options.wait === true) {
93
- log.warn(
94
- 'Please use the bySelectorAndWait method instead. We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
95
- );
96
- return this.browser.extraWait(this.pageCompleteCheck);
97
- }
98
- } catch (error) {
99
- log.error('Could not single click on element with selector %s', selector);
100
- log.verbose(error);
101
- throw new Error(
102
- 'Could not single click on element with selector ' + selector
103
- );
104
- }
138
+ return executeCommand(
139
+ log,
140
+ 'Could not single click on element with selector %s',
141
+ selector,
142
+ async () => {
143
+ const element = await this.browser
144
+ .getDriver()
145
+ .findElement(By.css(selector));
146
+ await this.actions.click(element).perform();
147
+ await this.actions.clear();
148
+ if (options && 'wait' in options && options.wait === true) {
149
+ log.warn(
150
+ 'Please use the bySelectorAndWait method instead. We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
151
+ );
152
+ return this.browser.extraWait(this.pageCompleteCheck);
153
+ }
154
+ },
155
+ this.browser
156
+ );
105
157
  }
106
158
 
107
159
  /**
160
+ * @private
108
161
  * Performs a single mouse click on an element matching a given CSS selector and waits on the page complete check.
109
162
  *
110
163
  * @async
@@ -113,22 +166,11 @@ export class SingleClick {
113
166
  * @throws {Error} Throws an error if the element is not found.
114
167
  */
115
168
  async bySelectorAndWait(selector) {
116
- try {
117
- const element = await this.browser
118
- .getDriver()
119
- .findElement(By.css(selector));
120
- await this.actions.click(element).perform();
121
- return this.browser.extraWait(this.pageCompleteCheck);
122
- } catch (error) {
123
- log.error('Could not single click on element with selector %s', selector);
124
- log.verbose(error);
125
- throw new Error(
126
- 'Could not single click on element with selector ' + selector
127
- );
128
- }
169
+ return this._andWait(this.bySelector, selector);
129
170
  }
130
171
 
131
172
  /**
173
+ * @private
132
174
  * Performs a single mouse click at the current cursor position.
133
175
  *
134
176
  * @async
@@ -137,22 +179,26 @@ export class SingleClick {
137
179
  * @throws {Error} Throws an error if the single click action cannot be performed.
138
180
  */
139
181
  async atCursor(options) {
140
- try {
141
- await this.actions.click().perform();
142
- if (options && 'wait' in options && options.wait === true) {
143
- log.warn(
144
- 'Please use the atCursorAndWait method instead.We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
145
- );
146
- return this.browser.extraWait(this.pageCompleteCheck);
147
- }
148
- } catch (error) {
149
- log.error('Could not perform single click');
150
- log.verbose(error);
151
- throw new Error('Could not perform single click');
152
- }
182
+ return executeCommand(
183
+ log,
184
+ 'Could not perform single click',
185
+ undefined,
186
+ async () => {
187
+ await this.actions.click().perform();
188
+ await this.actions.clear();
189
+ if (options && 'wait' in options && options.wait === true) {
190
+ log.warn(
191
+ 'Please use the atCursorAndWait method instead.We want to deprecate and remove the options from this method so we follow the same pattern everywhere.'
192
+ );
193
+ return this.browser.extraWait(this.pageCompleteCheck);
194
+ }
195
+ },
196
+ this.browser
197
+ );
153
198
  }
154
199
 
155
200
  /**
201
+ * @private
156
202
  * Performs a single mouse click at the current cursor position and waits on the
157
203
  * page complete check.
158
204
  *
@@ -161,17 +207,11 @@ export class SingleClick {
161
207
  * @throws {Error} Throws an error if the single click action cannot be performed.
162
208
  */
163
209
  async atCursorAndWait() {
164
- try {
165
- await this.actions.click().perform();
166
- return this.browser.extraWait(this.pageCompleteCheck);
167
- } catch (error) {
168
- log.error('Could not perform single click');
169
- log.verbose(error);
170
- throw new Error('Could not perform single click');
171
- }
210
+ return this._andWait(this.atCursor);
172
211
  }
173
212
 
174
213
  /**
214
+ * @private
175
215
  * Clicks on a link whose visible text matches the given string.
176
216
  *
177
217
  * @async
@@ -180,17 +220,17 @@ export class SingleClick {
180
220
  * @throws {Error} Throws an error if the link is not found.
181
221
  */
182
222
  async byLinkText(text) {
183
- try {
184
- const xpath = `//a[text()='${text}']`;
185
- return this.byXpath(xpath);
186
- } catch (error) {
187
- log.error('Could not find link by text %s', text);
188
- log.verbose(error);
189
- throw new Error('Could not find link by text ' + text);
190
- }
223
+ return executeCommand(
224
+ log,
225
+ 'Could not find link by text %s',
226
+ text,
227
+ () => this.byXpath(`//a[text()='${text}']`),
228
+ this.browser
229
+ );
191
230
  }
192
231
 
193
232
  /**
233
+ * @private
194
234
  * Clicks on a link whose visible text matches the given string and waits on the opage complete check.
195
235
  *
196
236
  * @async
@@ -199,17 +239,17 @@ export class SingleClick {
199
239
  * @throws {Error} Throws an error if the link is not found.
200
240
  */
201
241
  async byLinkTextAndWait(text) {
202
- try {
203
- const xpath = `//a[text()='${text}']`;
204
- return this.byXpathAndWait(xpath);
205
- } catch (error) {
206
- log.error('Could not find link by text %s', text);
207
- log.verbose(error);
208
- throw new Error('Could not find link by text ' + text);
209
- }
242
+ return executeCommand(
243
+ log,
244
+ 'Could not find link by text %s',
245
+ text,
246
+ () => this.byXpathAndWait(`//a[text()='${text}']`),
247
+ this.browser
248
+ );
210
249
  }
211
250
 
212
251
  /**
252
+ * @private
213
253
  * Clicks on a link whose visible text contains the given substring.
214
254
  *
215
255
  * @async
@@ -218,17 +258,17 @@ export class SingleClick {
218
258
  * @throws {Error} Throws an error if the link is not found.
219
259
  */
220
260
  async byPartialLinkText(text) {
221
- try {
222
- const xpath = `//a[contains(text(),'${text}')]`;
223
- return this.byXpath(xpath);
224
- } catch (error) {
225
- log.error('Could not find link by partial text %s', text);
226
- log.verbose(error);
227
- throw new Error('Could not find link by partial text ' + text);
228
- }
261
+ return executeCommand(
262
+ log,
263
+ 'Could not find link by partial text %s',
264
+ text,
265
+ () => this.byXpath(`//a[contains(text(),'${text}')]`),
266
+ this.browser
267
+ );
229
268
  }
230
269
 
231
270
  /**
271
+ * @private
232
272
  * Clicks on a link whose visible text contains the given substring and waits on the
233
273
  * page complete check.
234
274
  *
@@ -238,17 +278,17 @@ export class SingleClick {
238
278
  * @throws {Error} Throws an error if the link is not found.
239
279
  */
240
280
  async byPartialLinkTextAndWait(text) {
241
- try {
242
- const xpath = `//a[contains(text(),'${text}')]`;
243
- return this.byXpathAndWait(xpath);
244
- } catch (error) {
245
- log.error('Could not find link by partial text %s', text);
246
- log.verbose(error);
247
- throw new Error('Could not find link by partial text ' + text);
248
- }
281
+ return executeCommand(
282
+ log,
283
+ 'Could not find link by partial text %s',
284
+ text,
285
+ () => this.byXpathAndWait(`//a[contains(text(),'${text}')]`),
286
+ this.browser
287
+ );
249
288
  }
250
289
 
251
290
  /**
291
+ * @private
252
292
  * Clicks on a element with a specific id.
253
293
  *
254
294
  * @async
@@ -257,17 +297,21 @@ export class SingleClick {
257
297
  * @throws {Error} Throws an error if the id is not found.
258
298
  */
259
299
  async byId(id) {
260
- try {
261
- const element = await this.browser.getDriver().findElement(By.id(id));
262
- return this.actions.click(element).perform();
263
- } catch (error) {
264
- log.error('Could not find the element with id %s', id);
265
- log.verbose(error);
266
- throw new Error('Could not the element with id ' + id);
267
- }
300
+ return executeCommand(
301
+ log,
302
+ 'Could not find the element with id %s',
303
+ id,
304
+ async () => {
305
+ const element = await this.browser.getDriver().findElement(By.id(id));
306
+ await this.actions.click(element).perform();
307
+ return this.actions.clear();
308
+ },
309
+ this.browser
310
+ );
268
311
  }
269
312
 
270
313
  /**
314
+ * @private
271
315
  * Clicks on a element with a specific id and wait on the page complete check
272
316
  *
273
317
  * @async
@@ -276,14 +320,6 @@ export class SingleClick {
276
320
  * @throws {Error} Throws an error if the id is not found.
277
321
  */
278
322
  async byIdAndWait(id) {
279
- try {
280
- const element = await this.browser.getDriver().findElement(By.id(id));
281
- await this.actions.click(element).perform();
282
- return this.browser.extraWait(this.pageCompleteCheck);
283
- } catch (error) {
284
- log.error('Could not find the element with id %s', id);
285
- log.verbose(error);
286
- throw new Error('Could not the element with id ' + id);
287
- }
323
+ return this._andWait(this.byId, id);
288
324
  }
289
325
  }
@@ -25,7 +25,7 @@ export class Navigation {
25
25
  *
26
26
  * @async
27
27
  * @example await commands.navigation.back();
28
- * @param {Object} [options] - Additional options for navigation. Set {wait:true} to wait for the page complete check to run.
28
+ * @param {Object} [options] - Additional options for navigation. Set {waitForNavigation:true} to wait for the page complete check to run.
29
29
  * @returns {Promise<void>} A promise that resolves when the navigation action is completed.
30
30
  * @throws {Error} Throws an error if navigation fails.
31
31
  */
@@ -33,7 +33,7 @@ export class Navigation {
33
33
  const driver = this.browser.getDriver();
34
34
  try {
35
35
  await driver.navigate().back();
36
- if (options && 'wait' in options && options.wait == true) {
36
+ if (options && (options.waitForNavigation || options.wait)) {
37
37
  return this.browser.extraWait(this.pageCompleteCheck);
38
38
  }
39
39
  } catch (error) {
@@ -48,7 +48,7 @@ export class Navigation {
48
48
  *
49
49
  * @async
50
50
  * @example await commands.navigation.forward();
51
- * @param {Object} [options] - Additional options for navigation. Set {wait:true} to wait for the page complete check to run.
51
+ * @param {Object} [options] - Additional options for navigation. Set {waitForNavigation:true} to wait for the page complete check to run.
52
52
  * @returns {Promise<void>} A promise that resolves when the navigation action is completed.
53
53
  * @throws {Error} Throws an error if navigation fails.
54
54
  */
@@ -56,7 +56,7 @@ export class Navigation {
56
56
  const driver = this.browser.getDriver();
57
57
  try {
58
58
  await driver.navigate().forward();
59
- if (options && 'wait' in options && options.wait === true) {
59
+ if (options && (options.waitForNavigation || options.wait)) {
60
60
  return this.browser.extraWait(this.pageCompleteCheck);
61
61
  }
62
62
  } catch (error) {
@@ -71,7 +71,7 @@ export class Navigation {
71
71
  *
72
72
  * @async
73
73
  * @example await commands.navigation.refresh();
74
- * @param {Object} [options] - Additional options for refresh action. Set {wait:true} to wait for the page complete check to run.
74
+ * @param {Object} [options] - Additional options for refresh action. Set {waitForNavigation:true} to wait for the page complete check to run.
75
75
  * @returns {Promise<void>} A promise that resolves when the page has been refreshed.
76
76
  * @throws {Error} Throws an error if refreshing the page fails.
77
77
  */
@@ -79,7 +79,7 @@ export class Navigation {
79
79
  const driver = this.browser.getDriver();
80
80
  try {
81
81
  await driver.navigate().refresh();
82
- if (options && 'wait' in options && options.wait === true) {
82
+ if (options && (options.waitForNavigation || options.wait)) {
83
83
  return this.browser.extraWait(this.pageCompleteCheck);
84
84
  }
85
85
  } catch (error) {