codeceptjs 3.5.11 → 3.5.12-beta.2

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.
@@ -63,6 +63,8 @@ const webRoot = 'body';
63
63
  * @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriver"]._startBrowser()`.
64
64
  * @prop {object} [timeouts] [WebDriver timeouts](http://webdriver.io/docs/timeouts.html) defined as hash.
65
65
  * @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
66
+ * @prop {string} [logLevel=silent] - level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: https://webdriver.io/docs/configuration/#loglevel
67
+ * @prop {boolean} [devtoolsProtocol=false] - enable devtools protocol. Default: false. More info: https://webdriver.io/docs/automationProtocols/#devtools-protocol.
66
68
  */
67
69
  const config = {};
68
70
 
@@ -72,6 +74,13 @@ const config = {};
72
74
  *
73
75
  * WebDriver requires Selenium Server and ChromeDriver/GeckoDriver to be installed. Those tools can be easily installed via NPM. Please check [Testing with WebDriver](https://codecept.io/webdriver/#testing-with-webdriver) for more details.
74
76
  *
77
+ * With the release of WebdriverIO version v8.14.0, and onwards, all driver management hassles are now a thing of the past 🙌. Read more [here](https://webdriver.io/blog/2023/07/31/driver-management/).
78
+ * One of the significant advantages of this update is that you can now get rid of any driver services you previously had to manage, such as
79
+ * `wdio-chromedriver-service`, `wdio-geckodriver-service`, `wdio-edgedriver-service`, `wdio-safaridriver-service`, and even `@wdio/selenium-standalone-service`.
80
+ *
81
+ * For those who require custom driver options, fear not; WebDriver Helper allows you to pass in driver options through custom WebDriver configuration.
82
+ * If you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebDriver Helper will only start a driver when there are no other connection information settings like hostname or port specified.
83
+ *
75
84
  * <!-- configuration -->
76
85
  *
77
86
  * Example:
@@ -93,6 +102,28 @@ const config = {};
93
102
  * }
94
103
  * ```
95
104
  *
105
+ * Testing Chrome locally is now more convenient than ever. You can define a browser channel, and WebDriver Helper will take care of downloading the specified browser version for you.
106
+ * For example:
107
+ *
108
+ * ```js
109
+ * {
110
+ * helpers: {
111
+ * WebDriver : {
112
+ * smartWait: 5000,
113
+ * browser: "chrome",
114
+ * browserVersion: '116.0.5793.0', // or 'stable', 'beta', 'dev' or 'canary'
115
+ * restart: false,
116
+ * windowSize: "maximize",
117
+ * timeouts: {
118
+ * "script": 60000,
119
+ * "page load": 10000
120
+ * }
121
+ * }
122
+ * }
123
+ * }
124
+ * ```
125
+ *
126
+ *
96
127
  * Example with basic authentication
97
128
  * ```js
98
129
  * {
@@ -133,6 +164,25 @@ const config = {};
133
164
  * }
134
165
  * ```
135
166
  *
167
+ * ### Running with devtools protocol
168
+ *
169
+ * ```js
170
+ * {
171
+ * helpers: {
172
+ * WebDriver : {
173
+ * url: "http://localhost",
174
+ * browser: "chrome",
175
+ * devtoolsProtocol: true,
176
+ * desiredCapabilities: {
177
+ * chromeOptions: {
178
+ * args: [ "--headless", "--disable-gpu", "--no-sandbox" ]
179
+ * }
180
+ * }
181
+ * }
182
+ * }
183
+ * }
184
+ * ```
185
+ *
136
186
  * ### Internet Explorer
137
187
  *
138
188
  * Additional configuration params can be used from [IE options](https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/IE/Options.html)
@@ -415,7 +465,6 @@ class WebDriver extends Helper {
415
465
  _validateConfig(config) {
416
466
  const defaults = {
417
467
  logLevel: 'silent',
418
- path: '/wd/hub',
419
468
  // codeceptjs
420
469
  remoteFileUpload: true,
421
470
  smartWait: 0,
@@ -435,12 +484,17 @@ class WebDriver extends Helper {
435
484
  // override defaults with config
436
485
  config = Object.assign(defaults, config);
437
486
 
438
- if (typeof config.host !== 'undefined') config.hostname = config.host; // webdriverio spec
487
+ if (config.host) {
488
+ // webdriverio spec
489
+ config.hostname = config.host;
490
+ config.path = '/wd/hub';
491
+ }
439
492
  config.baseUrl = config.url || config.baseUrl;
440
493
  if (config.desiredCapabilities && Object.keys(config.desiredCapabilities).length) {
441
494
  config.capabilities = config.desiredCapabilities;
442
495
  }
443
496
  config.capabilities.browserName = config.browser || config.capabilities.browserName;
497
+ config.capabilities.browserVersion = config.browserVersion || config.capabilities.browserVersion;
444
498
  if (config.capabilities.chromeOptions) {
445
499
  config.capabilities['goog:chromeOptions'] = config.capabilities.chromeOptions;
446
500
  delete config.capabilities.chromeOptions;
@@ -542,6 +596,10 @@ class WebDriver extends Helper {
542
596
  delete this.options.capabilities.hostname;
543
597
  delete this.options.capabilities.port;
544
598
  delete this.options.capabilities.path;
599
+ if (this.options.devtoolsProtocol) {
600
+ if (!['chrome', 'chromium'].includes(this.options.browser.toLowerCase())) throw Error('The devtools protocol is only working with Chrome or Chromium');
601
+ this.options.automationProtocol = 'devtools';
602
+ }
545
603
  this.browser = await webdriverio.remote(this.options);
546
604
  }
547
605
  } catch (err) {
@@ -776,7 +834,7 @@ class WebDriver extends Helper {
776
834
  * ```
777
835
  *
778
836
  *
779
- * @param {string | object} locator element located by CSS|XPath|strict locator.
837
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
780
838
  */
781
839
  async _locate(locator, smartWait = false) {
782
840
  if (require('../store').debugMode) smartWait = false;
@@ -835,7 +893,7 @@ class WebDriver extends Helper {
835
893
  * this.helpers['WebDriver']._locateCheckable('I agree with terms and conditions').then // ...
836
894
  * ```
837
895
  *
838
- * @param {string | object} locator element located by CSS|XPath|strict locator.
896
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
839
897
  */
840
898
  async _locateCheckable(locator) {
841
899
  return findCheckable.call(this, locator, this.$$.bind(this)).then(res => res);
@@ -849,7 +907,7 @@ class WebDriver extends Helper {
849
907
  * const els = await this.helpers.WebDriver._locateClickable('Next page', '.pages');
850
908
  * ```
851
909
  *
852
- * @param {string | object} locator element located by CSS|XPath|strict locator.
910
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
853
911
  */
854
912
  async _locateClickable(locator, context) {
855
913
  const locateFn = prepareLocateFn.call(this, context);
@@ -863,7 +921,7 @@ class WebDriver extends Helper {
863
921
  * this.helpers['WebDriver']._locateFields('Your email').then // ...
864
922
  * ```
865
923
  *
866
- * @param {string | object} locator element located by CSS|XPath|strict locator.
924
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
867
925
  */
868
926
  async _locateFields(locator) {
869
927
  return findFields.call(this, locator).then(res => res);
@@ -877,7 +935,7 @@ class WebDriver extends Helper {
877
935
  * const webElements = await I.grabWebElements('#button');
878
936
  * ```
879
937
  *
880
- * @param {string | object} locator element located by CSS|XPath|strict locator.
938
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
881
939
  * @returns {Promise<*>} WebElement of being used Web helper
882
940
  *
883
941
  *
@@ -956,8 +1014,8 @@ class WebDriver extends Helper {
956
1014
  * I.click({css: 'nav a.login'});
957
1015
  * ```
958
1016
  *
959
- * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
960
- * @param {?string | object | null} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1017
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1018
+ * @param {?CodeceptJS.LocatorOrString | null} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
961
1019
  * @returns {void} automatically synchronized promise through #recorder
962
1020
  *
963
1021
  *
@@ -1004,8 +1062,8 @@ class WebDriver extends Helper {
1004
1062
  * I.forceClick({css: 'nav a.login'});
1005
1063
  * ```
1006
1064
  *
1007
- * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1008
- * @param {?string | object} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1065
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1066
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1009
1067
  * @returns {void} automatically synchronized promise through #recorder
1010
1068
  *
1011
1069
  *
@@ -1044,8 +1102,8 @@ class WebDriver extends Helper {
1044
1102
  * I.doubleClick('.btn.edit');
1045
1103
  * ```
1046
1104
  *
1047
- * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1048
- * @param {?string | object} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1105
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1106
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1049
1107
  * @returns {void} automatically synchronized promise through #recorder
1050
1108
  *
1051
1109
  *
@@ -1078,8 +1136,8 @@ class WebDriver extends Helper {
1078
1136
  * I.rightClick('Click me', '.context');
1079
1137
  * ```
1080
1138
  *
1081
- * @param {string | object} locator clickable element located by CSS|XPath|strict locator.
1082
- * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1139
+ * @param {CodeceptJS.LocatorOrString} locator clickable element located by CSS|XPath|strict locator.
1140
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1083
1141
  * @returns {void} automatically synchronized promise through #recorder
1084
1142
  *
1085
1143
  *
@@ -1122,8 +1180,8 @@ class WebDriver extends Helper {
1122
1180
  * I.forceRightClick('Menu');
1123
1181
  * ```
1124
1182
  *
1125
- * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1126
- * @param {?string | object} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1183
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1184
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1127
1185
  * @returns {void} automatically synchronized promise through #recorder
1128
1186
  *
1129
1187
  *
@@ -1164,8 +1222,8 @@ class WebDriver extends Helper {
1164
1222
  * // or by strict locator
1165
1223
  * I.fillField({css: 'form#login input[name=username]'}, 'John');
1166
1224
  * ```
1167
- * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1168
- * @param {string | object} value text value to fill.
1225
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1226
+ * @param {CodeceptJS.StringOrSecret} value text value to fill.
1169
1227
  * @returns {void} automatically synchronized promise through #recorder
1170
1228
  *
1171
1229
  * {{ react }}
@@ -1177,7 +1235,8 @@ class WebDriver extends Helper {
1177
1235
  assertElementExists(res, field, 'Field');
1178
1236
  const elem = usingFirstElement(res);
1179
1237
  highlightActiveElement.call(this, elem);
1180
- return elem.setValue(value.toString());
1238
+ await elem.clearValue();
1239
+ await elem.setValue(value.toString());
1181
1240
  }
1182
1241
 
1183
1242
  /**
@@ -1189,7 +1248,7 @@ class WebDriver extends Helper {
1189
1248
  * // typing secret
1190
1249
  * I.appendField('password', secret('123456'));
1191
1250
  * ```
1192
- * @param {string | object} field located by label|name|CSS|XPath|strict locator
1251
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator
1193
1252
  * @param {string} value text value to append.
1194
1253
  * @returns {void} automatically synchronized promise through #recorder
1195
1254
  *
@@ -1200,6 +1259,10 @@ class WebDriver extends Helper {
1200
1259
  assertElementExists(res, field, 'Field');
1201
1260
  const elem = usingFirstElement(res);
1202
1261
  highlightActiveElement.call(this, elem);
1262
+ if (this.options.automationProtocol) {
1263
+ const curentValue = await elem.getValue();
1264
+ return elem.setValue(curentValue + value.toString());
1265
+ }
1203
1266
  return elem.addValue(value.toString());
1204
1267
  }
1205
1268
 
@@ -1211,7 +1274,7 @@ class WebDriver extends Helper {
1211
1274
  * I.clearField('user[email]');
1212
1275
  * I.clearField('#email');
1213
1276
  * ```
1214
- * @param {string | object} editable field located by label|name|CSS|XPath|strict locator.
1277
+ * @param {LocatorOrString} editable field located by label|name|CSS|XPath|strict locator.
1215
1278
  * @returns {void} automatically synchronized promise through #recorder.
1216
1279
  *
1217
1280
  *
@@ -1221,6 +1284,9 @@ class WebDriver extends Helper {
1221
1284
  assertElementExists(res, field, 'Field');
1222
1285
  const elem = usingFirstElement(res);
1223
1286
  highlightActiveElement.call(this, elem);
1287
+ if (this.options.automationProtocol) {
1288
+ return elem.setValue('');
1289
+ }
1224
1290
  return elem.clearValue(getElementId(elem));
1225
1291
  }
1226
1292
 
@@ -1243,7 +1309,7 @@ class WebDriver extends Helper {
1243
1309
  * ```js
1244
1310
  * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1245
1311
  * ```
1246
- * @param {string | object} select field located by label|name|CSS|XPath|strict locator.
1312
+ * @param {LocatorOrString} select field located by label|name|CSS|XPath|strict locator.
1247
1313
  * @param {string|Array<*>} option visible text or value of option.
1248
1314
  * @returns {void} automatically synchronized promise through #recorder
1249
1315
  *
@@ -1290,7 +1356,7 @@ class WebDriver extends Helper {
1290
1356
  * I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
1291
1357
  * ```
1292
1358
  *
1293
- * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
1359
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1294
1360
  * @param {string} pathToFile local file path relative to codecept.conf.ts or codecept.conf.js config file.
1295
1361
  * @returns {void} automatically synchronized promise through #recorder
1296
1362
  *
@@ -1307,7 +1373,7 @@ class WebDriver extends Helper {
1307
1373
  const el = usingFirstElement(res);
1308
1374
 
1309
1375
  // Remote Upload (when running Selenium Server)
1310
- if (this.options.remoteFileUpload) {
1376
+ if (this.options.remoteFileUpload && !this.options.automationProtocol) {
1311
1377
  try {
1312
1378
  this.debugSection('File', 'Uploading file to remote server');
1313
1379
  file = await this.browser.uploadFile(file);
@@ -1331,8 +1397,8 @@ class WebDriver extends Helper {
1331
1397
  * I.checkOption('I Agree to Terms and Conditions');
1332
1398
  * I.checkOption('agree', '//form');
1333
1399
  * ```
1334
- * @param {string | object} field checkbox located by label | name | CSS | XPath | strict locator.
1335
- * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1400
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1401
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1336
1402
  * @returns {void} automatically synchronized promise through #recorder
1337
1403
  *
1338
1404
  */
@@ -1364,8 +1430,8 @@ class WebDriver extends Helper {
1364
1430
  * I.uncheckOption('I Agree to Terms and Conditions');
1365
1431
  * I.uncheckOption('agree', '//form');
1366
1432
  * ```
1367
- * @param {string | object} field checkbox located by label | name | CSS | XPath | strict locator.
1368
- * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1433
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1434
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1369
1435
  * @returns {void} automatically synchronized promise through #recorder
1370
1436
  *
1371
1437
  */
@@ -1393,7 +1459,7 @@ class WebDriver extends Helper {
1393
1459
  * let pins = await I.grabTextFromAll('#pin li');
1394
1460
  * ```
1395
1461
  *
1396
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1462
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1397
1463
  * @returns {Promise<string[]>} attribute value
1398
1464
  *
1399
1465
  *
@@ -1414,7 +1480,7 @@ class WebDriver extends Helper {
1414
1480
  * ```
1415
1481
  * If multiple elements found returns first element.
1416
1482
  *
1417
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1483
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1418
1484
  * @returns {Promise<string>} attribute value
1419
1485
  *
1420
1486
  *
@@ -1437,7 +1503,7 @@ class WebDriver extends Helper {
1437
1503
  * let postHTMLs = await I.grabHTMLFromAll('.post');
1438
1504
  * ```
1439
1505
  *
1440
- * @param {string | object} element located by CSS|XPath|strict locator.
1506
+ * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator.
1441
1507
  * @returns {Promise<string[]>} HTML code for an element
1442
1508
  *
1443
1509
  *
@@ -1458,7 +1524,7 @@ class WebDriver extends Helper {
1458
1524
  * let postHTML = await I.grabHTMLFrom('#post');
1459
1525
  * ```
1460
1526
  *
1461
- * @param {string | object} element located by CSS|XPath|strict locator.
1527
+ * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator.
1462
1528
  * @returns {Promise<string>} HTML code for an element
1463
1529
  *
1464
1530
  *
@@ -1480,7 +1546,7 @@ class WebDriver extends Helper {
1480
1546
  * ```js
1481
1547
  * let inputs = await I.grabValueFromAll('//form/input');
1482
1548
  * ```
1483
- * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
1549
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1484
1550
  * @returns {Promise<string[]>} attribute value
1485
1551
  *
1486
1552
  *
@@ -1501,7 +1567,7 @@ class WebDriver extends Helper {
1501
1567
  * ```js
1502
1568
  * let email = await I.grabValueFrom('input[name=email]');
1503
1569
  * ```
1504
- * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
1570
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1505
1571
  * @returns {Promise<string>} attribute value
1506
1572
  *
1507
1573
  *
@@ -1524,7 +1590,7 @@ class WebDriver extends Helper {
1524
1590
  * const values = await I.grabCssPropertyFromAll('h3', 'font-weight');
1525
1591
  * ```
1526
1592
  *
1527
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1593
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1528
1594
  * @param {string} cssProperty CSS property name.
1529
1595
  * @returns {Promise<string[]>} CSS value
1530
1596
  *
@@ -1545,7 +1611,7 @@ class WebDriver extends Helper {
1545
1611
  * const value = await I.grabCssPropertyFrom('h3', 'font-weight');
1546
1612
  * ```
1547
1613
  *
1548
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1614
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1549
1615
  * @param {string} cssProperty CSS property name.
1550
1616
  * @returns {Promise<string>} CSS value
1551
1617
  *
@@ -1568,7 +1634,7 @@ class WebDriver extends Helper {
1568
1634
  * ```js
1569
1635
  * let hints = await I.grabAttributeFromAll('.tooltip', 'title');
1570
1636
  * ```
1571
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1637
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1572
1638
  * @param {string} attr attribute name.
1573
1639
  * @returns {Promise<string[]>} attribute value
1574
1640
  *
@@ -1588,7 +1654,7 @@ class WebDriver extends Helper {
1588
1654
  * ```js
1589
1655
  * let hint = await I.grabAttributeFrom('#tooltip', 'title');
1590
1656
  * ```
1591
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1657
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1592
1658
  * @param {string} attr attribute name.
1593
1659
  * @returns {Promise<string>} attribute value
1594
1660
  *
@@ -1676,7 +1742,7 @@ class WebDriver extends Helper {
1676
1742
  * I.see('Register', {css: 'form.register'}); // use strict locator
1677
1743
  * ```
1678
1744
  * @param {string} text expected on page.
1679
- * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1745
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1680
1746
  * @returns {void} automatically synchronized promise through #recorder
1681
1747
  *
1682
1748
  *
@@ -1694,7 +1760,7 @@ class WebDriver extends Helper {
1694
1760
  * ```
1695
1761
  *
1696
1762
  * @param {string} text element value to check.
1697
- * @param {(string | object)?} [context=null] element located by CSS|XPath|strict locator.
1763
+ * @param {CodeceptJS.LocatorOrString?} [context=null] element located by CSS|XPath|strict locator.
1698
1764
  * @returns {void} automatically synchronized promise through #recorder
1699
1765
  *
1700
1766
  */
@@ -1712,7 +1778,7 @@ class WebDriver extends Helper {
1712
1778
  * ```
1713
1779
  *
1714
1780
  * @param {string} text which is not present.
1715
- * @param {string | object} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1781
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1716
1782
  * @returns {void} automatically synchronized promise through #recorder
1717
1783
  *
1718
1784
  *
@@ -1732,8 +1798,8 @@ class WebDriver extends Helper {
1732
1798
  * I.seeInField('form input[type=hidden]','hidden_value');
1733
1799
  * I.seeInField('#searchform input','Search');
1734
1800
  * ```
1735
- * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1736
- * @param {string | object} value value to check.
1801
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1802
+ * @param {CodeceptJS.StringOrSecret} value value to check.
1737
1803
  * @returns {void} automatically synchronized promise through #recorder
1738
1804
  *
1739
1805
  *
@@ -1752,8 +1818,8 @@ class WebDriver extends Helper {
1752
1818
  * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
1753
1819
  * ```
1754
1820
  *
1755
- * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1756
- * @param {string | object} value value to check.
1821
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1822
+ * @param {CodeceptJS.StringOrSecret} value value to check.
1757
1823
  * @returns {void} automatically synchronized promise through #recorder
1758
1824
  *
1759
1825
  *
@@ -1773,7 +1839,7 @@ class WebDriver extends Helper {
1773
1839
  * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1774
1840
  * ```
1775
1841
  *
1776
- * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1842
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1777
1843
  * @returns {void} automatically synchronized promise through #recorder
1778
1844
  *
1779
1845
  */
@@ -1791,7 +1857,7 @@ class WebDriver extends Helper {
1791
1857
  * I.dontSeeCheckboxIsChecked('agree'); // located by name
1792
1858
  * ```
1793
1859
  *
1794
- * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1860
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1795
1861
  * @returns {void} automatically synchronized promise through #recorder
1796
1862
  *
1797
1863
  */
@@ -1806,7 +1872,7 @@ class WebDriver extends Helper {
1806
1872
  * ```js
1807
1873
  * I.seeElement('#modal');
1808
1874
  * ```
1809
- * @param {string | object} locator located by CSS|XPath|strict locator.
1875
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1810
1876
  * @returns {void} automatically synchronized promise through #recorder
1811
1877
  *
1812
1878
  * {{ react }}
@@ -1826,7 +1892,7 @@ class WebDriver extends Helper {
1826
1892
  * I.dontSeeElement('.modal'); // modal is not shown
1827
1893
  * ```
1828
1894
  *
1829
- * @param {string | object} locator located by CSS|XPath|Strict locator.
1895
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
1830
1896
  * @returns {void} automatically synchronized promise through #recorder
1831
1897
  *
1832
1898
  * {{ react }}
@@ -1847,7 +1913,7 @@ class WebDriver extends Helper {
1847
1913
  * ```js
1848
1914
  * I.seeElementInDOM('#modal');
1849
1915
  * ```
1850
- * @param {string | object} locator element located by CSS|XPath|strict locator.
1916
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1851
1917
  * @returns {void} automatically synchronized promise through #recorder
1852
1918
  *
1853
1919
  *
@@ -1864,7 +1930,7 @@ class WebDriver extends Helper {
1864
1930
  * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not
1865
1931
  * ```
1866
1932
  *
1867
- * @param {string | object} locator located by CSS|XPath|Strict locator.
1933
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
1868
1934
  * @returns {void} automatically synchronized promise through #recorder
1869
1935
  *
1870
1936
  *
@@ -1967,7 +2033,7 @@ class WebDriver extends Helper {
1967
2033
  * I.seeNumberOfElements('#submitBtn', 1);
1968
2034
  * ```
1969
2035
  *
1970
- * @param {string | object} locator element located by CSS|XPath|strict locator.
2036
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1971
2037
  * @param {number} num number of elements.
1972
2038
  * @returns {void} automatically synchronized promise through #recorder
1973
2039
  *
@@ -1986,7 +2052,7 @@ class WebDriver extends Helper {
1986
2052
  * I.seeNumberOfVisibleElements('.buttons', 3);
1987
2053
  * ```
1988
2054
  *
1989
- * @param {string | object} locator element located by CSS|XPath|strict locator.
2055
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1990
2056
  * @param {number} num number of elements.
1991
2057
  * @returns {void} automatically synchronized promise through #recorder
1992
2058
  *
@@ -2004,7 +2070,7 @@ class WebDriver extends Helper {
2004
2070
  * I.seeCssPropertiesOnElements('h3', { 'font-weight': "bold"});
2005
2071
  * ```
2006
2072
  *
2007
- * @param {string | object} locator located by CSS|XPath|strict locator.
2073
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2008
2074
  * @param {object} cssProperties object with CSS properties and their values to check.
2009
2075
  * @returns {void} automatically synchronized promise through #recorder
2010
2076
  *
@@ -2012,35 +2078,33 @@ class WebDriver extends Helper {
2012
2078
  async seeCssPropertiesOnElements(locator, cssProperties) {
2013
2079
  const res = await this._locate(locator);
2014
2080
  assertElementExists(res, locator);
2081
+
2082
+ const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties);
2015
2083
  const elemAmount = res.length;
2084
+ let props = [];
2016
2085
 
2017
- let props = await forEachAsync(res, async (el) => {
2018
- return forEachAsync(Object.keys(cssProperties), async (prop) => {
2019
- const propValue = await this.browser.getElementCSSValue(getElementId(el), prop);
2020
- if (isColorProperty(prop) && propValue && propValue.value) {
2021
- return convertColorToRGBA(propValue.value);
2086
+ for (const element of res) {
2087
+ for (const prop of Object.keys(cssProperties)) {
2088
+ const cssProp = await this.grabCssPropertyFrom(locator, prop);
2089
+ if (isColorProperty(prop)) {
2090
+ props.push(convertColorToRGBA(cssProp));
2091
+ } else {
2092
+ props.push(cssProp);
2022
2093
  }
2023
- return propValue;
2024
- });
2025
- });
2026
-
2027
- const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties);
2094
+ }
2095
+ }
2028
2096
 
2029
2097
  const values = Object.keys(cssPropertiesCamelCase).map(key => cssPropertiesCamelCase[key]);
2030
2098
  if (!Array.isArray(props)) props = [props];
2031
2099
  let chunked = chunkArray(props, values.length);
2032
2100
  chunked = chunked.filter((val) => {
2033
2101
  for (let i = 0; i < val.length; ++i) {
2034
- const _acutal = Number.isNaN(val[i]) || (typeof values[i]) === 'string' ? val[i] : Number.parseInt(val[i], 10);
2035
- const _expected = Number.isNaN(values[i]) || (typeof values[i]) === 'string' ? values[i] : Number.parseInt(values[i], 10);
2036
- if (_acutal !== _expected) return false;
2102
+ // eslint-disable-next-line eqeqeq
2103
+ if (val[i] != values[i]) return false;
2037
2104
  }
2038
2105
  return true;
2039
2106
  });
2040
- return assert.ok(
2041
- chunked.length === elemAmount,
2042
- `expected all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`,
2043
- );
2107
+ return equals(`all elements (${(new Locator(locator))}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount);
2044
2108
  }
2045
2109
 
2046
2110
  /**
@@ -2050,7 +2114,7 @@ class WebDriver extends Helper {
2050
2114
  * I.seeAttributesOnElements('//form', { method: "post"});
2051
2115
  * ```
2052
2116
  *
2053
- * @param {string | object} locator located by CSS|XPath|strict locator.
2117
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2054
2118
  * @param {object} attributes attributes and their values to check.
2055
2119
  * @returns {void} automatically synchronized promise through #recorder
2056
2120
  *
@@ -2069,9 +2133,9 @@ class WebDriver extends Helper {
2069
2133
  let chunked = chunkArray(attrs, values.length);
2070
2134
  chunked = chunked.filter((val) => {
2071
2135
  for (let i = 0; i < val.length; ++i) {
2072
- const _acutal = Number.isNaN(val[i]) || (typeof values[i]) === 'string' ? val[i] : Number.parseInt(val[i], 10);
2136
+ const _actual = Number.isNaN(val[i]) || (typeof values[i]) === 'string' ? val[i] : Number.parseInt(val[i], 10);
2073
2137
  const _expected = Number.isNaN(values[i]) || (typeof values[i]) === 'string' ? values[i] : Number.parseInt(values[i], 10);
2074
- if (_acutal !== _expected) return false;
2138
+ if (_actual !== _expected) return false;
2075
2139
  }
2076
2140
  return true;
2077
2141
  });
@@ -2089,7 +2153,7 @@ class WebDriver extends Helper {
2089
2153
  * let numOfElements = await I.grabNumberOfVisibleElements('p');
2090
2154
  * ```
2091
2155
  *
2092
- * @param {string | object} locator located by CSS|XPath|strict locator.
2156
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2093
2157
  * @returns {Promise<number>} number of visible elements
2094
2158
  */
2095
2159
  async grabNumberOfVisibleElements(locator) {
@@ -2246,7 +2310,7 @@ class WebDriver extends Helper {
2246
2310
  * I.scrollIntoView('#submit', { behavior: "smooth", block: "center", inline: "center" });
2247
2311
  * ```
2248
2312
  *
2249
- * @param {string | object} locator located by CSS|XPath|strict locator.
2313
+ * @param {LocatorOrString} locator located by CSS|XPath|strict locator.
2250
2314
  * @param {ScrollIntoViewOptions|boolean} scrollIntoViewOptions either alignToTop=true|false or scrollIntoViewOptions. See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView.
2251
2315
  * @returns {void} automatically synchronized promise through #recorder
2252
2316
  *
@@ -2268,7 +2332,7 @@ class WebDriver extends Helper {
2268
2332
  * I.scrollTo('#submit', 5, 5);
2269
2333
  * ```
2270
2334
  *
2271
- * @param {string | object} locator located by CSS|XPath|strict locator.
2335
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2272
2336
  * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
2273
2337
  * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
2274
2338
  * @returns {void} automatically synchronized promise through #recorder
@@ -2311,7 +2375,7 @@ class WebDriver extends Helper {
2311
2375
  * I.moveCursorTo('#submit', 5,5);
2312
2376
  * ```
2313
2377
  *
2314
- * @param {string | object} locator located by CSS|XPath|strict locator.
2378
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2315
2379
  * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
2316
2380
  * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
2317
2381
  * @returns {void} automatically synchronized promise through #recorder
@@ -2321,7 +2385,11 @@ class WebDriver extends Helper {
2321
2385
  const res = await this._locate(withStrictLocator(locator), true);
2322
2386
  assertElementExists(res, locator);
2323
2387
  const elem = usingFirstElement(res);
2324
- return elem.moveTo({ xOffset, yOffset });
2388
+ try {
2389
+ await elem.moveTo({ xOffset, yOffset });
2390
+ } catch (e) {
2391
+ debug(e.message);
2392
+ }
2325
2393
  }
2326
2394
 
2327
2395
  /**
@@ -2332,7 +2400,7 @@ class WebDriver extends Helper {
2332
2400
  * I.saveElementScreenshot(`#submit`,'debug.png');
2333
2401
  * ```
2334
2402
  *
2335
- * @param {string | object} locator element located by CSS|XPath|strict locator.
2403
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2336
2404
  * @param {string} fileName file name to save.
2337
2405
  * @returns {void} automatically synchronized promise through #recorder
2338
2406
  *
@@ -2764,7 +2832,7 @@ class WebDriver extends Helper {
2764
2832
  *
2765
2833
  */
2766
2834
  async resizeWindow(width, height) {
2767
- return this._resizeBrowserWindow(this.browser, width, height);
2835
+ return this.browser.setWindowSize(width, height);
2768
2836
  }
2769
2837
 
2770
2838
  async _resizeBrowserWindow(browser, width, height) {
@@ -2799,7 +2867,7 @@ class WebDriver extends Helper {
2799
2867
  * I.see('#add-to-cart-bnt');
2800
2868
  * ```
2801
2869
  *
2802
- * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2870
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2803
2871
  * @param {any} [options] Playwright only: [Additional options](https://playwright.dev/docs/api/class-locator#locator-focus) for available options object as 2nd argument.
2804
2872
  * @returns {void} automatically synchronized promise through #recorder
2805
2873
  *
@@ -2829,7 +2897,7 @@ class WebDriver extends Helper {
2829
2897
  * I.dontSee('#add-to-cart-btn');
2830
2898
  * ```
2831
2899
  *
2832
- * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2900
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2833
2901
  * @param {any} [options] Playwright only: [Additional options](https://playwright.dev/docs/api/class-locator#locator-blur) for available options object as 2nd argument.
2834
2902
  * @returns {void} automatically synchronized promise through #recorder
2835
2903
  *
@@ -2851,8 +2919,8 @@ class WebDriver extends Helper {
2851
2919
  * I.dragAndDrop('#dragHandle', '#container');
2852
2920
  * ```
2853
2921
  *
2854
- * @param {string | object} srcElement located by CSS|XPath|strict locator.
2855
- * @param {string | object} destElement located by CSS|XPath|strict locator.
2922
+ * @param {LocatorOrString} srcElement located by CSS|XPath|strict locator.
2923
+ * @param {LocatorOrString} destElement located by CSS|XPath|strict locator.
2856
2924
  * @returns {void} automatically synchronized promise through #recorder
2857
2925
  *
2858
2926
  */
@@ -2877,7 +2945,7 @@ class WebDriver extends Helper {
2877
2945
  * I.dragSlider('#slider', -70);
2878
2946
  * ```
2879
2947
  *
2880
- * @param {string | object} locator located by label|name|CSS|XPath|strict locator.
2948
+ * @param {CodeceptJS.LocatorOrString} locator located by label|name|CSS|XPath|strict locator.
2881
2949
  * @param {number} offsetX position to drag.
2882
2950
  * @returns {void} automatically synchronized promise through #recorder
2883
2951
  *
@@ -3003,7 +3071,7 @@ class WebDriver extends Helper {
3003
3071
  * Waits for element to become enabled (by default waits for 1sec).
3004
3072
  * Element can be located by CSS or XPath.
3005
3073
  *
3006
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3074
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3007
3075
  * @param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
3008
3076
  * @returns {void} automatically synchronized promise through #recorder
3009
3077
  *
@@ -3036,7 +3104,7 @@ class WebDriver extends Helper {
3036
3104
  * I.waitForElement('.btn.continue', 5); // wait for 5 secs
3037
3105
  * ```
3038
3106
  *
3039
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3107
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3040
3108
  * @param {number} [sec] (optional, `1` by default) time in seconds to wait
3041
3109
  * @returns {void} automatically synchronized promise through #recorder
3042
3110
  *
@@ -3059,7 +3127,7 @@ class WebDriver extends Helper {
3059
3127
  * I.waitForClickable('.btn.continue', 5); // wait for 5 secs
3060
3128
  * ```
3061
3129
  *
3062
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3130
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3063
3131
  * @param {number} [sec] (optional, `1` by default) time in seconds to wait
3064
3132
  * @returns {void} automatically synchronized promise through #recorder
3065
3133
  *
@@ -3152,7 +3220,7 @@ class WebDriver extends Helper {
3152
3220
  *
3153
3221
  * @param {string }text to wait for.
3154
3222
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3155
- * @param {string | object} [context] (optional) element located by CSS|XPath|strict locator.
3223
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
3156
3224
  * @returns {void} automatically synchronized promise through #recorder
3157
3225
  *
3158
3226
  *
@@ -3182,7 +3250,7 @@ class WebDriver extends Helper {
3182
3250
  * I.waitForValue('//input', "GoodValue");
3183
3251
  * ```
3184
3252
  *
3185
- * @param {string | object} field input field.
3253
+ * @param {LocatorOrString} field input field.
3186
3254
  * @param {string }value expected value.
3187
3255
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3188
3256
  * @returns {void} automatically synchronized promise through #recorder
@@ -3214,7 +3282,7 @@ class WebDriver extends Helper {
3214
3282
  * I.waitForVisible('#popup');
3215
3283
  * ```
3216
3284
  *
3217
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3285
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3218
3286
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3219
3287
  * @returns {void} automatically synchronized promise through #recorder
3220
3288
  *
@@ -3241,7 +3309,7 @@ class WebDriver extends Helper {
3241
3309
  * I.waitNumberOfVisibleElements('a', 3);
3242
3310
  * ```
3243
3311
  *
3244
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3312
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3245
3313
  * @param {number} num number of elements.
3246
3314
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3247
3315
  * @returns {void} automatically synchronized promise through #recorder
@@ -3269,7 +3337,7 @@ class WebDriver extends Helper {
3269
3337
  * I.waitForInvisible('#popup');
3270
3338
  * ```
3271
3339
  *
3272
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3340
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3273
3341
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3274
3342
  * @returns {void} automatically synchronized promise through #recorder
3275
3343
  *
@@ -3293,7 +3361,7 @@ class WebDriver extends Helper {
3293
3361
  * I.waitToHide('#popup');
3294
3362
  * ```
3295
3363
  *
3296
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3364
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3297
3365
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3298
3366
  * @returns {void} automatically synchronized promise through #recorder
3299
3367
  *
@@ -3310,7 +3378,7 @@ class WebDriver extends Helper {
3310
3378
  * I.waitForDetached('#popup');
3311
3379
  * ```
3312
3380
  *
3313
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3381
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3314
3382
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3315
3383
  * @returns {void} automatically synchronized promise through #recorder
3316
3384
  *
@@ -3362,6 +3430,33 @@ class WebDriver extends Helper {
3362
3430
  return this.browser.waitUntil(async () => this.browser.execute(fn, ...args), { timeout: aSec * 1000, timeoutMsg: '' });
3363
3431
  }
3364
3432
 
3433
+ /**
3434
+ * Waits for number of tabs.
3435
+ *
3436
+ * ```js
3437
+ * I.waitForNumberOfTabs(2);
3438
+ * ```
3439
+ *
3440
+ * @param {number} expectedTabs expecting the number of tabs.
3441
+ * @param {number} sec number of secs to wait.
3442
+ * @returns {void} automatically synchronized promise through #recorder
3443
+ *
3444
+ */
3445
+ async waitForNumberOfTabs(expectedTabs, sec) {
3446
+ const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeoutInSeconds;
3447
+ let currentTabs;
3448
+ let count = 0;
3449
+
3450
+ do {
3451
+ currentTabs = await this.grabNumberOfOpenTabs();
3452
+ await this.wait(1);
3453
+ count += 1000;
3454
+ if (currentTabs >= expectedTabs) return;
3455
+ } while (count <= waitTimeout);
3456
+
3457
+ throw new Error(`Expected ${expectedTabs} tabs are not met after ${waitTimeout / 1000} sec.`);
3458
+ }
3459
+
3365
3460
  /**
3366
3461
  * Switches frame or in case of null locator reverts to parent.
3367
3462
  *
@@ -3370,13 +3465,16 @@ class WebDriver extends Helper {
3370
3465
  * I.switchTo(); // switch back to main page
3371
3466
  * ```
3372
3467
  *
3373
- * @param {?string | object} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
3468
+ * @param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
3374
3469
  * @returns {void} automatically synchronized promise through #recorder
3375
3470
  *
3376
3471
  */
3377
3472
  async switchTo(locator) {
3378
3473
  this.browser.isInsideFrame = true;
3379
3474
  if (Number.isInteger(locator)) {
3475
+ if (this.options.automationProtocol) {
3476
+ return this.browser.switchToFrame(locator + 1);
3477
+ }
3380
3478
  return this.browser.switchToFrame(locator);
3381
3479
  }
3382
3480
  if (!locator) {
@@ -3581,6 +3679,9 @@ class WebDriver extends Helper {
3581
3679
  }
3582
3680
 
3583
3681
  /**
3682
+ * This method is **deprecated**.
3683
+ *
3684
+ *
3584
3685
  * Set the current geo location
3585
3686
  *
3586
3687
  *
@@ -3595,14 +3696,24 @@ class WebDriver extends Helper {
3595
3696
  * @returns {void} automatically synchronized promise through #recorder
3596
3697
  *
3597
3698
  */
3598
- async setGeoLocation(latitude, longitude, altitude = null) {
3599
- if (altitude) {
3600
- return this.browser.setGeoLocation({ latitude, longitude });
3699
+ async setGeoLocation(latitude, longitude) {
3700
+ if (!this.options.automationProtocol) {
3701
+ console.log(`setGeoLocation deprecated:
3702
+ * This command is deprecated due to using deprecated JSON Wire Protocol command. More info: https://webdriver.io/docs/api/jsonwp/#setgeolocation
3703
+ * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`);
3704
+ return;
3601
3705
  }
3602
- return this.browser.setGeoLocation({ latitude, longitude, altitude });
3706
+ this.geoLocation = { latitude, longitude };
3707
+ const puppeteerBrowser = await this.browser.getPuppeteer();
3708
+ await this.browser.call(async () => {
3709
+ const pages = await puppeteerBrowser.pages();
3710
+ await pages[0].setGeolocation({ latitude, longitude });
3711
+ });
3603
3712
  }
3604
3713
 
3605
3714
  /**
3715
+ * This method is **deprecated**.
3716
+ *
3606
3717
  * Return the current geo location
3607
3718
  * Resumes test execution, so **should be used inside async function with `await`** operator.
3608
3719
  *
@@ -3614,7 +3725,14 @@ class WebDriver extends Helper {
3614
3725
  *
3615
3726
  */
3616
3727
  async grabGeoLocation() {
3617
- return this.browser.getGeoLocation();
3728
+ if (!this.options.automationProtocol) {
3729
+ console.log(`grabGeoLocation deprecated:
3730
+ * This command is deprecated due to using deprecated JSON Wire Protocol command. More info: https://webdriver.io/docs/api/jsonwp/#getgeolocation
3731
+ * Switch to devtools protocol to use this command by setting devtoolsProtocol: true in the configuration`);
3732
+ return;
3733
+ }
3734
+ if (!this.geoLocation) return 'No GeoLocation is set!';
3735
+ return this.geoLocation;
3618
3736
  }
3619
3737
 
3620
3738
  /**
@@ -3635,7 +3753,7 @@ class WebDriver extends Helper {
3635
3753
  * const width = await I.grabElementBoundingRect('h3', 'width');
3636
3754
  * // width == 527
3637
3755
  * ```
3638
- * @param {string | object} locator element located by CSS|XPath|strict locator.
3756
+ * @param {LocatorOrString} locator element located by CSS|XPath|strict locator.
3639
3757
  * @param {string=} elementSize x, y, width or height of the given element.
3640
3758
  * @returns {Promise<DOMRect>|Promise<number>} Element bounding rectangle
3641
3759
  *
@@ -3830,7 +3948,7 @@ async function proceedSeeField(assertType, field, value) {
3830
3948
  }
3831
3949
  };
3832
3950
 
3833
- const proceedSingle = el => this.browser.getElementAttribute(getElementId(el), 'value').then((res) => {
3951
+ const proceedSingle = el => el.getValue().then((res) => {
3834
3952
  if (res === null) {
3835
3953
  throw new Error(`Element ${el.selector} has no value attribute`);
3836
3954
  }