codeceptjs 3.5.0 → 3.5.1-2.beta.7
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 +24 -25
- package/lib/actor.js +6 -3
- package/lib/ai.js +12 -3
- package/lib/cli.js +12 -2
- package/lib/codecept.js +4 -0
- package/lib/colorUtils.js +10 -0
- package/lib/command/definitions.js +2 -7
- package/lib/command/dryRun.js +2 -1
- package/lib/command/info.js +24 -0
- package/lib/command/init.js +51 -5
- package/lib/command/run-multiple/collection.js +17 -5
- package/lib/command/run-multiple.js +4 -2
- package/lib/command/run-workers.js +66 -4
- package/lib/command/run.js +7 -0
- package/lib/command/workers/runTests.js +39 -0
- package/lib/data/context.js +14 -6
- package/lib/event.js +4 -0
- package/lib/helper/ApiDataFactory.js +2 -1
- package/lib/helper/Appium.js +73 -24
- package/lib/helper/Expect.js +422 -0
- package/lib/helper/FileSystem.js +1 -1
- package/lib/helper/GraphQL.js +25 -0
- package/lib/helper/Nightmare.js +9 -4
- package/lib/helper/OpenAI.js +14 -10
- package/lib/helper/Playwright.js +1205 -288
- package/lib/helper/Protractor.js +11 -6
- package/lib/helper/Puppeteer.js +173 -61
- package/lib/helper/TestCafe.js +44 -9
- package/lib/helper/WebDriver.js +231 -82
- package/lib/helper/errors/ElementNotFound.js +2 -1
- package/lib/helper/extras/PlaywrightReactVueLocator.js +38 -0
- package/lib/helper/scripts/blurElement.js +17 -0
- package/lib/helper/scripts/focusElement.js +17 -0
- package/lib/helper/scripts/highlightElement.js +2 -2
- package/lib/html.js +3 -3
- package/lib/interfaces/bdd.js +1 -1
- package/lib/interfaces/gherkin.js +37 -3
- package/lib/interfaces/scenarioConfig.js +1 -0
- package/lib/locator.js +17 -4
- package/lib/mochaFactory.js +2 -1
- package/lib/output.js +1 -1
- package/lib/pause.js +12 -9
- package/lib/plugin/autoLogin.js +45 -10
- package/lib/plugin/heal.js +47 -17
- package/lib/plugin/retryFailedStep.js +10 -1
- package/lib/plugin/retryTo.js +2 -4
- package/lib/plugin/selenoid.js +6 -1
- package/lib/plugin/standardActingHelpers.js +0 -2
- package/lib/plugin/stepByStepReport.js +2 -2
- package/lib/plugin/tryTo.js +5 -7
- package/lib/plugin/wdio.js +0 -1
- package/lib/recorder.js +20 -9
- package/lib/session.js +1 -1
- package/lib/step.js +30 -11
- package/lib/ui.js +1 -0
- package/lib/utils.js +18 -1
- package/lib/workers.js +28 -3
- package/package.json +108 -98
- package/translations/de-DE.js +5 -0
- package/translations/fr-FR.js +14 -1
- package/translations/it-IT.js +1 -0
- package/translations/ja-JP.js +5 -0
- package/translations/pl-PL.js +5 -0
- package/translations/pt-BR.js +1 -0
- package/translations/ru-RU.js +1 -0
- package/translations/zh-CN.js +5 -0
- package/translations/zh-TW.js +5 -0
- package/typings/index.d.ts +8 -6
- package/typings/promiseBasedTypes.d.ts +784 -822
- package/typings/types.d.ts +1214 -727
- package/CHANGELOG.md +0 -2492
- package/docs/advanced.md +0 -351
- package/docs/ai.md +0 -246
- package/docs/api.md +0 -323
- package/docs/basics.md +0 -980
- package/docs/bdd.md +0 -535
- package/docs/best.md +0 -237
- package/docs/books.md +0 -37
- package/docs/bootstrap.md +0 -135
- package/docs/build/ApiDataFactory.js +0 -409
- package/docs/build/Appium.js +0 -1978
- package/docs/build/FileSystem.js +0 -228
- package/docs/build/GraphQL.js +0 -204
- package/docs/build/GraphQLDataFactory.js +0 -309
- package/docs/build/JSONResponse.js +0 -338
- package/docs/build/Mochawesome.js +0 -71
- package/docs/build/Nightmare.js +0 -2147
- package/docs/build/OpenAI.js +0 -122
- package/docs/build/Playwright.js +0 -4134
- package/docs/build/Polly.js +0 -42
- package/docs/build/Protractor.js +0 -2701
- package/docs/build/Puppeteer.js +0 -3743
- package/docs/build/REST.js +0 -344
- package/docs/build/SeleniumWebdriver.js +0 -76
- package/docs/build/TestCafe.js +0 -2059
- package/docs/build/WebDriver.js +0 -4042
- package/docs/changelog.md +0 -2501
- package/docs/commands.md +0 -254
- package/docs/community-helpers.md +0 -58
- package/docs/configuration.md +0 -157
- package/docs/continuous-integration.md +0 -22
- package/docs/custom-helpers.md +0 -306
- package/docs/data.md +0 -375
- package/docs/detox.md +0 -235
- package/docs/docker.md +0 -137
- package/docs/email.md +0 -183
- package/docs/examples.md +0 -149
- package/docs/helpers/ApiDataFactory.md +0 -266
- package/docs/helpers/Appium.md +0 -1317
- package/docs/helpers/Detox.md +0 -586
- package/docs/helpers/FileSystem.md +0 -152
- package/docs/helpers/GraphQL.md +0 -130
- package/docs/helpers/GraphQLDataFactory.md +0 -226
- package/docs/helpers/JSONResponse.md +0 -254
- package/docs/helpers/Mochawesome.md +0 -8
- package/docs/helpers/MockRequest.md +0 -377
- package/docs/helpers/Nightmare.md +0 -1258
- package/docs/helpers/OpenAI.md +0 -70
- package/docs/helpers/Playwright.md +0 -2250
- package/docs/helpers/Polly.md +0 -44
- package/docs/helpers/Puppeteer-firefox.md +0 -86
- package/docs/helpers/Puppeteer.md +0 -2147
- package/docs/helpers/REST.md +0 -218
- package/docs/helpers/TestCafe.md +0 -1224
- package/docs/helpers/WebDriver.md +0 -2325
- package/docs/hooks.md +0 -340
- package/docs/index.md +0 -111
- package/docs/installation.md +0 -75
- package/docs/internal-api.md +0 -265
- package/docs/locators.md +0 -331
- package/docs/mobile-react-native-locators.md +0 -67
- package/docs/mobile.md +0 -344
- package/docs/nightmare.md +0 -223
- package/docs/pageobjects.md +0 -291
- package/docs/parallel.md +0 -288
- package/docs/playwright.md +0 -609
- package/docs/plugins.md +0 -1225
- package/docs/puppeteer.md +0 -316
- package/docs/quickstart.md +0 -163
- package/docs/react.md +0 -69
- package/docs/reports.md +0 -392
- package/docs/secrets.md +0 -36
- package/docs/shadow.md +0 -68
- package/docs/shared/keys.mustache +0 -31
- package/docs/shared/react.mustache +0 -1
- package/docs/testcafe.md +0 -174
- package/docs/translation.md +0 -247
- package/docs/tutorial.md +0 -271
- package/docs/typescript.md +0 -180
- package/docs/ui.md +0 -59
- package/docs/videos.md +0 -28
- package/docs/visual.md +0 -202
- package/docs/vue.md +0 -121
- package/docs/webapi/amOnPage.mustache +0 -11
- package/docs/webapi/appendField.mustache +0 -11
- package/docs/webapi/attachFile.mustache +0 -12
- package/docs/webapi/checkOption.mustache +0 -13
- package/docs/webapi/clearCookie.mustache +0 -10
- package/docs/webapi/clearField.mustache +0 -9
- package/docs/webapi/click.mustache +0 -25
- package/docs/webapi/clickLink.mustache +0 -8
- package/docs/webapi/closeCurrentTab.mustache +0 -7
- package/docs/webapi/closeOtherTabs.mustache +0 -8
- package/docs/webapi/dontSee.mustache +0 -11
- package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/dontSeeCookie.mustache +0 -8
- package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
- package/docs/webapi/dontSeeElement.mustache +0 -8
- package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
- package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
- package/docs/webapi/dontSeeInField.mustache +0 -11
- package/docs/webapi/dontSeeInSource.mustache +0 -8
- package/docs/webapi/dontSeeInTitle.mustache +0 -8
- package/docs/webapi/doubleClick.mustache +0 -13
- package/docs/webapi/downloadFile.mustache +0 -12
- package/docs/webapi/dragAndDrop.mustache +0 -9
- package/docs/webapi/dragSlider.mustache +0 -11
- package/docs/webapi/executeAsyncScript.mustache +0 -24
- package/docs/webapi/executeScript.mustache +0 -26
- package/docs/webapi/fillField.mustache +0 -16
- package/docs/webapi/forceClick.mustache +0 -28
- package/docs/webapi/forceRightClick.mustache +0 -18
- package/docs/webapi/grabAllWindowHandles.mustache +0 -7
- package/docs/webapi/grabAttributeFrom.mustache +0 -10
- package/docs/webapi/grabAttributeFromAll.mustache +0 -9
- package/docs/webapi/grabBrowserLogs.mustache +0 -9
- package/docs/webapi/grabCookie.mustache +0 -11
- package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
- package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
- package/docs/webapi/grabCurrentUrl.mustache +0 -9
- package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
- package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
- package/docs/webapi/grabElementBoundingRect.mustache +0 -20
- package/docs/webapi/grabGeoLocation.mustache +0 -8
- package/docs/webapi/grabHTMLFrom.mustache +0 -10
- package/docs/webapi/grabHTMLFromAll.mustache +0 -9
- package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
- package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
- package/docs/webapi/grabPageScrollPosition.mustache +0 -8
- package/docs/webapi/grabPopupText.mustache +0 -5
- package/docs/webapi/grabSource.mustache +0 -8
- package/docs/webapi/grabTextFrom.mustache +0 -10
- package/docs/webapi/grabTextFromAll.mustache +0 -9
- package/docs/webapi/grabTitle.mustache +0 -8
- package/docs/webapi/grabValueFrom.mustache +0 -9
- package/docs/webapi/grabValueFromAll.mustache +0 -8
- package/docs/webapi/moveCursorTo.mustache +0 -12
- package/docs/webapi/openNewTab.mustache +0 -7
- package/docs/webapi/pressKey.mustache +0 -12
- package/docs/webapi/pressKeyDown.mustache +0 -12
- package/docs/webapi/pressKeyUp.mustache +0 -12
- package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
- package/docs/webapi/refreshPage.mustache +0 -6
- package/docs/webapi/resizeWindow.mustache +0 -6
- package/docs/webapi/rightClick.mustache +0 -14
- package/docs/webapi/saveElementScreenshot.mustache +0 -10
- package/docs/webapi/saveScreenshot.mustache +0 -12
- package/docs/webapi/say.mustache +0 -10
- package/docs/webapi/scrollIntoView.mustache +0 -11
- package/docs/webapi/scrollPageToBottom.mustache +0 -6
- package/docs/webapi/scrollPageToTop.mustache +0 -6
- package/docs/webapi/scrollTo.mustache +0 -12
- package/docs/webapi/see.mustache +0 -11
- package/docs/webapi/seeAttributesOnElements.mustache +0 -9
- package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
- package/docs/webapi/seeCookie.mustache +0 -8
- package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
- package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
- package/docs/webapi/seeElement.mustache +0 -8
- package/docs/webapi/seeElementInDOM.mustache +0 -8
- package/docs/webapi/seeInCurrentUrl.mustache +0 -8
- package/docs/webapi/seeInField.mustache +0 -12
- package/docs/webapi/seeInPopup.mustache +0 -8
- package/docs/webapi/seeInSource.mustache +0 -7
- package/docs/webapi/seeInTitle.mustache +0 -8
- package/docs/webapi/seeNumberOfElements.mustache +0 -11
- package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/seeTextEquals.mustache +0 -9
- package/docs/webapi/seeTitleEquals.mustache +0 -8
- package/docs/webapi/selectOption.mustache +0 -21
- package/docs/webapi/setCookie.mustache +0 -16
- package/docs/webapi/setGeoLocation.mustache +0 -12
- package/docs/webapi/switchTo.mustache +0 -9
- package/docs/webapi/switchToNextTab.mustache +0 -10
- package/docs/webapi/switchToPreviousTab.mustache +0 -10
- package/docs/webapi/type.mustache +0 -21
- package/docs/webapi/uncheckOption.mustache +0 -13
- package/docs/webapi/wait.mustache +0 -8
- package/docs/webapi/waitForClickable.mustache +0 -11
- package/docs/webapi/waitForDetached.mustache +0 -10
- package/docs/webapi/waitForElement.mustache +0 -11
- package/docs/webapi/waitForEnabled.mustache +0 -6
- package/docs/webapi/waitForFunction.mustache +0 -17
- package/docs/webapi/waitForInvisible.mustache +0 -10
- package/docs/webapi/waitForText.mustache +0 -13
- package/docs/webapi/waitForValue.mustache +0 -10
- package/docs/webapi/waitForVisible.mustache +0 -10
- package/docs/webapi/waitInUrl.mustache +0 -9
- package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
- package/docs/webapi/waitToHide.mustache +0 -10
- package/docs/webapi/waitUrlEquals.mustache +0 -10
- package/docs/webdriver.md +0 -657
- package/docs/wiki/Books-&-Posts.md +0 -27
- package/docs/wiki/Community-Helpers-&-Plugins.md +0 -49
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -29
- package/docs/wiki/Examples.md +0 -139
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -68
- package/docs/wiki/Home.md +0 -16
- package/docs/wiki/Release-Process.md +0 -24
- package/docs/wiki/Roadmap.md +0 -23
- package/docs/wiki/Tests.md +0 -1393
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -153
- package/docs/wiki/Videos.md +0 -19
package/lib/helper/Protractor.js
CHANGED
|
@@ -631,14 +631,16 @@ class Protractor extends Helper {
|
|
|
631
631
|
* {{> seeInField }}
|
|
632
632
|
*/
|
|
633
633
|
async seeInField(field, value) {
|
|
634
|
-
|
|
634
|
+
const _value = (typeof value === 'boolean') ? value : value.toString();
|
|
635
|
+
return proceedSeeInField.call(this, 'assert', field, _value);
|
|
635
636
|
}
|
|
636
637
|
|
|
637
638
|
/**
|
|
638
639
|
* {{> dontSeeInField }}
|
|
639
640
|
*/
|
|
640
641
|
async dontSeeInField(field, value) {
|
|
641
|
-
|
|
642
|
+
const _value = (typeof value === 'boolean') ? value : value.toString();
|
|
643
|
+
return proceedSeeInField.call(this, 'negate', field, _value);
|
|
642
644
|
}
|
|
643
645
|
|
|
644
646
|
/**
|
|
@@ -1053,7 +1055,7 @@ class Protractor extends Helper {
|
|
|
1053
1055
|
const stream = fs.createWriteStream(outputFile);
|
|
1054
1056
|
stream.write(Buffer.from(png, 'base64'));
|
|
1055
1057
|
stream.end();
|
|
1056
|
-
return new Promise(resolve => stream.on('finish', resolve));
|
|
1058
|
+
return new Promise(resolve => stream.on('finish', resolve)); // eslint-disable-line no-promise-executor-return
|
|
1057
1059
|
};
|
|
1058
1060
|
|
|
1059
1061
|
const res = await this._locate(locator);
|
|
@@ -1076,7 +1078,7 @@ class Protractor extends Helper {
|
|
|
1076
1078
|
const stream = fs.createWriteStream(outputFile);
|
|
1077
1079
|
stream.write(Buffer.from(png, 'base64'));
|
|
1078
1080
|
stream.end();
|
|
1079
|
-
return new Promise(resolve => stream.on('finish', resolve));
|
|
1081
|
+
return new Promise(resolve => stream.on('finish', resolve)); // eslint-disable-line no-promise-executor-return
|
|
1080
1082
|
};
|
|
1081
1083
|
|
|
1082
1084
|
if (!fullPage) {
|
|
@@ -1613,8 +1615,11 @@ class Protractor extends Helper {
|
|
|
1613
1615
|
const body = document.body;
|
|
1614
1616
|
const html = document.documentElement;
|
|
1615
1617
|
window.scrollTo(0, Math.max(
|
|
1616
|
-
body.scrollHeight,
|
|
1617
|
-
|
|
1618
|
+
body.scrollHeight,
|
|
1619
|
+
body.offsetHeight,
|
|
1620
|
+
html.clientHeight,
|
|
1621
|
+
html.scrollHeight,
|
|
1622
|
+
html.offsetHeight
|
|
1618
1623
|
));
|
|
1619
1624
|
});
|
|
1620
1625
|
/* eslint-enable */
|
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -4,6 +4,7 @@ const fsExtra = require('fs-extra');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
const Helper = require('@codeceptjs/helper');
|
|
7
|
+
const { v4: uuidv4 } = require('uuid');
|
|
7
8
|
const Locator = require('../locator');
|
|
8
9
|
const recorder = require('../recorder');
|
|
9
10
|
const store = require('../store');
|
|
@@ -19,11 +20,12 @@ const {
|
|
|
19
20
|
fileExists,
|
|
20
21
|
chunkArray,
|
|
21
22
|
toCamelCase,
|
|
23
|
+
clearString,
|
|
22
24
|
convertCssPropertiesToCamelCase,
|
|
23
25
|
screenshotOutputFolder,
|
|
24
26
|
getNormalizedKeyAttributeValue,
|
|
25
27
|
isModifierKey,
|
|
26
|
-
requireWithFallback,
|
|
28
|
+
requireWithFallback, normalizeSpacesInString,
|
|
27
29
|
} = require('../utils');
|
|
28
30
|
const {
|
|
29
31
|
isColorProperty,
|
|
@@ -35,6 +37,8 @@ const Popup = require('./extras/Popup');
|
|
|
35
37
|
const Console = require('./extras/Console');
|
|
36
38
|
const findReact = require('./extras/React');
|
|
37
39
|
const { highlightElement } = require('./scripts/highlightElement');
|
|
40
|
+
const { blurElement } = require('./scripts/blurElement');
|
|
41
|
+
const { focusElement } = require('./scripts/focusElement');
|
|
38
42
|
|
|
39
43
|
let puppeteer;
|
|
40
44
|
let perfTiming;
|
|
@@ -55,6 +59,8 @@ const consoleLogStore = new Console();
|
|
|
55
59
|
* @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
|
|
56
60
|
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
57
61
|
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
62
|
+
* @prop {boolean} [trace=false] - record [tracing information](https://pptr.dev/api/puppeteer.tracing) with screenshots.
|
|
63
|
+
* @prop {boolean} [keepTraceForPassedTests=false] - save trace for passed tests.
|
|
58
64
|
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to false.
|
|
59
65
|
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to false.
|
|
60
66
|
* @prop {number} [waitForAction=100] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
@@ -67,7 +73,7 @@ const consoleLogStore = new Console();
|
|
|
67
73
|
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
68
74
|
* @prop {string} [browser=chrome] - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
69
75
|
* @prop {object} [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
70
|
-
* @prop {boolean} [highlightElement] - highlight the interacting elements
|
|
76
|
+
* @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
|
|
71
77
|
*/
|
|
72
78
|
const config = {};
|
|
73
79
|
|
|
@@ -90,6 +96,14 @@ const config = {};
|
|
|
90
96
|
*
|
|
91
97
|
* <!-- configuration -->
|
|
92
98
|
*
|
|
99
|
+
* #### Trace Recording Customization
|
|
100
|
+
*
|
|
101
|
+
* Trace recording provides complete information on test execution and includes screenshots, and network requests logged during run.
|
|
102
|
+
* Traces will be saved to `output/trace`
|
|
103
|
+
*
|
|
104
|
+
* * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
|
|
105
|
+
* * `keepTraceForPassedTests`: - save trace for passed tests
|
|
106
|
+
*
|
|
93
107
|
* #### Example #1: Wait for 0 network connections.
|
|
94
108
|
*
|
|
95
109
|
* ```js
|
|
@@ -229,6 +243,7 @@ class Puppeteer extends Helper {
|
|
|
229
243
|
keepBrowserState: false,
|
|
230
244
|
show: false,
|
|
231
245
|
defaultPopupAction: 'accept',
|
|
246
|
+
highlightElement: false,
|
|
232
247
|
};
|
|
233
248
|
|
|
234
249
|
return Object.assign(defaults, config);
|
|
@@ -244,6 +259,7 @@ class Puppeteer extends Helper {
|
|
|
244
259
|
headless: !this.options.show,
|
|
245
260
|
...this._getOptions(config),
|
|
246
261
|
};
|
|
262
|
+
if (this.puppeteerOptions.headless) this.puppeteerOptions.headless = 'new';
|
|
247
263
|
this.isRemoteBrowser = !!this.puppeteerOptions.browserWSEndpoint;
|
|
248
264
|
popupStore.defaultAction = this.options.defaultPopupAction;
|
|
249
265
|
}
|
|
@@ -278,10 +294,11 @@ class Puppeteer extends Helper {
|
|
|
278
294
|
}
|
|
279
295
|
}
|
|
280
296
|
|
|
281
|
-
async _before() {
|
|
297
|
+
async _before(test) {
|
|
282
298
|
this.sessionPages = {};
|
|
299
|
+
this.currentRunningTest = test;
|
|
283
300
|
recorder.retry({
|
|
284
|
-
retries: 3,
|
|
301
|
+
retries: process.env.FAILED_STEP_RETRIES || 3,
|
|
285
302
|
when: err => {
|
|
286
303
|
if (!err || typeof (err.message) !== 'string') {
|
|
287
304
|
return false;
|
|
@@ -601,8 +618,8 @@ class Puppeteer extends Helper {
|
|
|
601
618
|
return this.switchTo(null)
|
|
602
619
|
.then(() => frame.reduce((p, frameLocator) => p.then(() => this.switchTo(frameLocator)), Promise.resolve()));
|
|
603
620
|
}
|
|
604
|
-
await this.switchTo(
|
|
605
|
-
this.withinLocator = new Locator(
|
|
621
|
+
await this.switchTo(frame);
|
|
622
|
+
this.withinLocator = new Locator(frame);
|
|
606
623
|
return;
|
|
607
624
|
}
|
|
608
625
|
|
|
@@ -644,6 +661,14 @@ class Puppeteer extends Helper {
|
|
|
644
661
|
}
|
|
645
662
|
}
|
|
646
663
|
|
|
664
|
+
if (this.options.trace) {
|
|
665
|
+
const fileName = `${`${global.output_dir}${path.sep}trace${path.sep}${uuidv4()}_${clearString(this.currentRunningTest.title)}`.slice(0, 245)}.json`;
|
|
666
|
+
const dir = path.dirname(fileName);
|
|
667
|
+
if (!fileExists(dir)) fs.mkdirSync(dir);
|
|
668
|
+
await this.page.tracing.start({ screenshots: true, path: fileName });
|
|
669
|
+
this.currentRunningTest.artifacts.trace = fileName;
|
|
670
|
+
}
|
|
671
|
+
|
|
647
672
|
await this.page.goto(url, { waitUntil: this.options.waitForNavigation });
|
|
648
673
|
|
|
649
674
|
const performanceTiming = JSON.parse(await this.page.evaluate(() => JSON.stringify(window.performance.timing)));
|
|
@@ -660,11 +685,13 @@ class Puppeteer extends Helper {
|
|
|
660
685
|
}
|
|
661
686
|
|
|
662
687
|
/**
|
|
663
|
-
* {{> resizeWindow }}
|
|
664
688
|
*
|
|
665
689
|
* Unlike other drivers Puppeteer changes the size of a viewport, not the window!
|
|
666
|
-
* Puppeteer does not control the window of a browser so it can't adjust its real size.
|
|
690
|
+
* Puppeteer does not control the window of a browser, so it can't adjust its real size.
|
|
667
691
|
* It also can't maximize a window.
|
|
692
|
+
*
|
|
693
|
+
* {{> resizeWindow }}
|
|
694
|
+
*
|
|
668
695
|
*/
|
|
669
696
|
async resizeWindow(width, height) {
|
|
670
697
|
if (width === 'maximize') {
|
|
@@ -679,14 +706,14 @@ class Puppeteer extends Helper {
|
|
|
679
706
|
* Set headers for all next requests
|
|
680
707
|
*
|
|
681
708
|
* ```js
|
|
682
|
-
* I.
|
|
709
|
+
* I.setPuppeteerRequestHeaders({
|
|
683
710
|
* 'X-Sent-By': 'CodeceptJS',
|
|
684
711
|
* });
|
|
685
712
|
* ```
|
|
686
713
|
*
|
|
687
714
|
* @param {object} customHeaders headers to set
|
|
688
715
|
*/
|
|
689
|
-
async
|
|
716
|
+
async setPuppeteerRequestHeaders(customHeaders) {
|
|
690
717
|
if (!customHeaders) {
|
|
691
718
|
throw new Error('Cannot send empty headers.');
|
|
692
719
|
}
|
|
@@ -707,6 +734,32 @@ class Puppeteer extends Helper {
|
|
|
707
734
|
return this._waitForAction();
|
|
708
735
|
}
|
|
709
736
|
|
|
737
|
+
/**
|
|
738
|
+
* {{> focus }}
|
|
739
|
+
*
|
|
740
|
+
*/
|
|
741
|
+
async focus(locator) {
|
|
742
|
+
const els = await this._locate(locator);
|
|
743
|
+
assertElementExists(els, locator, 'Element to focus');
|
|
744
|
+
const el = els[0];
|
|
745
|
+
|
|
746
|
+
await el.click();
|
|
747
|
+
await el.focus();
|
|
748
|
+
return this._waitForAction();
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* {{> blur }}
|
|
753
|
+
*
|
|
754
|
+
*/
|
|
755
|
+
async blur(locator) {
|
|
756
|
+
const els = await this._locate(locator);
|
|
757
|
+
assertElementExists(els, locator, 'Element to blur');
|
|
758
|
+
|
|
759
|
+
await blurElement(els[0], this.page);
|
|
760
|
+
return this._waitForAction();
|
|
761
|
+
}
|
|
762
|
+
|
|
710
763
|
/**
|
|
711
764
|
* {{> dragAndDrop }}
|
|
712
765
|
*/
|
|
@@ -738,8 +791,11 @@ class Puppeteer extends Helper {
|
|
|
738
791
|
const body = document.body;
|
|
739
792
|
const html = document.documentElement;
|
|
740
793
|
window.scrollTo(0, Math.max(
|
|
741
|
-
body.scrollHeight,
|
|
742
|
-
|
|
794
|
+
body.scrollHeight,
|
|
795
|
+
body.offsetHeight,
|
|
796
|
+
html.clientHeight,
|
|
797
|
+
html.scrollHeight,
|
|
798
|
+
html.offsetHeight,
|
|
743
799
|
));
|
|
744
800
|
});
|
|
745
801
|
}
|
|
@@ -828,7 +884,7 @@ class Puppeteer extends Helper {
|
|
|
828
884
|
}
|
|
829
885
|
|
|
830
886
|
/**
|
|
831
|
-
* Find a checkbox by providing human
|
|
887
|
+
* Find a checkbox by providing human-readable text:
|
|
832
888
|
* NOTE: Assumes the checkable element exists
|
|
833
889
|
*
|
|
834
890
|
* ```js
|
|
@@ -843,7 +899,7 @@ class Puppeteer extends Helper {
|
|
|
843
899
|
}
|
|
844
900
|
|
|
845
901
|
/**
|
|
846
|
-
* Find a clickable element by providing human
|
|
902
|
+
* Find a clickable element by providing human-readable text:
|
|
847
903
|
*
|
|
848
904
|
* ```js
|
|
849
905
|
* this.helpers['Puppeteer']._locateClickable('Next page').then // ...
|
|
@@ -855,7 +911,7 @@ class Puppeteer extends Helper {
|
|
|
855
911
|
}
|
|
856
912
|
|
|
857
913
|
/**
|
|
858
|
-
* Find field elements by providing human
|
|
914
|
+
* Find field elements by providing human-readable text:
|
|
859
915
|
*
|
|
860
916
|
* ```js
|
|
861
917
|
* this.helpers['Puppeteer']._locateFields('Your email').then // ...
|
|
@@ -865,6 +921,14 @@ class Puppeteer extends Helper {
|
|
|
865
921
|
return findFields.call(this, locator);
|
|
866
922
|
}
|
|
867
923
|
|
|
924
|
+
/**
|
|
925
|
+
* {{> grabWebElements }}
|
|
926
|
+
*
|
|
927
|
+
*/
|
|
928
|
+
async grabWebElements(locator) {
|
|
929
|
+
return this._locate(locator);
|
|
930
|
+
}
|
|
931
|
+
|
|
868
932
|
/**
|
|
869
933
|
* Switch focus to a particular tab by its number. It waits tabs loading and then switch tab
|
|
870
934
|
*
|
|
@@ -1059,7 +1123,7 @@ class Puppeteer extends Helper {
|
|
|
1059
1123
|
* Sets a directory to where save files. Allows to test file downloads.
|
|
1060
1124
|
* Should be used with [FileSystem helper](https://codecept.io/helpers/FileSystem) to check that file were downloaded correctly.
|
|
1061
1125
|
*
|
|
1062
|
-
* By default files are saved to `output/downloads`.
|
|
1126
|
+
* By default, files are saved to `output/downloads`.
|
|
1063
1127
|
* This directory is cleaned on every `handleDownloads` call, to ensure no old files are kept.
|
|
1064
1128
|
*
|
|
1065
1129
|
* ```js
|
|
@@ -1231,9 +1295,9 @@ class Puppeteer extends Helper {
|
|
|
1231
1295
|
}
|
|
1232
1296
|
|
|
1233
1297
|
/**
|
|
1234
|
-
* {{> pressKeyWithKeyNormalization }}
|
|
1235
|
-
*
|
|
1236
1298
|
* _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
|
|
1299
|
+
*
|
|
1300
|
+
* {{> pressKeyWithKeyNormalization }}
|
|
1237
1301
|
*/
|
|
1238
1302
|
async pressKey(key) {
|
|
1239
1303
|
const modifiers = [];
|
|
@@ -1291,7 +1355,7 @@ class Puppeteer extends Helper {
|
|
|
1291
1355
|
await this._evaluateHandeInContext(el => el.innerHTML = '', el);
|
|
1292
1356
|
}
|
|
1293
1357
|
|
|
1294
|
-
highlightActiveElement.call(this, el, this.
|
|
1358
|
+
highlightActiveElement.call(this, el, await this._getContext());
|
|
1295
1359
|
await el.type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
1296
1360
|
|
|
1297
1361
|
return this._waitForAction();
|
|
@@ -1312,7 +1376,7 @@ class Puppeteer extends Helper {
|
|
|
1312
1376
|
async appendField(field, value) {
|
|
1313
1377
|
const els = await findVisibleFields.call(this, field);
|
|
1314
1378
|
assertElementExists(els, field, 'Field');
|
|
1315
|
-
highlightActiveElement.call(this, els[0], this.
|
|
1379
|
+
highlightActiveElement.call(this, els[0], await this._getContext());
|
|
1316
1380
|
await els[0].press('End');
|
|
1317
1381
|
await els[0].type(value.toString(), { delay: this.options.pressKeyDelay });
|
|
1318
1382
|
return this._waitForAction();
|
|
@@ -1322,20 +1386,22 @@ class Puppeteer extends Helper {
|
|
|
1322
1386
|
* {{> seeInField }}
|
|
1323
1387
|
*/
|
|
1324
1388
|
async seeInField(field, value) {
|
|
1325
|
-
|
|
1389
|
+
const _value = (typeof value === 'boolean') ? value : value.toString();
|
|
1390
|
+
return proceedSeeInField.call(this, 'assert', field, _value);
|
|
1326
1391
|
}
|
|
1327
1392
|
|
|
1328
1393
|
/**
|
|
1329
1394
|
* {{> dontSeeInField }}
|
|
1330
1395
|
*/
|
|
1331
1396
|
async dontSeeInField(field, value) {
|
|
1332
|
-
|
|
1397
|
+
const _value = (typeof value === 'boolean') ? value : value.toString();
|
|
1398
|
+
return proceedSeeInField.call(this, 'negate', field, _value);
|
|
1333
1399
|
}
|
|
1334
1400
|
|
|
1335
1401
|
/**
|
|
1336
|
-
* {{> attachFile }}
|
|
1337
|
-
*
|
|
1338
1402
|
* > ⚠ There is an [issue with file upload in Puppeteer 2.1.0 & 2.1.1](https://github.com/puppeteer/puppeteer/issues/5420), downgrade to 2.0.0 if you face it.
|
|
1403
|
+
*
|
|
1404
|
+
* {{> attachFile }}
|
|
1339
1405
|
*/
|
|
1340
1406
|
async attachFile(locator, pathToFile) {
|
|
1341
1407
|
const file = path.join(global.codecept_dir, pathToFile);
|
|
@@ -1359,7 +1425,7 @@ class Puppeteer extends Helper {
|
|
|
1359
1425
|
if (await el.getProperty('tagName').then(t => t.jsonValue()) !== 'SELECT') {
|
|
1360
1426
|
throw new Error('Element is not <select>');
|
|
1361
1427
|
}
|
|
1362
|
-
highlightActiveElement.call(this, els[0], this.
|
|
1428
|
+
highlightActiveElement.call(this, els[0], await this._getContext());
|
|
1363
1429
|
if (!Array.isArray(option)) option = [option];
|
|
1364
1430
|
|
|
1365
1431
|
for (const key in option) {
|
|
@@ -1566,9 +1632,9 @@ class Puppeteer extends Helper {
|
|
|
1566
1632
|
}
|
|
1567
1633
|
|
|
1568
1634
|
/**
|
|
1569
|
-
*
|
|
1635
|
+
* If a function returns a Promise, tt will wait for its resolution.
|
|
1570
1636
|
*
|
|
1571
|
-
*
|
|
1637
|
+
* {{> executeScript }}
|
|
1572
1638
|
*/
|
|
1573
1639
|
async executeScript(...args) {
|
|
1574
1640
|
let context = this.page;
|
|
@@ -1579,9 +1645,8 @@ class Puppeteer extends Helper {
|
|
|
1579
1645
|
}
|
|
1580
1646
|
|
|
1581
1647
|
/**
|
|
1582
|
-
* {{> executeAsyncScript }}
|
|
1583
|
-
*
|
|
1584
1648
|
* Asynchronous scripts can also be executed with `executeScript` if a function returns a Promise.
|
|
1649
|
+
* {{> executeAsyncScript }}
|
|
1585
1650
|
*/
|
|
1586
1651
|
async executeAsyncScript(...args) {
|
|
1587
1652
|
const asyncFn = function () {
|
|
@@ -1708,29 +1773,26 @@ class Puppeteer extends Helper {
|
|
|
1708
1773
|
|
|
1709
1774
|
const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties);
|
|
1710
1775
|
const elemAmount = res.length;
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
.
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
}));
|
|
1725
|
-
});
|
|
1726
|
-
});
|
|
1727
|
-
let props = await Promise.all(commands);
|
|
1776
|
+
let props = [];
|
|
1777
|
+
|
|
1778
|
+
for (const element of res) {
|
|
1779
|
+
for (const prop of Object.keys(cssProperties)) {
|
|
1780
|
+
const cssProp = await this.grabCssPropertyFrom(locator, prop);
|
|
1781
|
+
if (isColorProperty(prop)) {
|
|
1782
|
+
props.push(convertColorToRGBA(cssProp));
|
|
1783
|
+
} else {
|
|
1784
|
+
props.push(cssProp);
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1728
1789
|
const values = Object.keys(cssPropertiesCamelCase).map(key => cssPropertiesCamelCase[key]);
|
|
1729
1790
|
if (!Array.isArray(props)) props = [props];
|
|
1730
1791
|
let chunked = chunkArray(props, values.length);
|
|
1731
1792
|
chunked = chunked.filter((val) => {
|
|
1732
1793
|
for (let i = 0; i < val.length; ++i) {
|
|
1733
|
-
|
|
1794
|
+
// eslint-disable-next-line eqeqeq
|
|
1795
|
+
if (val[i] != values[i]) return false;
|
|
1734
1796
|
}
|
|
1735
1797
|
return true;
|
|
1736
1798
|
});
|
|
@@ -1761,7 +1823,10 @@ class Puppeteer extends Helper {
|
|
|
1761
1823
|
let chunked = chunkArray(attrs, values.length);
|
|
1762
1824
|
chunked = chunked.filter((val) => {
|
|
1763
1825
|
for (let i = 0; i < val.length; ++i) {
|
|
1764
|
-
|
|
1826
|
+
const _actual = Number.isNaN(val[i]) || (typeof values[i]) === 'string' ? val[i] : Number.parseInt(values[i], 10);
|
|
1827
|
+
const _expected = Number.isNaN(values[i]) || (typeof values[i]) === 'string' ? values[i] : Number.parseInt(values[i], 10);
|
|
1828
|
+
// if the attribute doesn't exist, returns false as well
|
|
1829
|
+
if (!_actual || !_actual.includes(_expected)) return false;
|
|
1765
1830
|
}
|
|
1766
1831
|
return true;
|
|
1767
1832
|
});
|
|
@@ -1865,8 +1930,30 @@ class Puppeteer extends Helper {
|
|
|
1865
1930
|
}
|
|
1866
1931
|
}
|
|
1867
1932
|
|
|
1868
|
-
async _failed() {
|
|
1933
|
+
async _failed(test) {
|
|
1869
1934
|
await this._withinEnd();
|
|
1935
|
+
|
|
1936
|
+
if (this.options.trace) {
|
|
1937
|
+
await this.page.tracing.stop();
|
|
1938
|
+
const _traceName = this.currentRunningTest.artifacts.trace.replace('.json', '.failed.json');
|
|
1939
|
+
fs.renameSync(this.currentRunningTest.artifacts.trace, _traceName);
|
|
1940
|
+
test.artifacts.trace = _traceName;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
async _passed(test) {
|
|
1945
|
+
await this._withinEnd();
|
|
1946
|
+
|
|
1947
|
+
if (this.options.trace) {
|
|
1948
|
+
await this.page.tracing.stop();
|
|
1949
|
+
if (this.options.keepTraceForPassedTests) {
|
|
1950
|
+
const _traceName = this.currentRunningTest.artifacts.trace.replace('.json', '.passed.json');
|
|
1951
|
+
fs.renameSync(this.currentRunningTest.artifacts.trace, _traceName);
|
|
1952
|
+
test.artifacts.trace = _traceName;
|
|
1953
|
+
} else {
|
|
1954
|
+
fs.unlinkSync(this.currentRunningTest.artifacts.trace);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1870
1957
|
}
|
|
1871
1958
|
|
|
1872
1959
|
/**
|
|
@@ -1978,7 +2065,7 @@ class Puppeteer extends Helper {
|
|
|
1978
2065
|
assertElementExists(els, locator);
|
|
1979
2066
|
|
|
1980
2067
|
return this.waitForFunction(isElementClickable, [els[0]], waitTimeout).catch(async (e) => {
|
|
1981
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
2068
|
+
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
1982
2069
|
throw new Error(`element ${new Locator(locator).toString()} still not clickable after ${waitTimeout || this.options.waitForTimeout / 1000} sec`);
|
|
1983
2070
|
} else {
|
|
1984
2071
|
throw e;
|
|
@@ -2009,7 +2096,7 @@ class Puppeteer extends Helper {
|
|
|
2009
2096
|
/**
|
|
2010
2097
|
* {{> waitForVisible }}
|
|
2011
2098
|
*
|
|
2012
|
-
*
|
|
2099
|
+
* {{ react }}
|
|
2013
2100
|
*/
|
|
2014
2101
|
async waitForVisible(locator, sec) {
|
|
2015
2102
|
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
|
|
@@ -2064,6 +2151,24 @@ class Puppeteer extends Helper {
|
|
|
2064
2151
|
});
|
|
2065
2152
|
}
|
|
2066
2153
|
|
|
2154
|
+
/**
|
|
2155
|
+
* {{> waitForNumberOfTabs }}
|
|
2156
|
+
*/
|
|
2157
|
+
async waitForNumberOfTabs(expectedTabs, sec) {
|
|
2158
|
+
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
|
|
2159
|
+
let currentTabs;
|
|
2160
|
+
let count = 0;
|
|
2161
|
+
|
|
2162
|
+
do {
|
|
2163
|
+
currentTabs = await this.grabNumberOfOpenTabs();
|
|
2164
|
+
await this.wait(1);
|
|
2165
|
+
count += 1000;
|
|
2166
|
+
if (currentTabs >= expectedTabs) return;
|
|
2167
|
+
} while (count <= waitTimeout);
|
|
2168
|
+
|
|
2169
|
+
throw new Error(`Expected ${expectedTabs} tabs are not met after ${waitTimeout / 1000} sec.`);
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2067
2172
|
async _getContext() {
|
|
2068
2173
|
if (this.context && this.context.constructor.name === 'Frame') {
|
|
2069
2174
|
return this.context;
|
|
@@ -2082,7 +2187,7 @@ class Puppeteer extends Helper {
|
|
|
2082
2187
|
return currUrl.indexOf(urlPart) > -1;
|
|
2083
2188
|
}, { timeout: waitTimeout }, urlPart).catch(async (e) => {
|
|
2084
2189
|
const currUrl = await this._getPageUrl(); // Required because the waitForFunction can't return data.
|
|
2085
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
2190
|
+
if (/Waiting failed:/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2086
2191
|
throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`);
|
|
2087
2192
|
} else {
|
|
2088
2193
|
throw e;
|
|
@@ -2106,7 +2211,7 @@ class Puppeteer extends Helper {
|
|
|
2106
2211
|
return currUrl.indexOf(urlPart) > -1;
|
|
2107
2212
|
}, { timeout: waitTimeout }, urlPart).catch(async (e) => {
|
|
2108
2213
|
const currUrl = await this._getPageUrl(); // Required because the waitForFunction can't return data.
|
|
2109
|
-
if (/failed: timeout/i.test(e.message)) {
|
|
2214
|
+
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2110
2215
|
throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`);
|
|
2111
2216
|
} else {
|
|
2112
2217
|
throw e;
|
|
@@ -2238,9 +2343,9 @@ class Puppeteer extends Helper {
|
|
|
2238
2343
|
}
|
|
2239
2344
|
|
|
2240
2345
|
/**
|
|
2241
|
-
* Waits for navigation to finish. By default takes configured `waitForNavigation` option.
|
|
2346
|
+
* Waits for navigation to finish. By default, takes configured `waitForNavigation` option.
|
|
2242
2347
|
*
|
|
2243
|
-
* See [
|
|
2348
|
+
* See [Puppeteer's reference](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions)
|
|
2244
2349
|
*
|
|
2245
2350
|
* @param {*} opts
|
|
2246
2351
|
*/
|
|
@@ -2315,6 +2420,10 @@ async function findElements(matcher, locator) {
|
|
|
2315
2420
|
if (locator.react) return findReact(matcher.executionContext(), locator);
|
|
2316
2421
|
locator = new Locator(locator, 'css');
|
|
2317
2422
|
if (!locator.isXPath()) return matcher.$$(locator.simplify());
|
|
2423
|
+
// puppeteer version < 19.4.0 is no longer supported. This one is backward support.
|
|
2424
|
+
if (puppeteer.default?.defaultBrowserRevision) {
|
|
2425
|
+
return matcher.$$(`xpath/${locator.value}`);
|
|
2426
|
+
}
|
|
2318
2427
|
return matcher.$x(locator.value);
|
|
2319
2428
|
}
|
|
2320
2429
|
|
|
@@ -2332,7 +2441,7 @@ async function proceedClick(locator, context = null, options = {}) {
|
|
|
2332
2441
|
assertElementExists(els, locator, 'Clickable element');
|
|
2333
2442
|
}
|
|
2334
2443
|
|
|
2335
|
-
highlightActiveElement.call(this, els[0], this.
|
|
2444
|
+
highlightActiveElement.call(this, els[0], await this._getContext());
|
|
2336
2445
|
|
|
2337
2446
|
await els[0].click(options);
|
|
2338
2447
|
const promises = [];
|
|
@@ -2392,7 +2501,7 @@ async function proceedSee(assertType, text, context, strict = false) {
|
|
|
2392
2501
|
if (strict) {
|
|
2393
2502
|
return allText.map(elText => equals(description)[assertType](text, elText));
|
|
2394
2503
|
}
|
|
2395
|
-
return stringIncludes(description)[assertType](text, allText.join(' | '));
|
|
2504
|
+
return stringIncludes(description)[assertType](normalizeSpacesInString(text), normalizeSpacesInString(allText.join(' | ')));
|
|
2396
2505
|
}
|
|
2397
2506
|
|
|
2398
2507
|
async function findCheckable(locator, context) {
|
|
@@ -2569,7 +2678,10 @@ async function elementSelected(element) {
|
|
|
2569
2678
|
|
|
2570
2679
|
function isFrameLocator(locator) {
|
|
2571
2680
|
locator = new Locator(locator);
|
|
2572
|
-
if (locator.isFrame())
|
|
2681
|
+
if (locator.isFrame()) {
|
|
2682
|
+
const _locator = new Locator(locator);
|
|
2683
|
+
return _locator.value;
|
|
2684
|
+
}
|
|
2573
2685
|
return false;
|
|
2574
2686
|
}
|
|
2575
2687
|
|
|
@@ -2687,7 +2799,7 @@ function getNormalizedKey(key) {
|
|
|
2687
2799
|
}
|
|
2688
2800
|
|
|
2689
2801
|
function highlightActiveElement(element, context) {
|
|
2690
|
-
if (
|
|
2691
|
-
|
|
2692
|
-
|
|
2802
|
+
if (this.options.highlightElement && global.debugMode) {
|
|
2803
|
+
highlightElement(element, context);
|
|
2804
|
+
}
|
|
2693
2805
|
}
|