codeceptjs 3.6.10 → 3.7.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -110
- package/bin/codecept.js +2 -2
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +46 -36
- package/lib/assert/empty.js +3 -5
- package/lib/assert/equal.js +4 -7
- package/lib/assert/include.js +4 -6
- package/lib/assert/throws.js +2 -4
- package/lib/assert/truth.js +2 -2
- package/lib/codecept.js +87 -83
- package/lib/command/configMigrate.js +2 -4
- package/lib/command/definitions.js +5 -25
- package/lib/command/generate.js +10 -14
- package/lib/command/gherkin/snippets.js +10 -8
- package/lib/command/gherkin/steps.js +1 -1
- package/lib/command/info.js +1 -3
- package/lib/command/init.js +8 -12
- package/lib/command/interactive.js +1 -1
- package/lib/command/list.js +1 -1
- package/lib/command/run-multiple.js +12 -35
- package/lib/command/run-workers.js +10 -10
- package/lib/command/utils.js +5 -6
- package/lib/command/workers/runTests.js +14 -17
- package/lib/container.js +327 -237
- package/lib/data/context.js +10 -13
- package/lib/data/dataScenarioConfig.js +8 -8
- package/lib/data/dataTableArgument.js +6 -6
- package/lib/data/table.js +5 -11
- package/lib/els.js +177 -0
- package/lib/event.js +1 -0
- package/lib/heal.js +78 -80
- package/lib/helper/ApiDataFactory.js +3 -6
- package/lib/helper/Appium.js +15 -30
- package/lib/helper/FileSystem.js +3 -3
- package/lib/helper/GraphQLDataFactory.js +3 -3
- package/lib/helper/JSONResponse.js +57 -37
- package/lib/helper/Nightmare.js +35 -53
- package/lib/helper/Playwright.js +189 -251
- package/lib/helper/Protractor.js +54 -77
- package/lib/helper/Puppeteer.js +134 -232
- package/lib/helper/REST.js +5 -17
- package/lib/helper/TestCafe.js +21 -44
- package/lib/helper/WebDriver.js +103 -162
- package/lib/helper/testcafe/testcafe-utils.js +26 -27
- package/lib/listener/artifacts.js +2 -2
- package/lib/listener/emptyRun.js +58 -0
- package/lib/listener/exit.js +4 -4
- package/lib/listener/{retry.js → globalRetry.js} +5 -5
- package/lib/listener/{timeout.js → globalTimeout.js} +8 -8
- package/lib/listener/helpers.js +15 -15
- package/lib/listener/mocha.js +1 -1
- package/lib/listener/steps.js +17 -12
- package/lib/listener/store.js +12 -0
- package/lib/mocha/asyncWrapper.js +204 -0
- package/lib/{interfaces → mocha}/bdd.js +3 -3
- package/lib/mocha/cli.js +257 -0
- package/lib/mocha/factory.js +104 -0
- package/lib/{interfaces → mocha}/featureConfig.js +11 -12
- package/lib/{interfaces → mocha}/gherkin.js +26 -28
- package/lib/mocha/hooks.js +83 -0
- package/lib/mocha/index.js +12 -0
- package/lib/mocha/inject.js +24 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +10 -6
- package/lib/mocha/suite.js +55 -0
- package/lib/mocha/test.js +60 -0
- package/lib/mocha/types.d.ts +31 -0
- package/lib/mocha/ui.js +219 -0
- package/lib/output.js +28 -10
- package/lib/pause.js +159 -135
- package/lib/plugin/autoDelay.js +4 -4
- package/lib/plugin/autoLogin.js +6 -7
- package/lib/plugin/commentStep.js +1 -1
- package/lib/plugin/coverage.js +10 -19
- package/lib/plugin/customLocator.js +3 -3
- package/lib/plugin/debugErrors.js +2 -2
- package/lib/plugin/eachElement.js +1 -1
- package/lib/plugin/fakerTransform.js +1 -1
- package/lib/plugin/heal.js +6 -9
- package/lib/plugin/retryFailedStep.js +4 -4
- package/lib/plugin/retryTo.js +2 -2
- package/lib/plugin/screenshotOnFail.js +9 -36
- package/lib/plugin/selenoid.js +15 -35
- package/lib/plugin/stepByStepReport.js +51 -13
- package/lib/plugin/stepTimeout.js +4 -11
- package/lib/plugin/subtitles.js +4 -4
- package/lib/plugin/tryTo.js +1 -1
- package/lib/plugin/wdio.js +8 -10
- package/lib/recorder.js +142 -121
- package/lib/secret.js +1 -1
- package/lib/step.js +160 -144
- package/lib/store.js +6 -2
- package/lib/template/heal.js +2 -11
- package/lib/utils.js +224 -216
- package/lib/within.js +73 -55
- package/lib/workers.js +265 -261
- package/package.json +46 -47
- package/typings/index.d.ts +172 -184
- package/typings/promiseBasedTypes.d.ts +53 -516
- package/typings/types.d.ts +127 -587
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/mochaFactory.js +0 -113
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
package/lib/helper/WebDriver.js
CHANGED
|
@@ -10,16 +10,7 @@ const { urlEquals, equals } = require('../assert/equal')
|
|
|
10
10
|
const { debug } = require('../output')
|
|
11
11
|
const { empty } = require('../assert/empty')
|
|
12
12
|
const { truth } = require('../assert/truth')
|
|
13
|
-
const {
|
|
14
|
-
xpathLocator,
|
|
15
|
-
fileExists,
|
|
16
|
-
decodeUrl,
|
|
17
|
-
chunkArray,
|
|
18
|
-
convertCssPropertiesToCamelCase,
|
|
19
|
-
screenshotOutputFolder,
|
|
20
|
-
getNormalizedKeyAttributeValue,
|
|
21
|
-
modifierKeys,
|
|
22
|
-
} = require('../utils')
|
|
13
|
+
const { xpathLocator, fileExists, decodeUrl, chunkArray, convertCssPropertiesToCamelCase, screenshotOutputFolder, getNormalizedKeyAttributeValue, modifierKeys } = require('../utils')
|
|
23
14
|
const { isColorProperty, convertColorToRGBA } = require('../colorUtils')
|
|
24
15
|
const ElementNotFound = require('./errors/ElementNotFound')
|
|
25
16
|
const ConnectionRefused = require('./errors/ConnectionRefused')
|
|
@@ -27,19 +18,8 @@ const Locator = require('../locator')
|
|
|
27
18
|
const { highlightElement } = require('./scripts/highlightElement')
|
|
28
19
|
const { focusElement } = require('./scripts/focusElement')
|
|
29
20
|
const { blurElement } = require('./scripts/blurElement')
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
seeElementError,
|
|
33
|
-
seeElementInDOMError,
|
|
34
|
-
dontSeeElementInDOMError,
|
|
35
|
-
} = require('./errors/ElementAssertion')
|
|
36
|
-
const {
|
|
37
|
-
dontSeeTraffic,
|
|
38
|
-
seeTraffic,
|
|
39
|
-
grabRecordedNetworkTraffics,
|
|
40
|
-
stopRecordingTraffic,
|
|
41
|
-
flushNetworkTraffics,
|
|
42
|
-
} = require('./network/actions')
|
|
21
|
+
const { dontSeeElementError, seeElementError, seeElementInDOMError, dontSeeElementInDOMError } = require('./errors/ElementAssertion')
|
|
22
|
+
const { dontSeeTraffic, seeTraffic, grabRecordedNetworkTraffics, stopRecordingTraffic, flushNetworkTraffics } = require('./network/actions')
|
|
43
23
|
|
|
44
24
|
const SHADOW = 'shadow'
|
|
45
25
|
const webRoot = 'body'
|
|
@@ -595,10 +575,7 @@ class WebDriver extends Helper {
|
|
|
595
575
|
}
|
|
596
576
|
|
|
597
577
|
async _res(locator) {
|
|
598
|
-
const res =
|
|
599
|
-
this._isShadowLocator(locator) || this._isCustomLocator(locator)
|
|
600
|
-
? await this._locate(locator)
|
|
601
|
-
: await this.$$(withStrictLocator(locator))
|
|
578
|
+
const res = this._isShadowLocator(locator) || this._isCustomLocator(locator) ? await this._locate(locator) : await this.$$(withStrictLocator(locator))
|
|
602
579
|
return res
|
|
603
580
|
}
|
|
604
581
|
|
|
@@ -631,7 +608,7 @@ class WebDriver extends Helper {
|
|
|
631
608
|
this.$$ = this.browser.$$.bind(this.browser)
|
|
632
609
|
|
|
633
610
|
if (this._isCustomLocatorStrategyDefined()) {
|
|
634
|
-
Object.keys(this.customLocatorStrategies).forEach(async
|
|
611
|
+
Object.keys(this.customLocatorStrategies).forEach(async customLocator => {
|
|
635
612
|
this.debugSection('Weddriver', `adding custom locator strategy: ${customLocator}`)
|
|
636
613
|
const locatorFunction = this._lookupCustomLocator(customLocator)
|
|
637
614
|
this.browser.addLocatorStrategy(customLocator, locatorFunction)
|
|
@@ -642,6 +619,7 @@ class WebDriver extends Helper {
|
|
|
642
619
|
this.browser.capabilities.platformName = this.browser.capabilities.platformName.toLowerCase()
|
|
643
620
|
}
|
|
644
621
|
|
|
622
|
+
this.browser.on('dialog', () => {})
|
|
645
623
|
return this.browser
|
|
646
624
|
}
|
|
647
625
|
|
|
@@ -667,7 +645,7 @@ class WebDriver extends Helper {
|
|
|
667
645
|
this.isRunning = false
|
|
668
646
|
return this.browser.deleteSession()
|
|
669
647
|
}
|
|
670
|
-
if (this.browser.isInsideFrame) await this.browser.
|
|
648
|
+
if (this.browser.isInsideFrame) await this.browser.switchFrame(null)
|
|
671
649
|
|
|
672
650
|
if (this.options.keepBrowserState) return
|
|
673
651
|
|
|
@@ -675,7 +653,7 @@ class WebDriver extends Helper {
|
|
|
675
653
|
this.debugSection('Session', 'cleaning cookies and localStorage')
|
|
676
654
|
await this.browser.deleteCookies()
|
|
677
655
|
}
|
|
678
|
-
await this.browser.execute('localStorage.clear();').catch(
|
|
656
|
+
await this.browser.execute('localStorage.clear();').catch(err => {
|
|
679
657
|
if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err
|
|
680
658
|
})
|
|
681
659
|
await this.closeOtherTabs()
|
|
@@ -705,17 +683,17 @@ class WebDriver extends Helper {
|
|
|
705
683
|
|
|
706
684
|
return browser
|
|
707
685
|
},
|
|
708
|
-
stop: async
|
|
686
|
+
stop: async browser => {
|
|
709
687
|
if (!browser) return
|
|
710
688
|
return browser.deleteSession()
|
|
711
689
|
},
|
|
712
|
-
loadVars: async
|
|
690
|
+
loadVars: async browser => {
|
|
713
691
|
if (this.context !== this.root) throw new Error("Can't start session inside within block")
|
|
714
692
|
this.browser = browser
|
|
715
693
|
this.$$ = this.browser.$$.bind(this.browser)
|
|
716
694
|
this.sessionWindows[this.activeSessionName] = browser
|
|
717
695
|
},
|
|
718
|
-
restoreVars: async
|
|
696
|
+
restoreVars: async session => {
|
|
719
697
|
if (!session) {
|
|
720
698
|
this.activeSessionName = ''
|
|
721
699
|
}
|
|
@@ -757,7 +735,7 @@ class WebDriver extends Helper {
|
|
|
757
735
|
this.browser.isInsideFrame = true
|
|
758
736
|
if (Array.isArray(frame)) {
|
|
759
737
|
// this.switchTo(null);
|
|
760
|
-
await forEachAsync(frame, async
|
|
738
|
+
await forEachAsync(frame, async f => this.switchTo(f))
|
|
761
739
|
return
|
|
762
740
|
}
|
|
763
741
|
await this.switchTo(frame)
|
|
@@ -835,10 +813,7 @@ class WebDriver extends Helper {
|
|
|
835
813
|
* @param {object} locator
|
|
836
814
|
*/
|
|
837
815
|
async _smartWait(locator) {
|
|
838
|
-
this.debugSection(
|
|
839
|
-
`SmartWait (${this.options.smartWait}ms)`,
|
|
840
|
-
`Locating ${JSON.stringify(locator)} in ${this.options.smartWait}`,
|
|
841
|
-
)
|
|
816
|
+
this.debugSection(`SmartWait (${this.options.smartWait}ms)`, `Locating ${JSON.stringify(locator)} in ${this.options.smartWait}`)
|
|
842
817
|
await this.defineTimeout({ implicit: this.options.smartWait })
|
|
843
818
|
}
|
|
844
819
|
|
|
@@ -913,7 +888,7 @@ class WebDriver extends Helper {
|
|
|
913
888
|
* @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
914
889
|
*/
|
|
915
890
|
async _locateCheckable(locator) {
|
|
916
|
-
return findCheckable.call(this, locator, this.$$.bind(this)).then(
|
|
891
|
+
return findCheckable.call(this, locator, this.$$.bind(this)).then(res => res)
|
|
917
892
|
}
|
|
918
893
|
|
|
919
894
|
/**
|
|
@@ -941,7 +916,7 @@ class WebDriver extends Helper {
|
|
|
941
916
|
* @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
942
917
|
*/
|
|
943
918
|
async _locateFields(locator) {
|
|
944
|
-
return findFields.call(this, locator).then(
|
|
919
|
+
return findFields.call(this, locator).then(res => res)
|
|
945
920
|
}
|
|
946
921
|
|
|
947
922
|
/**
|
|
@@ -1025,7 +1000,7 @@ class WebDriver extends Helper {
|
|
|
1025
1000
|
const elem = usingFirstElement(res)
|
|
1026
1001
|
highlightActiveElement.call(this, elem)
|
|
1027
1002
|
|
|
1028
|
-
return this.executeScript(
|
|
1003
|
+
return this.executeScript(el => {
|
|
1029
1004
|
if (document.activeElement instanceof HTMLElement) {
|
|
1030
1005
|
document.activeElement.blur()
|
|
1031
1006
|
}
|
|
@@ -1097,7 +1072,7 @@ class WebDriver extends Helper {
|
|
|
1097
1072
|
}
|
|
1098
1073
|
const elem = usingFirstElement(res)
|
|
1099
1074
|
|
|
1100
|
-
return this.executeScript(
|
|
1075
|
+
return this.executeScript(el => {
|
|
1101
1076
|
if (document.activeElement instanceof HTMLElement) {
|
|
1102
1077
|
document.activeElement.blur()
|
|
1103
1078
|
}
|
|
@@ -1160,15 +1135,9 @@ class WebDriver extends Helper {
|
|
|
1160
1135
|
}
|
|
1161
1136
|
|
|
1162
1137
|
// select options by visible text
|
|
1163
|
-
let els = await forEachAsync(option, async (opt)
|
|
1164
|
-
this.browser.findElementsFromElement(
|
|
1165
|
-
getElementId(elem),
|
|
1166
|
-
'xpath',
|
|
1167
|
-
Locator.select.byVisibleText(xpathLocator.literal(opt)),
|
|
1168
|
-
),
|
|
1169
|
-
)
|
|
1138
|
+
let els = await forEachAsync(option, async opt => this.browser.findElementsFromElement(getElementId(elem), 'xpath', Locator.select.byVisibleText(xpathLocator.literal(opt))))
|
|
1170
1139
|
|
|
1171
|
-
const clickOptionFn = async
|
|
1140
|
+
const clickOptionFn = async el => {
|
|
1172
1141
|
if (el[0]) el = el[0]
|
|
1173
1142
|
const elementId = getElementId(el)
|
|
1174
1143
|
if (elementId) return this.browser.elementClick(elementId)
|
|
@@ -1178,19 +1147,9 @@ class WebDriver extends Helper {
|
|
|
1178
1147
|
return forEachAsync(els, clickOptionFn)
|
|
1179
1148
|
}
|
|
1180
1149
|
// select options by value
|
|
1181
|
-
els = await forEachAsync(option, async (opt)
|
|
1182
|
-
this.browser.findElementsFromElement(
|
|
1183
|
-
getElementId(elem),
|
|
1184
|
-
'xpath',
|
|
1185
|
-
Locator.select.byValue(xpathLocator.literal(opt)),
|
|
1186
|
-
),
|
|
1187
|
-
)
|
|
1150
|
+
els = await forEachAsync(option, async opt => this.browser.findElementsFromElement(getElementId(elem), 'xpath', Locator.select.byValue(xpathLocator.literal(opt))))
|
|
1188
1151
|
if (els.length === 0) {
|
|
1189
|
-
throw new ElementNotFound(
|
|
1190
|
-
select,
|
|
1191
|
-
`Option "${option}" in`,
|
|
1192
|
-
'was not found neither by a visible text nor by a value',
|
|
1193
|
-
)
|
|
1152
|
+
throw new ElementNotFound(select, `Option "${option}" in`, 'was not found neither by a visible text nor by a value')
|
|
1194
1153
|
}
|
|
1195
1154
|
return forEachAsync(els, clickOptionFn)
|
|
1196
1155
|
}
|
|
@@ -1217,9 +1176,7 @@ class WebDriver extends Helper {
|
|
|
1217
1176
|
this.debugSection('File', 'Uploading file to remote server')
|
|
1218
1177
|
file = await this.browser.uploadFile(file)
|
|
1219
1178
|
} catch (err) {
|
|
1220
|
-
throw new Error(
|
|
1221
|
-
`File can't be transferred to remote server. Set \`remoteFileUpload: false\` in config to upload file locally.\n${err.message}`,
|
|
1222
|
-
)
|
|
1179
|
+
throw new Error(`File can't be transferred to remote server. Set \`remoteFileUpload: false\` in config to upload file locally.\n${err.message}`)
|
|
1223
1180
|
}
|
|
1224
1181
|
}
|
|
1225
1182
|
|
|
@@ -1272,7 +1229,11 @@ class WebDriver extends Helper {
|
|
|
1272
1229
|
*/
|
|
1273
1230
|
async grabTextFromAll(locator) {
|
|
1274
1231
|
const res = await this._locate(locator, true)
|
|
1275
|
-
|
|
1232
|
+
let val = []
|
|
1233
|
+
await forEachAsync(res, async el => {
|
|
1234
|
+
const text = await this.browser.getElementText(getElementId(el))
|
|
1235
|
+
val.push(text)
|
|
1236
|
+
})
|
|
1276
1237
|
this.debugSection('GrabText', String(val))
|
|
1277
1238
|
return val
|
|
1278
1239
|
}
|
|
@@ -1297,7 +1258,7 @@ class WebDriver extends Helper {
|
|
|
1297
1258
|
*/
|
|
1298
1259
|
async grabHTMLFromAll(locator) {
|
|
1299
1260
|
const elems = await this._locate(locator, true)
|
|
1300
|
-
const html = await forEachAsync(elems,
|
|
1261
|
+
const html = await forEachAsync(elems, elem => elem.getHTML(false))
|
|
1301
1262
|
this.debugSection('GrabHTML', String(html))
|
|
1302
1263
|
return html
|
|
1303
1264
|
}
|
|
@@ -1322,7 +1283,7 @@ class WebDriver extends Helper {
|
|
|
1322
1283
|
*/
|
|
1323
1284
|
async grabValueFromAll(locator) {
|
|
1324
1285
|
const res = await this._locate(locator, true)
|
|
1325
|
-
const val = await forEachAsync(res,
|
|
1286
|
+
const val = await forEachAsync(res, el => el.getValue())
|
|
1326
1287
|
this.debugSection('GrabValue', String(val))
|
|
1327
1288
|
|
|
1328
1289
|
return val
|
|
@@ -1347,7 +1308,7 @@ class WebDriver extends Helper {
|
|
|
1347
1308
|
*/
|
|
1348
1309
|
async grabCssPropertyFromAll(locator, cssProperty) {
|
|
1349
1310
|
const res = await this._locate(locator, true)
|
|
1350
|
-
const val = await forEachAsync(res, async
|
|
1311
|
+
const val = await forEachAsync(res, async el => this.browser.getElementCSSValue(getElementId(el), cssProperty))
|
|
1351
1312
|
this.debugSection('Grab', String(val))
|
|
1352
1313
|
return val
|
|
1353
1314
|
}
|
|
@@ -1371,7 +1332,7 @@ class WebDriver extends Helper {
|
|
|
1371
1332
|
*/
|
|
1372
1333
|
async grabAttributeFromAll(locator, attr) {
|
|
1373
1334
|
const res = await this._locate(locator, true)
|
|
1374
|
-
const val = await forEachAsync(res, async
|
|
1335
|
+
const val = await forEachAsync(res, async el => el.getAttribute(attr))
|
|
1375
1336
|
this.debugSection('GrabAttribute', String(val))
|
|
1376
1337
|
return val
|
|
1377
1338
|
}
|
|
@@ -1488,7 +1449,7 @@ class WebDriver extends Helper {
|
|
|
1488
1449
|
async seeElement(locator) {
|
|
1489
1450
|
const res = await this._locate(locator, true)
|
|
1490
1451
|
assertElementExists(res, locator)
|
|
1491
|
-
const selected = await forEachAsync(res, async
|
|
1452
|
+
const selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
1492
1453
|
try {
|
|
1493
1454
|
return truth(`elements of ${new Locator(locator)}`, 'to be seen').assert(selected)
|
|
1494
1455
|
} catch (e) {
|
|
@@ -1505,7 +1466,7 @@ class WebDriver extends Helper {
|
|
|
1505
1466
|
if (!res || res.length === 0) {
|
|
1506
1467
|
return truth(`elements of ${new Locator(locator)}`, 'to be seen').negate(false)
|
|
1507
1468
|
}
|
|
1508
|
-
const selected = await forEachAsync(res, async
|
|
1469
|
+
const selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
1509
1470
|
try {
|
|
1510
1471
|
return truth(`elements of ${new Locator(locator)}`, 'to be seen').negate(selected)
|
|
1511
1472
|
} catch (e) {
|
|
@@ -1590,11 +1551,7 @@ class WebDriver extends Helper {
|
|
|
1590
1551
|
*/
|
|
1591
1552
|
async seeNumberOfElements(locator, num) {
|
|
1592
1553
|
const res = await this._locate(locator)
|
|
1593
|
-
return assert.equal(
|
|
1594
|
-
res.length,
|
|
1595
|
-
num,
|
|
1596
|
-
`expected number of elements (${new Locator(locator)}) is ${num}, but found ${res.length}`,
|
|
1597
|
-
)
|
|
1554
|
+
return assert.equal(res.length, num, `expected number of elements (${new Locator(locator)}) is ${num}, but found ${res.length}`)
|
|
1598
1555
|
}
|
|
1599
1556
|
|
|
1600
1557
|
/**
|
|
@@ -1603,11 +1560,7 @@ class WebDriver extends Helper {
|
|
|
1603
1560
|
*/
|
|
1604
1561
|
async seeNumberOfVisibleElements(locator, num) {
|
|
1605
1562
|
const res = await this.grabNumberOfVisibleElements(locator)
|
|
1606
|
-
return assert.equal(
|
|
1607
|
-
res,
|
|
1608
|
-
num,
|
|
1609
|
-
`expected number of visible elements (${new Locator(locator)}) is ${num}, but found ${res}`,
|
|
1610
|
-
)
|
|
1563
|
+
return assert.equal(res, num, `expected number of visible elements (${new Locator(locator)}) is ${num}, but found ${res}`)
|
|
1611
1564
|
}
|
|
1612
1565
|
|
|
1613
1566
|
/**
|
|
@@ -1632,19 +1585,16 @@ class WebDriver extends Helper {
|
|
|
1632
1585
|
}
|
|
1633
1586
|
}
|
|
1634
1587
|
|
|
1635
|
-
const values = Object.keys(cssPropertiesCamelCase).map(
|
|
1588
|
+
const values = Object.keys(cssPropertiesCamelCase).map(key => cssPropertiesCamelCase[key])
|
|
1636
1589
|
if (!Array.isArray(props)) props = [props]
|
|
1637
1590
|
let chunked = chunkArray(props, values.length)
|
|
1638
|
-
chunked = chunked.filter(
|
|
1591
|
+
chunked = chunked.filter(val => {
|
|
1639
1592
|
for (let i = 0; i < val.length; ++i) {
|
|
1640
|
-
// eslint-disable-next-line eqeqeq
|
|
1641
1593
|
if (val[i] != values[i]) return false
|
|
1642
1594
|
}
|
|
1643
1595
|
return true
|
|
1644
1596
|
})
|
|
1645
|
-
return equals(
|
|
1646
|
-
`all elements (${new Locator(locator)}) to have CSS property ${JSON.stringify(cssProperties)}`,
|
|
1647
|
-
).assert(chunked.length, elemAmount)
|
|
1597
|
+
return equals(`all elements (${new Locator(locator)}) to have CSS property ${JSON.stringify(cssProperties)}`).assert(chunked.length, elemAmount)
|
|
1648
1598
|
}
|
|
1649
1599
|
|
|
1650
1600
|
/**
|
|
@@ -1655,28 +1605,24 @@ class WebDriver extends Helper {
|
|
|
1655
1605
|
assertElementExists(res, locator)
|
|
1656
1606
|
const elemAmount = res.length
|
|
1657
1607
|
|
|
1658
|
-
let attrs = await forEachAsync(res, async
|
|
1659
|
-
return forEachAsync(Object.keys(attributes), async
|
|
1608
|
+
let attrs = await forEachAsync(res, async el => {
|
|
1609
|
+
return forEachAsync(Object.keys(attributes), async attr => el.getAttribute(attr))
|
|
1660
1610
|
})
|
|
1661
1611
|
|
|
1662
|
-
const values = Object.keys(attributes).map(
|
|
1612
|
+
const values = Object.keys(attributes).map(key => attributes[key])
|
|
1663
1613
|
if (!Array.isArray(attrs)) attrs = [attrs]
|
|
1664
1614
|
let chunked = chunkArray(attrs, values.length)
|
|
1665
|
-
chunked = chunked.filter(
|
|
1615
|
+
chunked = chunked.filter(val => {
|
|
1666
1616
|
for (let i = 0; i < val.length; ++i) {
|
|
1667
1617
|
const _actual = Number.isNaN(val[i]) || typeof values[i] === 'string' ? val[i] : Number.parseInt(val[i], 10)
|
|
1668
|
-
const _expected =
|
|
1669
|
-
Number.isNaN(values[i]) || typeof values[i] === 'string' ? values[i] : Number.parseInt(values[i], 10)
|
|
1618
|
+
const _expected = Number.isNaN(values[i]) || typeof values[i] === 'string' ? values[i] : Number.parseInt(values[i], 10)
|
|
1670
1619
|
// the attribute could be a boolean
|
|
1671
1620
|
if (typeof _actual === 'boolean') return _actual === _expected
|
|
1672
1621
|
if (_actual !== _expected) return false
|
|
1673
1622
|
}
|
|
1674
1623
|
return true
|
|
1675
1624
|
})
|
|
1676
|
-
return assert.ok(
|
|
1677
|
-
chunked.length === elemAmount,
|
|
1678
|
-
`expected all elements (${new Locator(locator)}) to have attributes ${JSON.stringify(attributes)}`,
|
|
1679
|
-
)
|
|
1625
|
+
return assert.ok(chunked.length === elemAmount, `expected all elements (${new Locator(locator)}) to have attributes ${JSON.stringify(attributes)}`)
|
|
1680
1626
|
}
|
|
1681
1627
|
|
|
1682
1628
|
/**
|
|
@@ -1685,9 +1631,9 @@ class WebDriver extends Helper {
|
|
|
1685
1631
|
async grabNumberOfVisibleElements(locator) {
|
|
1686
1632
|
const res = await this._locate(locator)
|
|
1687
1633
|
|
|
1688
|
-
let selected = await forEachAsync(res, async
|
|
1634
|
+
let selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
1689
1635
|
if (!Array.isArray(selected)) selected = [selected]
|
|
1690
|
-
selected = selected.filter(
|
|
1636
|
+
selected = selected.filter(val => val === true)
|
|
1691
1637
|
return selected.length
|
|
1692
1638
|
}
|
|
1693
1639
|
|
|
@@ -1860,7 +1806,7 @@ class WebDriver extends Helper {
|
|
|
1860
1806
|
width: document.body.scrollWidth,
|
|
1861
1807
|
}
|
|
1862
1808
|
})
|
|
1863
|
-
.then(
|
|
1809
|
+
.then(res => res)
|
|
1864
1810
|
|
|
1865
1811
|
if (height < 100) height = 500 // errors for very small height
|
|
1866
1812
|
|
|
@@ -1928,7 +1874,7 @@ class WebDriver extends Helper {
|
|
|
1928
1874
|
|
|
1929
1875
|
return promiseRetry(
|
|
1930
1876
|
async (retry, number) => {
|
|
1931
|
-
const _grabCookie = async
|
|
1877
|
+
const _grabCookie = async name => {
|
|
1932
1878
|
const cookie = await this.browser.getCookies([name])
|
|
1933
1879
|
if (cookie.length === 0) throw Error(`Cookie ${name} is not found after ${retries}s`)
|
|
1934
1880
|
}
|
|
@@ -1952,11 +1898,10 @@ class WebDriver extends Helper {
|
|
|
1952
1898
|
* libraries](http://jster.net/category/windows-modals-popups).
|
|
1953
1899
|
*/
|
|
1954
1900
|
async acceptPopup() {
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
})
|
|
1901
|
+
const text = await this.browser.getAlertText()
|
|
1902
|
+
if (text) {
|
|
1903
|
+
return await this.browser.acceptAlert()
|
|
1904
|
+
}
|
|
1960
1905
|
}
|
|
1961
1906
|
|
|
1962
1907
|
/**
|
|
@@ -1964,11 +1909,10 @@ class WebDriver extends Helper {
|
|
|
1964
1909
|
*
|
|
1965
1910
|
*/
|
|
1966
1911
|
async cancelPopup() {
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
})
|
|
1912
|
+
const text = await this.browser.getAlertText()
|
|
1913
|
+
if (text) {
|
|
1914
|
+
return await this.browser.dismissAlert()
|
|
1915
|
+
}
|
|
1972
1916
|
}
|
|
1973
1917
|
|
|
1974
1918
|
/**
|
|
@@ -1978,7 +1922,7 @@ class WebDriver extends Helper {
|
|
|
1978
1922
|
* @param {string} text value to check.
|
|
1979
1923
|
*/
|
|
1980
1924
|
async seeInPopup(text) {
|
|
1981
|
-
return this.browser.getAlertText().then(
|
|
1925
|
+
return await this.browser.getAlertText().then(res => {
|
|
1982
1926
|
if (res === null) {
|
|
1983
1927
|
throw new Error('Popup is not opened')
|
|
1984
1928
|
}
|
|
@@ -2259,9 +2203,9 @@ class WebDriver extends Helper {
|
|
|
2259
2203
|
async closeOtherTabs() {
|
|
2260
2204
|
const handles = await this.browser.getWindowHandles()
|
|
2261
2205
|
const currentHandle = await this.browser.getWindowHandle()
|
|
2262
|
-
const otherHandles = handles.filter(
|
|
2206
|
+
const otherHandles = handles.filter(handle => handle !== currentHandle)
|
|
2263
2207
|
|
|
2264
|
-
await forEachAsync(otherHandles, async
|
|
2208
|
+
await forEachAsync(otherHandles, async handle => {
|
|
2265
2209
|
await this.browser.switchToWindow(handle)
|
|
2266
2210
|
await this.browser.closeWindow()
|
|
2267
2211
|
})
|
|
@@ -2272,7 +2216,7 @@ class WebDriver extends Helper {
|
|
|
2272
2216
|
* {{> wait }}
|
|
2273
2217
|
*/
|
|
2274
2218
|
async wait(sec) {
|
|
2275
|
-
return new Promise(
|
|
2219
|
+
return new Promise(resolve => {
|
|
2276
2220
|
setTimeout(resolve, sec * 1000)
|
|
2277
2221
|
})
|
|
2278
2222
|
}
|
|
@@ -2289,9 +2233,9 @@ class WebDriver extends Helper {
|
|
|
2289
2233
|
if (!res || res.length === 0) {
|
|
2290
2234
|
return false
|
|
2291
2235
|
}
|
|
2292
|
-
const selected = await forEachAsync(res, async
|
|
2236
|
+
const selected = await forEachAsync(res, async el => this.browser.isElementEnabled(getElementId(el)))
|
|
2293
2237
|
if (Array.isArray(selected)) {
|
|
2294
|
-
return selected.filter(
|
|
2238
|
+
return selected.filter(val => val === true).length > 0
|
|
2295
2239
|
}
|
|
2296
2240
|
return selected
|
|
2297
2241
|
},
|
|
@@ -2346,14 +2290,14 @@ class WebDriver extends Helper {
|
|
|
2346
2290
|
return client
|
|
2347
2291
|
.waitUntil(
|
|
2348
2292
|
function () {
|
|
2349
|
-
return this.getUrl().then(
|
|
2293
|
+
return this.getUrl().then(res => {
|
|
2350
2294
|
currUrl = decodeUrl(res)
|
|
2351
2295
|
return currUrl.indexOf(urlPart) > -1
|
|
2352
2296
|
})
|
|
2353
2297
|
},
|
|
2354
2298
|
{ timeout: aSec * 1000 },
|
|
2355
2299
|
)
|
|
2356
|
-
.catch(
|
|
2300
|
+
.catch(e => {
|
|
2357
2301
|
if (e.message.indexOf('timeout')) {
|
|
2358
2302
|
throw new Error(`expected url to include ${urlPart}, but found ${currUrl}`)
|
|
2359
2303
|
}
|
|
@@ -2373,12 +2317,12 @@ class WebDriver extends Helper {
|
|
|
2373
2317
|
let currUrl = ''
|
|
2374
2318
|
return this.browser
|
|
2375
2319
|
.waitUntil(function () {
|
|
2376
|
-
return this.getUrl().then(
|
|
2320
|
+
return this.getUrl().then(res => {
|
|
2377
2321
|
currUrl = decodeUrl(res)
|
|
2378
2322
|
return currUrl === urlPart
|
|
2379
2323
|
})
|
|
2380
2324
|
}, aSec * 1000)
|
|
2381
|
-
.catch(
|
|
2325
|
+
.catch(e => {
|
|
2382
2326
|
if (e.message.indexOf('timeout')) {
|
|
2383
2327
|
throw new Error(`expected url to be ${urlPart}, but found ${currUrl}`)
|
|
2384
2328
|
}
|
|
@@ -2398,9 +2342,9 @@ class WebDriver extends Helper {
|
|
|
2398
2342
|
async () => {
|
|
2399
2343
|
const res = await this.$$(withStrictLocator.call(this, _context))
|
|
2400
2344
|
if (!res || res.length === 0) return false
|
|
2401
|
-
const selected = await forEachAsync(res, async
|
|
2345
|
+
const selected = await forEachAsync(res, async el => this.browser.getElementText(getElementId(el)))
|
|
2402
2346
|
if (Array.isArray(selected)) {
|
|
2403
|
-
return selected.filter(
|
|
2347
|
+
return selected.filter(part => part.indexOf(text) >= 0).length > 0
|
|
2404
2348
|
}
|
|
2405
2349
|
return selected.indexOf(text) >= 0
|
|
2406
2350
|
},
|
|
@@ -2422,9 +2366,9 @@ class WebDriver extends Helper {
|
|
|
2422
2366
|
async () => {
|
|
2423
2367
|
const res = await findFields.call(this, field)
|
|
2424
2368
|
if (!res || res.length === 0) return false
|
|
2425
|
-
const selected = await forEachAsync(res, async
|
|
2369
|
+
const selected = await forEachAsync(res, async el => el.getValue())
|
|
2426
2370
|
if (Array.isArray(selected)) {
|
|
2427
|
-
return selected.filter(
|
|
2371
|
+
return selected.filter(part => part.indexOf(value) >= 0).length > 0
|
|
2428
2372
|
}
|
|
2429
2373
|
return selected.indexOf(value) >= 0
|
|
2430
2374
|
},
|
|
@@ -2446,9 +2390,9 @@ class WebDriver extends Helper {
|
|
|
2446
2390
|
async () => {
|
|
2447
2391
|
const res = await this._res(locator)
|
|
2448
2392
|
if (!res || res.length === 0) return false
|
|
2449
|
-
const selected = await forEachAsync(res, async
|
|
2393
|
+
const selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
2450
2394
|
if (Array.isArray(selected)) {
|
|
2451
|
-
return selected.filter(
|
|
2395
|
+
return selected.filter(val => val === true).length > 0
|
|
2452
2396
|
}
|
|
2453
2397
|
return selected
|
|
2454
2398
|
},
|
|
@@ -2469,10 +2413,10 @@ class WebDriver extends Helper {
|
|
|
2469
2413
|
async () => {
|
|
2470
2414
|
const res = await this._res(locator)
|
|
2471
2415
|
if (!res || res.length === 0) return false
|
|
2472
|
-
let selected = await forEachAsync(res, async
|
|
2416
|
+
let selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
2473
2417
|
|
|
2474
2418
|
if (!Array.isArray(selected)) selected = [selected]
|
|
2475
|
-
selected = selected.filter(
|
|
2419
|
+
selected = selected.filter(val => val === true)
|
|
2476
2420
|
return selected.length === num
|
|
2477
2421
|
},
|
|
2478
2422
|
{
|
|
@@ -2492,7 +2436,7 @@ class WebDriver extends Helper {
|
|
|
2492
2436
|
async () => {
|
|
2493
2437
|
const res = await this._res(locator)
|
|
2494
2438
|
if (!res || res.length === 0) return true
|
|
2495
|
-
const selected = await forEachAsync(res, async
|
|
2439
|
+
const selected = await forEachAsync(res, async el => el.isDisplayed())
|
|
2496
2440
|
return !selected.length
|
|
2497
2441
|
},
|
|
2498
2442
|
{ timeout: aSec * 1000, timeoutMsg: `element (${new Locator(locator)}) still visible after ${aSec} sec` },
|
|
@@ -2568,17 +2512,14 @@ class WebDriver extends Helper {
|
|
|
2568
2512
|
*/
|
|
2569
2513
|
async switchTo(locator) {
|
|
2570
2514
|
this.browser.isInsideFrame = true
|
|
2571
|
-
if (Number.isInteger(locator)) {
|
|
2572
|
-
return this.browser.switchToFrame(locator)
|
|
2573
|
-
}
|
|
2574
2515
|
if (!locator) {
|
|
2575
|
-
return this.browser.
|
|
2516
|
+
return this.browser.switchFrame(null)
|
|
2576
2517
|
}
|
|
2577
2518
|
|
|
2578
2519
|
let res = await this._locate(locator, true)
|
|
2579
2520
|
assertElementExists(res, locator)
|
|
2580
2521
|
res = usingFirstElement(res)
|
|
2581
|
-
return this.browser.
|
|
2522
|
+
return this.browser.switchFrame(res)
|
|
2582
2523
|
}
|
|
2583
2524
|
|
|
2584
2525
|
/**
|
|
@@ -2591,7 +2532,7 @@ class WebDriver extends Helper {
|
|
|
2591
2532
|
|
|
2592
2533
|
await this.browser.waitUntil(
|
|
2593
2534
|
async () => {
|
|
2594
|
-
await this.browser.getWindowHandles().then(
|
|
2535
|
+
await this.browser.getWindowHandles().then(handles => {
|
|
2595
2536
|
if (handles.indexOf(current) + num + 1 <= handles.length) {
|
|
2596
2537
|
target = handles[handles.indexOf(current) + num]
|
|
2597
2538
|
}
|
|
@@ -2613,7 +2554,7 @@ class WebDriver extends Helper {
|
|
|
2613
2554
|
|
|
2614
2555
|
await this.browser.waitUntil(
|
|
2615
2556
|
async () => {
|
|
2616
|
-
await this.browser.getWindowHandles().then(
|
|
2557
|
+
await this.browser.getWindowHandles().then(handles => {
|
|
2617
2558
|
if (handles.indexOf(current) - num > -1) {
|
|
2618
2559
|
target = handles[handles.indexOf(current) - num]
|
|
2619
2560
|
}
|
|
@@ -2683,10 +2624,7 @@ class WebDriver extends Helper {
|
|
|
2683
2624
|
return client.execute(function () {
|
|
2684
2625
|
const body = document.body
|
|
2685
2626
|
const html = document.documentElement
|
|
2686
|
-
window.scrollTo(
|
|
2687
|
-
0,
|
|
2688
|
-
Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
|
|
2689
|
-
)
|
|
2627
|
+
window.scrollTo(0, Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight))
|
|
2690
2628
|
})
|
|
2691
2629
|
}
|
|
2692
2630
|
|
|
@@ -2760,10 +2698,10 @@ async function proceedSee(assertType, text, context, strict = false) {
|
|
|
2760
2698
|
const smartWaitEnabled = assertType === 'assert'
|
|
2761
2699
|
const res = await this._locate(withStrictLocator(context), smartWaitEnabled)
|
|
2762
2700
|
assertElementExists(res, context)
|
|
2763
|
-
const selected = await forEachAsync(res, async
|
|
2701
|
+
const selected = await forEachAsync(res, async el => this.browser.getElementText(getElementId(el)))
|
|
2764
2702
|
if (strict) {
|
|
2765
2703
|
if (Array.isArray(selected) && selected.length !== 0) {
|
|
2766
|
-
return selected.map(
|
|
2704
|
+
return selected.map(elText => equals(description)[assertType](text, elText))
|
|
2767
2705
|
}
|
|
2768
2706
|
return equals(description)[assertType](text, selected)
|
|
2769
2707
|
}
|
|
@@ -2791,7 +2729,7 @@ async function forEachAsync(array, callback, options = { expandArrayResults: tru
|
|
|
2791
2729
|
const res = await callback(inputArray[index], index, inputArray)
|
|
2792
2730
|
|
|
2793
2731
|
if (Array.isArray(res) && expandArrayResults) {
|
|
2794
|
-
res.forEach(
|
|
2732
|
+
res.forEach(val => values.push(val))
|
|
2795
2733
|
} else if (res) {
|
|
2796
2734
|
values.push(res)
|
|
2797
2735
|
}
|
|
@@ -2877,11 +2815,11 @@ async function proceedSeeField(assertType, field, value) {
|
|
|
2877
2815
|
const elem = usingFirstElement(res)
|
|
2878
2816
|
const elemId = getElementId(elem)
|
|
2879
2817
|
|
|
2880
|
-
const proceedMultiple = async
|
|
2818
|
+
const proceedMultiple = async fields => {
|
|
2881
2819
|
const fieldResults = toArray(
|
|
2882
|
-
await forEachAsync(fields, async
|
|
2820
|
+
await forEachAsync(fields, async el => {
|
|
2883
2821
|
const elementId = getElementId(el)
|
|
2884
|
-
return this.browser.
|
|
2822
|
+
return this.browser.getElementAttribute(elementId, 'value')
|
|
2885
2823
|
}),
|
|
2886
2824
|
)
|
|
2887
2825
|
|
|
@@ -2890,27 +2828,24 @@ async function proceedSeeField(assertType, field, value) {
|
|
|
2890
2828
|
} else {
|
|
2891
2829
|
// Assert that results were found so the forEach assert does not silently pass
|
|
2892
2830
|
equals(`no. of items matching > 0: ${field}`)[assertType](true, !!fieldResults.length)
|
|
2893
|
-
fieldResults.forEach(
|
|
2831
|
+
fieldResults.forEach(val => stringIncludes(`fields by ${field}`)[assertType](value, val))
|
|
2894
2832
|
}
|
|
2895
2833
|
}
|
|
2896
2834
|
|
|
2897
|
-
const proceedSingle =
|
|
2898
|
-
el.getValue().then(
|
|
2835
|
+
const proceedSingle = el =>
|
|
2836
|
+
el.getValue().then(res => {
|
|
2899
2837
|
if (res === null) {
|
|
2900
2838
|
throw new Error(`Element ${el.selector} has no value attribute`)
|
|
2901
2839
|
}
|
|
2902
2840
|
stringIncludes(`fields by ${field}`)[assertType](value, res)
|
|
2903
2841
|
})
|
|
2904
2842
|
|
|
2905
|
-
const filterBySelected = async (elements
|
|
2906
|
-
filterAsync(elements, async (el) => this.browser.isElementSelected(getElementId(el)))
|
|
2843
|
+
const filterBySelected = async elements => filterAsync(elements, async el => this.browser.isElementSelected(getElementId(el)))
|
|
2907
2844
|
|
|
2908
2845
|
const filterSelectedByValue = async (elements, value) => {
|
|
2909
|
-
return filterAsync(elements, async
|
|
2846
|
+
return filterAsync(elements, async el => {
|
|
2910
2847
|
const elementId = getElementId(el)
|
|
2911
|
-
const currentValue = this.browser.
|
|
2912
|
-
? await el.getValue()
|
|
2913
|
-
: await this.browser.getElementAttribute(elementId, 'value')
|
|
2848
|
+
const currentValue = await this.browser.getElementAttribute(elementId, 'value')
|
|
2914
2849
|
const isSelected = await this.browser.isElementSelected(elementId)
|
|
2915
2850
|
return currentValue === value && isSelected
|
|
2916
2851
|
})
|
|
@@ -2918,7 +2853,13 @@ async function proceedSeeField(assertType, field, value) {
|
|
|
2918
2853
|
|
|
2919
2854
|
const tag = await elem.getTagName()
|
|
2920
2855
|
if (tag === 'select') {
|
|
2921
|
-
|
|
2856
|
+
let subOptions
|
|
2857
|
+
|
|
2858
|
+
try {
|
|
2859
|
+
subOptions = await this.browser.findElementsFromElement(elemId, 'css', 'option')
|
|
2860
|
+
} catch (e) {
|
|
2861
|
+
subOptions = await this.browser.findElementsFromElement(elemId, 'xpath', 'option')
|
|
2862
|
+
}
|
|
2922
2863
|
|
|
2923
2864
|
if (value === '') {
|
|
2924
2865
|
// Don't filter by value
|
|
@@ -2959,7 +2900,7 @@ async function proceedSeeCheckbox(assertType, field) {
|
|
|
2959
2900
|
const res = await findFields.call(this, field)
|
|
2960
2901
|
assertElementExists(res, field, 'Field')
|
|
2961
2902
|
|
|
2962
|
-
const selected = await forEachAsync(res, async
|
|
2903
|
+
const selected = await forEachAsync(res, async el => this.browser.isElementSelected(getElementId(el)))
|
|
2963
2904
|
return truth(`checkable field "${field}"`, 'to be checked')[assertType](selected)
|
|
2964
2905
|
}
|
|
2965
2906
|
|
|
@@ -3160,7 +3101,7 @@ function getNormalizedKey(key) {
|
|
|
3160
3101
|
return convertKeyToRawKey(normalizedKey)
|
|
3161
3102
|
}
|
|
3162
3103
|
|
|
3163
|
-
const unicodeModifierKeys = modifierKeys.map(
|
|
3104
|
+
const unicodeModifierKeys = modifierKeys.map(k => convertKeyToRawKey(k))
|
|
3164
3105
|
function isModifierKey(key) {
|
|
3165
3106
|
return unicodeModifierKeys.includes(key)
|
|
3166
3107
|
}
|
|
@@ -3173,9 +3114,9 @@ function highlightActiveElement(element) {
|
|
|
3173
3114
|
|
|
3174
3115
|
function prepareLocateFn(context) {
|
|
3175
3116
|
if (!context) return this._locate.bind(this)
|
|
3176
|
-
return
|
|
3117
|
+
return l => {
|
|
3177
3118
|
l = new Locator(l, 'css')
|
|
3178
|
-
return this._locate(context, true).then(async
|
|
3119
|
+
return this._locate(context, true).then(async res => {
|
|
3179
3120
|
assertElementExists(res, context, 'Context element')
|
|
3180
3121
|
if (l.react) {
|
|
3181
3122
|
return res[0].react$$(l.react, l.props || undefined)
|