codeceptjs 3.5.4 → 3.5.6
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/docs/build/Appium.js +40 -1
- package/docs/build/FileSystem.js +1 -1
- package/docs/build/Nightmare.js +4 -0
- package/docs/build/Playwright.js +59 -41
- package/docs/build/Protractor.js +4 -0
- package/docs/build/Puppeteer.js +21 -10
- package/docs/build/TestCafe.js +2 -0
- package/docs/build/WebDriver.js +8 -4
- package/docs/changelog.md +1 -170
- package/docs/community-helpers.md +4 -8
- package/docs/examples.md +2 -8
- package/docs/helpers/Appium.md +37 -0
- package/docs/helpers/FileSystem.md +1 -1
- package/docs/helpers/Nightmare.md +26 -24
- package/docs/helpers/Playwright.md +1 -1
- package/docs/helpers/Protractor.md +4 -2
- package/docs/helpers/Puppeteer.md +29 -27
- package/docs/helpers/TestCafe.md +16 -15
- package/docs/helpers/WebDriver.md +32 -30
- package/docs/webapi/executeAsyncScript.mustache +2 -0
- package/docs/webapi/executeScript.mustache +2 -0
- package/lib/codecept.js +4 -0
- package/lib/command/info.js +24 -0
- package/lib/command/init.js +40 -4
- package/lib/command/run-workers.js +5 -0
- package/lib/command/run.js +7 -0
- package/lib/data/context.js +14 -6
- package/lib/helper/Appium.js +40 -1
- package/lib/helper/FileSystem.js +1 -1
- package/lib/helper/Playwright.js +58 -40
- package/lib/helper/Puppeteer.js +17 -10
- package/lib/helper/WebDriver.js +4 -4
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/pause.js +1 -2
- package/lib/plugin/autoLogin.js +0 -5
- package/lib/plugin/retryTo.js +0 -2
- package/lib/plugin/tryTo.js +0 -3
- package/lib/session.js +1 -1
- package/package.json +88 -88
- package/translations/fr-FR.js +13 -1
- package/typings/promiseBasedTypes.d.ts +19 -1
- package/typings/types.d.ts +36 -16
package/docs/build/Appium.js
CHANGED
|
@@ -117,6 +117,43 @@ const vendorPrefix = {
|
|
|
117
117
|
* }
|
|
118
118
|
* ```
|
|
119
119
|
*
|
|
120
|
+
* Example Android App using Appiumv2 on BrowserStack:
|
|
121
|
+
*
|
|
122
|
+
* ```js
|
|
123
|
+
* {
|
|
124
|
+
* helpers: {
|
|
125
|
+
* Appium: {
|
|
126
|
+
* appiumV2: true,
|
|
127
|
+
* host: "hub-cloud.browserstack.com",
|
|
128
|
+
* port: 4444,
|
|
129
|
+
* user: process.env.BROWSERSTACK_USER,
|
|
130
|
+
* key: process.env.BROWSERSTACK_KEY,
|
|
131
|
+
* app: `bs://c700ce60cf1gjhgjh3ae8ed9770ghjg5a55b8e022f13c5827cg`,
|
|
132
|
+
* browser: '',
|
|
133
|
+
* desiredCapabilities: {
|
|
134
|
+
* 'appPackage': data.packageName,
|
|
135
|
+
* 'deviceName': process.env.DEVICE || 'Google Pixel 3',
|
|
136
|
+
* 'platformName': process.env.PLATFORM || 'android',
|
|
137
|
+
* 'platformVersion': process.env.OS_VERSION || '10.0',
|
|
138
|
+
* 'automationName': process.env.ENGINE || 'UIAutomator2',
|
|
139
|
+
* 'newCommandTimeout': 300000,
|
|
140
|
+
* 'androidDeviceReadyTimeout': 300000,
|
|
141
|
+
* 'androidInstallTimeout': 90000,
|
|
142
|
+
* 'appWaitDuration': 300000,
|
|
143
|
+
* 'autoGrantPermissions': true,
|
|
144
|
+
* 'gpsEnabled': true,
|
|
145
|
+
* 'isHeadless': false,
|
|
146
|
+
* 'noReset': false,
|
|
147
|
+
* 'noSign': true,
|
|
148
|
+
* 'bstack:options' : {
|
|
149
|
+
* "appiumVersion" : "2.0.1",
|
|
150
|
+
* },
|
|
151
|
+
* }
|
|
152
|
+
* }
|
|
153
|
+
* }
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
120
157
|
* Additional configuration params can be used from <https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md>
|
|
121
158
|
*
|
|
122
159
|
* ## Access From Helpers
|
|
@@ -234,7 +271,9 @@ class Appium extends Webdriver {
|
|
|
234
271
|
const _convertedCaps = {};
|
|
235
272
|
for (const [key, value] of Object.entries(capabilities)) {
|
|
236
273
|
if (!key.startsWith(vendorPrefix.appium)) {
|
|
237
|
-
|
|
274
|
+
if (key !== 'platformName') {
|
|
275
|
+
_convertedCaps[`${vendorPrefix.appium}:${key}`] = value;
|
|
276
|
+
}
|
|
238
277
|
} else {
|
|
239
278
|
_convertedCaps[`${key}`] = value;
|
|
240
279
|
}
|
package/docs/build/FileSystem.js
CHANGED
package/docs/build/Nightmare.js
CHANGED
|
@@ -882,6 +882,8 @@ class Nightmare extends Helper {
|
|
|
882
882
|
*
|
|
883
883
|
* @param {string|function} fn function to be executed in browser context.
|
|
884
884
|
* @param {...any} args to be passed to function.
|
|
885
|
+
* @returns {Promise<any>} script return value
|
|
886
|
+
*
|
|
885
887
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
886
888
|
*
|
|
887
889
|
*
|
|
@@ -916,6 +918,8 @@ class Nightmare extends Helper {
|
|
|
916
918
|
*
|
|
917
919
|
* @param {string|function} fn function to be executed in browser context.
|
|
918
920
|
* @param {...any} args to be passed to function.
|
|
921
|
+
* @returns {Promise<any>} script return value
|
|
922
|
+
*
|
|
919
923
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
920
924
|
*
|
|
921
925
|
*
|
package/docs/build/Playwright.js
CHANGED
|
@@ -47,7 +47,6 @@ const {
|
|
|
47
47
|
setRestartStrategy, restartsSession, restartsContext, restartsBrowser,
|
|
48
48
|
} = require('./extras/PlaywrightRestartOpts');
|
|
49
49
|
const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
|
|
50
|
-
const { highlightElement } = require('./scripts/highlightElement');
|
|
51
50
|
|
|
52
51
|
const pathSeparator = path.sep;
|
|
53
52
|
|
|
@@ -94,7 +93,7 @@ const pathSeparator = path.sep;
|
|
|
94
93
|
* @prop {string[]} [ignoreLog] - An array with console message types that are not logged to debug log. Default value is `['warning', 'log']`. E.g. you can set `[]` to log all messages. See all possible [values](https://playwright.dev/docs/api/class-consolemessage#console-message-type).
|
|
95
94
|
* @prop {boolean} [ignoreHTTPSErrors] - Allows access to untrustworthy pages, e.g. to a page with an expired certificate. Default value is `false`
|
|
96
95
|
* @prop {boolean} [bypassCSP] - bypass Content Security Policy or CSP
|
|
97
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
96
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
98
97
|
*/
|
|
99
98
|
const config = {};
|
|
100
99
|
|
|
@@ -482,6 +481,7 @@ class Playwright extends Helper {
|
|
|
482
481
|
contextOptions.httpCredentials = this.options.basicAuth;
|
|
483
482
|
this.isAuthenticated = true;
|
|
484
483
|
}
|
|
484
|
+
if (this.options.bypassCSP) contextOptions.bypassCSP = this.options.bypassCSP;
|
|
485
485
|
if (this.options.recordVideo) contextOptions.recordVideo = this.options.recordVideo;
|
|
486
486
|
if (this.storageState) contextOptions.storageState = this.storageState;
|
|
487
487
|
if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
|
|
@@ -834,8 +834,9 @@ class Playwright extends Helper {
|
|
|
834
834
|
|
|
835
835
|
async _stopBrowser() {
|
|
836
836
|
this.withinLocator = null;
|
|
837
|
-
this._setPage(null);
|
|
837
|
+
await this._setPage(null);
|
|
838
838
|
this.context = null;
|
|
839
|
+
this.frame = null;
|
|
839
840
|
popupStore.clear();
|
|
840
841
|
await this.browser.close();
|
|
841
842
|
}
|
|
@@ -857,8 +858,8 @@ class Playwright extends Helper {
|
|
|
857
858
|
await this.switchTo(null);
|
|
858
859
|
return frame.reduce((p, frameLocator) => p.then(() => this.switchTo(frameLocator)), Promise.resolve());
|
|
859
860
|
}
|
|
860
|
-
await this.switchTo(
|
|
861
|
-
this.withinLocator = new Locator(
|
|
861
|
+
await this.switchTo(frame);
|
|
862
|
+
this.withinLocator = new Locator(frame);
|
|
862
863
|
return;
|
|
863
864
|
}
|
|
864
865
|
|
|
@@ -874,6 +875,7 @@ class Playwright extends Helper {
|
|
|
874
875
|
this.withinLocator = null;
|
|
875
876
|
this.context = await this.page;
|
|
876
877
|
this.contextLocator = null;
|
|
878
|
+
this.frame = null;
|
|
877
879
|
}
|
|
878
880
|
|
|
879
881
|
_extractDataFromPerformanceTiming(timing, ...dataNames) {
|
|
@@ -1298,6 +1300,9 @@ class Playwright extends Helper {
|
|
|
1298
1300
|
*/
|
|
1299
1301
|
async _locate(locator) {
|
|
1300
1302
|
const context = await this.context || await this._getContext();
|
|
1303
|
+
|
|
1304
|
+
if (this.frame) return findElements(this.frame, locator);
|
|
1305
|
+
|
|
1301
1306
|
return findElements(context, locator);
|
|
1302
1307
|
}
|
|
1303
1308
|
|
|
@@ -2008,7 +2013,7 @@ class Playwright extends Helper {
|
|
|
2008
2013
|
|
|
2009
2014
|
await el.clear();
|
|
2010
2015
|
|
|
2011
|
-
highlightActiveElement.call(this, el
|
|
2016
|
+
await highlightActiveElement.call(this, el);
|
|
2012
2017
|
|
|
2013
2018
|
await el.type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
2014
2019
|
|
|
@@ -2038,7 +2043,7 @@ class Playwright extends Helper {
|
|
|
2038
2043
|
|
|
2039
2044
|
const el = els[0];
|
|
2040
2045
|
|
|
2041
|
-
highlightActiveElement.call(this, el
|
|
2046
|
+
await highlightActiveElement.call(this, el);
|
|
2042
2047
|
|
|
2043
2048
|
await el.clear();
|
|
2044
2049
|
|
|
@@ -2064,7 +2069,7 @@ class Playwright extends Helper {
|
|
|
2064
2069
|
async appendField(field, value) {
|
|
2065
2070
|
const els = await findFields.call(this, field);
|
|
2066
2071
|
assertElementExists(els, field, 'Field');
|
|
2067
|
-
highlightActiveElement.call(this, els[0]
|
|
2072
|
+
await highlightActiveElement.call(this, els[0]);
|
|
2068
2073
|
await els[0].press('End');
|
|
2069
2074
|
await els[0].type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
2070
2075
|
return this._waitForAction();
|
|
@@ -2166,7 +2171,7 @@ class Playwright extends Helper {
|
|
|
2166
2171
|
assertElementExists(els, select, 'Selectable field');
|
|
2167
2172
|
const el = els[0];
|
|
2168
2173
|
|
|
2169
|
-
highlightActiveElement.call(this, el
|
|
2174
|
+
await highlightActiveElement.call(this, el);
|
|
2170
2175
|
|
|
2171
2176
|
if (!Array.isArray(option)) option = [option];
|
|
2172
2177
|
|
|
@@ -2554,11 +2559,11 @@ class Playwright extends Helper {
|
|
|
2554
2559
|
* @returns {Promise<any>}
|
|
2555
2560
|
*/
|
|
2556
2561
|
async executeScript(fn, arg) {
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2562
|
+
if (this.context && this.context.constructor.name === 'FrameLocator') {
|
|
2563
|
+
// switching to iframe context
|
|
2564
|
+
return this.context.locator(':root').evaluate(fn, arg);
|
|
2560
2565
|
}
|
|
2561
|
-
return
|
|
2566
|
+
return this.page.evaluate.apply(this.page, [fn, arg]);
|
|
2562
2567
|
}
|
|
2563
2568
|
|
|
2564
2569
|
/**
|
|
@@ -3312,7 +3317,7 @@ class Playwright extends Helper {
|
|
|
3312
3317
|
}
|
|
3313
3318
|
|
|
3314
3319
|
async _getContext() {
|
|
3315
|
-
if (this.context && this.context.constructor.name === '
|
|
3320
|
+
if (this.context && this.context.constructor.name === 'FrameLocator') {
|
|
3316
3321
|
return this.context;
|
|
3317
3322
|
}
|
|
3318
3323
|
return this.page;
|
|
@@ -3417,6 +3422,14 @@ class Playwright extends Helper {
|
|
|
3417
3422
|
}, [locator.value, text, $XPath.toString()], { timeout: waitTimeout });
|
|
3418
3423
|
}
|
|
3419
3424
|
} else {
|
|
3425
|
+
// we have this as https://github.com/microsoft/playwright/issues/26829 is not yet implemented
|
|
3426
|
+
if (this.frame) {
|
|
3427
|
+
const { setTimeout } = require('timers/promises');
|
|
3428
|
+
await setTimeout(waitTimeout);
|
|
3429
|
+
waiter = await this.frame.locator(`:has-text('${text}')`).first().isVisible();
|
|
3430
|
+
if (!waiter) throw new Error(`Text "${text}" was not found on page after ${waitTimeout / 1000} sec`);
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3420
3433
|
waiter = contextObject.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: waitTimeout });
|
|
3421
3434
|
}
|
|
3422
3435
|
return waiter.catch((err) => {
|
|
@@ -3480,39 +3493,42 @@ class Playwright extends Helper {
|
|
|
3480
3493
|
}
|
|
3481
3494
|
|
|
3482
3495
|
if (locator >= 0 && locator < childFrames.length) {
|
|
3483
|
-
this.context =
|
|
3496
|
+
this.context = await this.page.frameLocator('iframe').nth(locator);
|
|
3484
3497
|
this.contextLocator = locator;
|
|
3485
3498
|
} else {
|
|
3486
3499
|
throw new Error('Element #invalidIframeSelector was not found by text|CSS|XPath');
|
|
3487
3500
|
}
|
|
3488
3501
|
return;
|
|
3489
3502
|
}
|
|
3490
|
-
let contentFrame;
|
|
3491
3503
|
|
|
3492
3504
|
if (!locator) {
|
|
3493
|
-
this.context =
|
|
3505
|
+
this.context = this.page;
|
|
3494
3506
|
this.contextLocator = null;
|
|
3507
|
+
this.frame = null;
|
|
3495
3508
|
return;
|
|
3496
3509
|
}
|
|
3497
3510
|
|
|
3498
3511
|
// iframe by selector
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
contentFrame = await this.page.frames()[1];
|
|
3505
|
-
// get content of the iframe using its name
|
|
3506
|
-
} else if (locator.toLowerCase().includes('name=')) {
|
|
3507
|
-
const frameName = locator.split('=')[1].replace(/"/g, '').replaceAll(/]/g, '');
|
|
3508
|
-
contentFrame = await this.page.frame(frameName);
|
|
3512
|
+
locator = buildLocatorString(new Locator(locator, 'css'));
|
|
3513
|
+
const frame = await this._locateElement(locator);
|
|
3514
|
+
|
|
3515
|
+
if (!frame) {
|
|
3516
|
+
throw new Error(`Frame ${JSON.stringify(locator)} was not found by text|CSS|XPath`);
|
|
3509
3517
|
}
|
|
3510
3518
|
|
|
3519
|
+
if (this.frame) {
|
|
3520
|
+
this.frame = await this.frame.frameLocator(locator);
|
|
3521
|
+
} else {
|
|
3522
|
+
this.frame = await this.page.frameLocator(locator);
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
const contentFrame = this.frame;
|
|
3526
|
+
|
|
3511
3527
|
if (contentFrame) {
|
|
3512
3528
|
this.context = contentFrame;
|
|
3513
3529
|
this.contextLocator = null;
|
|
3514
3530
|
} else {
|
|
3515
|
-
this.context =
|
|
3531
|
+
this.context = this.page.frame(this.page.frames()[1].name());
|
|
3516
3532
|
this.contextLocator = locator;
|
|
3517
3533
|
}
|
|
3518
3534
|
}
|
|
@@ -4268,7 +4284,7 @@ async function findElement(matcher, locator) {
|
|
|
4268
4284
|
if (locator.react) return findReact(matcher, locator);
|
|
4269
4285
|
locator = new Locator(locator, 'css');
|
|
4270
4286
|
|
|
4271
|
-
return matcher.locator(buildLocatorString(locator));
|
|
4287
|
+
return matcher.locator(buildLocatorString(locator)).first();
|
|
4272
4288
|
}
|
|
4273
4289
|
|
|
4274
4290
|
async function getVisibleElements(elements) {
|
|
@@ -4298,7 +4314,7 @@ async function proceedClick(locator, context = null, options = {}) {
|
|
|
4298
4314
|
assertElementExists(els, locator, 'Clickable element');
|
|
4299
4315
|
}
|
|
4300
4316
|
|
|
4301
|
-
highlightActiveElement.call(this, els[0]
|
|
4317
|
+
await highlightActiveElement.call(this, els[0]);
|
|
4302
4318
|
|
|
4303
4319
|
/*
|
|
4304
4320
|
using the force true options itself but instead dispatching a click
|
|
@@ -4348,13 +4364,9 @@ async function proceedSee(assertType, text, context, strict = false) {
|
|
|
4348
4364
|
let allText;
|
|
4349
4365
|
|
|
4350
4366
|
if (!context) {
|
|
4351
|
-
|
|
4352
|
-
if (el && !el.getProperty) {
|
|
4353
|
-
// Fallback to body
|
|
4354
|
-
el = await this.page.$('body');
|
|
4355
|
-
}
|
|
4367
|
+
const el = await this.context;
|
|
4356
4368
|
|
|
4357
|
-
allText = [await el.innerText()];
|
|
4369
|
+
allText = [await el.locator('body').innerText()];
|
|
4358
4370
|
description = 'web application';
|
|
4359
4371
|
} else {
|
|
4360
4372
|
const locator = new Locator(context, 'css');
|
|
@@ -4526,7 +4538,9 @@ async function elementSelected(element) {
|
|
|
4526
4538
|
|
|
4527
4539
|
function isFrameLocator(locator) {
|
|
4528
4540
|
locator = new Locator(locator);
|
|
4529
|
-
if (locator.isFrame())
|
|
4541
|
+
if (locator.isFrame()) {
|
|
4542
|
+
return locator.value;
|
|
4543
|
+
}
|
|
4530
4544
|
return false;
|
|
4531
4545
|
}
|
|
4532
4546
|
|
|
@@ -4721,10 +4735,14 @@ async function saveTraceForContext(context, name) {
|
|
|
4721
4735
|
return fileName;
|
|
4722
4736
|
}
|
|
4723
4737
|
|
|
4724
|
-
function highlightActiveElement(element
|
|
4725
|
-
if (
|
|
4726
|
-
|
|
4727
|
-
|
|
4738
|
+
async function highlightActiveElement(element) {
|
|
4739
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
4740
|
+
await element.evaluate(el => {
|
|
4741
|
+
const prevStyle = el.style.boxShadow;
|
|
4742
|
+
el.style.boxShadow = '0px 0px 4px 3px rgba(255, 0, 0, 0.7)';
|
|
4743
|
+
setTimeout(() => el.style.boxShadow = prevStyle, 2000);
|
|
4744
|
+
});
|
|
4745
|
+
}
|
|
4728
4746
|
}
|
|
4729
4747
|
|
|
4730
4748
|
const createAdvancedTestResults = (url, dataToCheck, requests) => {
|
package/docs/build/Protractor.js
CHANGED
|
@@ -1525,6 +1525,8 @@ class Protractor extends Helper {
|
|
|
1525
1525
|
*
|
|
1526
1526
|
* @param {string|function} fn function to be executed in browser context.
|
|
1527
1527
|
* @param {...any} args to be passed to function.
|
|
1528
|
+
* @returns {Promise<any>} script return value
|
|
1529
|
+
*
|
|
1528
1530
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
1529
1531
|
*
|
|
1530
1532
|
*/
|
|
@@ -1556,6 +1558,8 @@ class Protractor extends Helper {
|
|
|
1556
1558
|
*
|
|
1557
1559
|
* @param {string|function} fn function to be executed in browser context.
|
|
1558
1560
|
* @param {...any} args to be passed to function.
|
|
1561
|
+
* @returns {Promise<any>} script return value
|
|
1562
|
+
*
|
|
1559
1563
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
1560
1564
|
*
|
|
1561
1565
|
*/
|
package/docs/build/Puppeteer.js
CHANGED
|
@@ -69,7 +69,7 @@ const consoleLogStore = new Console();
|
|
|
69
69
|
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
70
70
|
* @prop {string} [browser=chrome] - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
71
71
|
* @prop {object} [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
72
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
72
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
73
73
|
*/
|
|
74
74
|
const config = {};
|
|
75
75
|
|
|
@@ -612,8 +612,8 @@ class Puppeteer extends Helper {
|
|
|
612
612
|
return this.switchTo(null)
|
|
613
613
|
.then(() => frame.reduce((p, frameLocator) => p.then(() => this.switchTo(frameLocator)), Promise.resolve()));
|
|
614
614
|
}
|
|
615
|
-
await this.switchTo(
|
|
616
|
-
this.withinLocator = new Locator(
|
|
615
|
+
await this.switchTo(frame);
|
|
616
|
+
this.withinLocator = new Locator(frame);
|
|
617
617
|
return;
|
|
618
618
|
}
|
|
619
619
|
|
|
@@ -2314,6 +2314,8 @@ class Puppeteer extends Helper {
|
|
|
2314
2314
|
*
|
|
2315
2315
|
* @param {string|function} fn function to be executed in browser context.
|
|
2316
2316
|
* @param {...any} args to be passed to function.
|
|
2317
|
+
* @returns {Promise<any>} script return value
|
|
2318
|
+
*
|
|
2317
2319
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
2318
2320
|
*
|
|
2319
2321
|
*
|
|
@@ -2351,6 +2353,8 @@ class Puppeteer extends Helper {
|
|
|
2351
2353
|
*
|
|
2352
2354
|
* @param {string|function} fn function to be executed in browser context.
|
|
2353
2355
|
* @param {...any} args to be passed to function.
|
|
2356
|
+
* @returns {Promise<any>} script return value
|
|
2357
|
+
*
|
|
2354
2358
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
2355
2359
|
*
|
|
2356
2360
|
*
|
|
@@ -2942,7 +2946,7 @@ class Puppeteer extends Helper {
|
|
|
2942
2946
|
assertElementExists(els, locator);
|
|
2943
2947
|
|
|
2944
2948
|
return this.waitForFunction(isElementClickable, [els[0]], waitTimeout).catch(async (e) => {
|
|
2945
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
2949
|
+
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2946
2950
|
throw new Error(`element ${new Locator(locator).toString()} still not clickable after ${waitTimeout || this.options.waitForTimeout / 1000} sec`);
|
|
2947
2951
|
} else {
|
|
2948
2952
|
throw e;
|
|
@@ -3096,7 +3100,7 @@ class Puppeteer extends Helper {
|
|
|
3096
3100
|
return currUrl.indexOf(urlPart) > -1;
|
|
3097
3101
|
}, { timeout: waitTimeout }, urlPart).catch(async (e) => {
|
|
3098
3102
|
const currUrl = await this._getPageUrl(); // Required because the waitForFunction can't return data.
|
|
3099
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
3103
|
+
if (/Waiting failed:/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
3100
3104
|
throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`);
|
|
3101
3105
|
} else {
|
|
3102
3106
|
throw e;
|
|
@@ -3130,7 +3134,7 @@ class Puppeteer extends Helper {
|
|
|
3130
3134
|
return currUrl.indexOf(urlPart) > -1;
|
|
3131
3135
|
}, { timeout: waitTimeout }, urlPart).catch(async (e) => {
|
|
3132
3136
|
const currUrl = await this._getPageUrl(); // Required because the waitForFunction can't return data.
|
|
3133
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
3137
|
+
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
3134
3138
|
throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`);
|
|
3135
3139
|
} else {
|
|
3136
3140
|
throw e;
|
|
@@ -3427,6 +3431,10 @@ async function findElements(matcher, locator) {
|
|
|
3427
3431
|
if (locator.react) return findReact(matcher.executionContext(), locator);
|
|
3428
3432
|
locator = new Locator(locator, 'css');
|
|
3429
3433
|
if (!locator.isXPath()) return matcher.$$(locator.simplify());
|
|
3434
|
+
// puppeteer version < 19.4.0 is no longer supported. This one is backward support.
|
|
3435
|
+
if (puppeteer.default?.defaultBrowserRevision) {
|
|
3436
|
+
return matcher.$$(`xpath/${locator.value}`);
|
|
3437
|
+
}
|
|
3430
3438
|
return matcher.$x(locator.value);
|
|
3431
3439
|
}
|
|
3432
3440
|
|
|
@@ -3681,7 +3689,10 @@ async function elementSelected(element) {
|
|
|
3681
3689
|
|
|
3682
3690
|
function isFrameLocator(locator) {
|
|
3683
3691
|
locator = new Locator(locator);
|
|
3684
|
-
if (locator.isFrame())
|
|
3692
|
+
if (locator.isFrame()) {
|
|
3693
|
+
const _locator = new Locator(locator);
|
|
3694
|
+
return _locator.value;
|
|
3695
|
+
}
|
|
3685
3696
|
return false;
|
|
3686
3697
|
}
|
|
3687
3698
|
|
|
@@ -3799,7 +3810,7 @@ function getNormalizedKey(key) {
|
|
|
3799
3810
|
}
|
|
3800
3811
|
|
|
3801
3812
|
function highlightActiveElement(element, context) {
|
|
3802
|
-
if (
|
|
3803
|
-
|
|
3804
|
-
|
|
3813
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
3814
|
+
highlightElement(element, context);
|
|
3815
|
+
}
|
|
3805
3816
|
}
|
package/docs/build/TestCafe.js
CHANGED
|
@@ -1270,6 +1270,8 @@ class TestCafe extends Helper {
|
|
|
1270
1270
|
*
|
|
1271
1271
|
* @param {string|function} fn function to be executed in browser context.
|
|
1272
1272
|
* @param {...any} args to be passed to function.
|
|
1273
|
+
* @returns {Promise<any>} script return value
|
|
1274
|
+
*
|
|
1273
1275
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
1274
1276
|
*
|
|
1275
1277
|
*
|
package/docs/build/WebDriver.js
CHANGED
|
@@ -62,7 +62,7 @@ const webRoot = 'body';
|
|
|
62
62
|
* @prop {object} [desiredCapabilities] Selenium's [desired capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities).
|
|
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
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false
|
|
65
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
66
66
|
*/
|
|
67
67
|
const config = {};
|
|
68
68
|
|
|
@@ -2173,6 +2173,8 @@ class WebDriver extends Helper {
|
|
|
2173
2173
|
*
|
|
2174
2174
|
* @param {string|function} fn function to be executed in browser context.
|
|
2175
2175
|
* @param {...any} args to be passed to function.
|
|
2176
|
+
* @returns {Promise<any>} script return value
|
|
2177
|
+
*
|
|
2176
2178
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
2177
2179
|
*
|
|
2178
2180
|
*
|
|
@@ -2207,6 +2209,8 @@ class WebDriver extends Helper {
|
|
|
2207
2209
|
*
|
|
2208
2210
|
* @param {string|function} fn function to be executed in browser context.
|
|
2209
2211
|
* @param {...any} args to be passed to function.
|
|
2212
|
+
* @returns {Promise<any>} script return value
|
|
2213
|
+
*
|
|
2210
2214
|
* ⚠️ returns a _promise_ which is synchronized internally by recorder
|
|
2211
2215
|
*
|
|
2212
2216
|
*
|
|
@@ -4079,9 +4083,9 @@ function isModifierKey(key) {
|
|
|
4079
4083
|
}
|
|
4080
4084
|
|
|
4081
4085
|
function highlightActiveElement(element) {
|
|
4082
|
-
if (
|
|
4083
|
-
|
|
4084
|
-
|
|
4086
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
4087
|
+
highlightElement(element, this.browser);
|
|
4088
|
+
}
|
|
4085
4089
|
}
|
|
4086
4090
|
|
|
4087
4091
|
function prepareLocateFn(context) {
|