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.
- package/README.md +3 -3
- package/docs/build/Appium.js +35 -35
- package/docs/build/Nightmare.js +50 -50
- package/docs/build/Playwright.js +100 -72
- package/docs/build/Protractor.js +59 -59
- package/docs/build/Puppeteer.js +96 -69
- package/docs/build/TestCafe.js +48 -48
- package/docs/build/WebDriver.js +223 -105
- package/docs/helpers/Playwright.md +15 -0
- package/docs/helpers/Puppeteer.md +15 -0
- package/docs/helpers/WebDriver.md +340 -266
- package/docs/locators.md +9 -1
- package/docs/webapi/waitForNumberOfTabs.mustache +9 -0
- package/docs/webdriver.md +52 -6
- package/lib/command/run-multiple.js +3 -1
- package/lib/command/run-workers.js +32 -1
- package/lib/command/workers/runTests.js +2 -2
- package/lib/css2xpath/js/css_to_xpath.js +20 -0
- package/lib/css2xpath/js/expression.js +23 -0
- package/lib/css2xpath/js/renderer.js +239 -0
- package/lib/helper/Playwright.js +21 -2
- package/lib/helper/Puppeteer.js +18 -0
- package/lib/helper/WebDriver.js +140 -31
- package/lib/locator.js +31 -4
- package/lib/plugin/retryFailedStep.js +5 -1
- package/lib/plugin/retryTo.js +2 -2
- package/package.json +24 -18
- package/typings/index.d.ts +9 -6
- package/typings/promiseBasedTypes.d.ts +84 -1
- package/typings/types.d.ts +102 -2
package/docs/build/WebDriver.js
CHANGED
|
@@ -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 (
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
960
|
-
* @param {?
|
|
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 {
|
|
1008
|
-
* @param {?
|
|
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 {
|
|
1048
|
-
* @param {?
|
|
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 {
|
|
1082
|
-
* @param {?
|
|
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 {
|
|
1126
|
-
* @param {?
|
|
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 {
|
|
1168
|
-
* @param {
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
1335
|
-
* @param {?
|
|
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 {
|
|
1368
|
-
* @param {?
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {?
|
|
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 {
|
|
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 {
|
|
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 {
|
|
1736
|
-
* @param {
|
|
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 {
|
|
1756
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
2018
|
-
|
|
2019
|
-
const
|
|
2020
|
-
if (isColorProperty(prop)
|
|
2021
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2035
|
-
|
|
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.
|
|
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 {
|
|
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
|
|
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 (
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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.
|
|
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 {
|
|
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 {
|
|
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 {
|
|
2855
|
-
* @param {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 {?
|
|
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
|
|
3599
|
-
if (
|
|
3600
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =>
|
|
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
|
}
|