codeceptjs 4.0.0-rc.1 → 4.0.0-rc.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 +39 -27
- package/bin/mcp-server.js +610 -0
- package/docs/webapi/appendField.mustache +5 -0
- package/docs/webapi/attachFile.mustache +12 -0
- package/docs/webapi/checkOption.mustache +1 -1
- package/docs/webapi/clearField.mustache +5 -0
- package/docs/webapi/dontSeeCurrentPathEquals.mustache +10 -0
- package/docs/webapi/dontSeeElement.mustache +4 -0
- package/docs/webapi/dontSeeInField.mustache +5 -0
- package/docs/webapi/fillField.mustache +5 -0
- package/docs/webapi/seeCurrentPathEquals.mustache +10 -0
- package/docs/webapi/seeElement.mustache +4 -0
- package/docs/webapi/seeInField.mustache +5 -0
- package/docs/webapi/selectOption.mustache +5 -0
- package/docs/webapi/uncheckOption.mustache +1 -1
- package/lib/codecept.js +20 -17
- package/lib/command/init.js +0 -3
- package/lib/command/run-workers.js +1 -0
- package/lib/container.js +19 -4
- package/lib/helper/Appium.js +8 -8
- package/lib/helper/Playwright.js +163 -70
- package/lib/helper/Puppeteer.js +165 -59
- package/lib/helper/WebDriver.js +134 -49
- package/lib/listener/globalRetry.js +32 -6
- package/lib/plugin/aiTrace.js +464 -0
- package/lib/plugin/retryFailedStep.js +28 -19
- package/lib/plugin/stepByStepReport.js +5 -1
- package/lib/utils.js +48 -0
- package/lib/workers.js +49 -7
- package/package.json +5 -3
- package/lib/listener/enhancedGlobalRetry.js +0 -110
- package/lib/plugin/enhancedRetryFailedStep.js +0 -99
- package/lib/plugin/htmlReporter.js +0 -3648
- package/lib/retryCoordinator.js +0 -207
- package/typings/promiseBasedTypes.d.ts +0 -9469
- package/typings/types.d.ts +0 -11402
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
isModifierKey,
|
|
27
27
|
requireWithFallback,
|
|
28
28
|
normalizeSpacesInString,
|
|
29
|
+
normalizePath,
|
|
30
|
+
resolveUrl,
|
|
31
|
+
getMimeType,
|
|
32
|
+
base64EncodeFile,
|
|
29
33
|
} from '../utils.js'
|
|
30
34
|
import { isColorProperty, convertColorToRGBA } from '../colorUtils.js'
|
|
31
35
|
import ElementNotFound from './errors/ElementNotFound.js'
|
|
@@ -1158,8 +1162,16 @@ class Puppeteer extends Helper {
|
|
|
1158
1162
|
* {{> seeElement }}
|
|
1159
1163
|
* {{ react }}
|
|
1160
1164
|
*/
|
|
1161
|
-
async seeElement(locator) {
|
|
1162
|
-
let els
|
|
1165
|
+
async seeElement(locator, context = null) {
|
|
1166
|
+
let els
|
|
1167
|
+
if (context) {
|
|
1168
|
+
const contextPage = await this.context
|
|
1169
|
+
const contextEls = await findElements.call(this, contextPage, context)
|
|
1170
|
+
assertElementExists(contextEls, context, 'Context element')
|
|
1171
|
+
els = await findElements.call(this, contextEls[0], locator)
|
|
1172
|
+
} else {
|
|
1173
|
+
els = await this._locate(locator)
|
|
1174
|
+
}
|
|
1163
1175
|
els = (await Promise.all(els.map(el => el.boundingBox() && el))).filter(v => v)
|
|
1164
1176
|
// Puppeteer visibility was ignored? | Remove when Puppeteer is fixed
|
|
1165
1177
|
els = await Promise.all(els.map(async el => (await el.evaluate(node => window.getComputedStyle(node).visibility !== 'hidden' && window.getComputedStyle(node).display !== 'none')) && el))
|
|
@@ -1174,8 +1186,16 @@ class Puppeteer extends Helper {
|
|
|
1174
1186
|
* {{> dontSeeElement }}
|
|
1175
1187
|
* {{ react }}
|
|
1176
1188
|
*/
|
|
1177
|
-
async dontSeeElement(locator) {
|
|
1178
|
-
let els
|
|
1189
|
+
async dontSeeElement(locator, context = null) {
|
|
1190
|
+
let els
|
|
1191
|
+
if (context) {
|
|
1192
|
+
const contextPage = await this.context
|
|
1193
|
+
const contextEls = await findElements.call(this, contextPage, context)
|
|
1194
|
+
assertElementExists(contextEls, context, 'Context element')
|
|
1195
|
+
els = await findElements.call(this, contextEls[0], locator)
|
|
1196
|
+
} else {
|
|
1197
|
+
els = await this._locate(locator)
|
|
1198
|
+
}
|
|
1179
1199
|
els = (await Promise.all(els.map(el => el.boundingBox() && el))).filter(v => v)
|
|
1180
1200
|
// Puppeteer visibility was ignored? | Remove when Puppeteer is fixed
|
|
1181
1201
|
els = await Promise.all(els.map(async el => (await el.evaluate(node => window.getComputedStyle(node).visibility !== 'hidden' && window.getComputedStyle(node).display !== 'none')) && el))
|
|
@@ -1541,8 +1561,8 @@ class Puppeteer extends Helper {
|
|
|
1541
1561
|
* {{> fillField }}
|
|
1542
1562
|
* {{ react }}
|
|
1543
1563
|
*/
|
|
1544
|
-
async fillField(field, value) {
|
|
1545
|
-
const els = await findVisibleFields.call(this, field)
|
|
1564
|
+
async fillField(field, value, context = null) {
|
|
1565
|
+
const els = await findVisibleFields.call(this, field, context)
|
|
1546
1566
|
assertElementExists(els, field, 'Field')
|
|
1547
1567
|
const el = els[0]
|
|
1548
1568
|
const tag = await el.getProperty('tagName').then(el => el.jsonValue())
|
|
@@ -1562,8 +1582,8 @@ class Puppeteer extends Helper {
|
|
|
1562
1582
|
/**
|
|
1563
1583
|
* {{> clearField }}
|
|
1564
1584
|
*/
|
|
1565
|
-
async clearField(field) {
|
|
1566
|
-
return this.fillField(field, '')
|
|
1585
|
+
async clearField(field, context = null) {
|
|
1586
|
+
return this.fillField(field, '', context)
|
|
1567
1587
|
}
|
|
1568
1588
|
|
|
1569
1589
|
/**
|
|
@@ -1571,8 +1591,8 @@ class Puppeteer extends Helper {
|
|
|
1571
1591
|
*
|
|
1572
1592
|
* {{ react }}
|
|
1573
1593
|
*/
|
|
1574
|
-
async appendField(field, value) {
|
|
1575
|
-
const els = await findVisibleFields.call(this, field)
|
|
1594
|
+
async appendField(field, value, context = null) {
|
|
1595
|
+
const els = await findVisibleFields.call(this, field, context)
|
|
1576
1596
|
assertElementExists(els, field, 'Field')
|
|
1577
1597
|
highlightActiveElement.call(this, els[0], await this._getContext())
|
|
1578
1598
|
await els[0].press('End')
|
|
@@ -1583,17 +1603,17 @@ class Puppeteer extends Helper {
|
|
|
1583
1603
|
/**
|
|
1584
1604
|
* {{> seeInField }}
|
|
1585
1605
|
*/
|
|
1586
|
-
async seeInField(field, value) {
|
|
1606
|
+
async seeInField(field, value, context = null) {
|
|
1587
1607
|
const _value = typeof value === 'boolean' ? value : value.toString()
|
|
1588
|
-
return proceedSeeInField.call(this, 'assert', field, _value)
|
|
1608
|
+
return proceedSeeInField.call(this, 'assert', field, _value, context)
|
|
1589
1609
|
}
|
|
1590
1610
|
|
|
1591
1611
|
/**
|
|
1592
1612
|
* {{> dontSeeInField }}
|
|
1593
1613
|
*/
|
|
1594
|
-
async dontSeeInField(field, value) {
|
|
1614
|
+
async dontSeeInField(field, value, context = null) {
|
|
1595
1615
|
const _value = typeof value === 'boolean' ? value : value.toString()
|
|
1596
|
-
return proceedSeeInField.call(this, 'negate', field, _value)
|
|
1616
|
+
return proceedSeeInField.call(this, 'negate', field, _value, context)
|
|
1597
1617
|
}
|
|
1598
1618
|
|
|
1599
1619
|
/**
|
|
@@ -1601,46 +1621,77 @@ class Puppeteer extends Helper {
|
|
|
1601
1621
|
*
|
|
1602
1622
|
* {{> attachFile }}
|
|
1603
1623
|
*/
|
|
1604
|
-
async attachFile(locator, pathToFile) {
|
|
1624
|
+
async attachFile(locator, pathToFile, context = null) {
|
|
1605
1625
|
const file = path.join(global.codecept_dir, pathToFile)
|
|
1606
1626
|
|
|
1607
1627
|
if (!fileExists(file)) {
|
|
1608
1628
|
throw new Error(`File at ${file} can not be found on local system`)
|
|
1609
1629
|
}
|
|
1610
|
-
const els = await findFields.call(this, locator)
|
|
1611
|
-
|
|
1612
|
-
|
|
1630
|
+
const els = await findFields.call(this, locator, context)
|
|
1631
|
+
if (els.length) {
|
|
1632
|
+
const tag = await els[0].evaluate(el => el.tagName)
|
|
1633
|
+
const type = await els[0].evaluate(el => el.type)
|
|
1634
|
+
if (tag === 'INPUT' && type === 'file') {
|
|
1635
|
+
await els[0].uploadFile(file)
|
|
1636
|
+
return this._waitForAction()
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
const targetEls = els.length ? els : await this._locate(locator)
|
|
1641
|
+
assertElementExists(targetEls, locator, 'Element')
|
|
1642
|
+
const base64Content = base64EncodeFile(file)
|
|
1643
|
+
const fileName = path.basename(file)
|
|
1644
|
+
const mimeType = getMimeType(fileName)
|
|
1645
|
+
await targetEls[0].evaluate((el, { base64Content, fileName, mimeType }) => {
|
|
1646
|
+
const binaryStr = atob(base64Content)
|
|
1647
|
+
const bytes = new Uint8Array(binaryStr.length)
|
|
1648
|
+
for (let i = 0; i < binaryStr.length; i++) bytes[i] = binaryStr.charCodeAt(i)
|
|
1649
|
+
const fileObj = new File([bytes], fileName, { type: mimeType })
|
|
1650
|
+
const dataTransfer = new DataTransfer()
|
|
1651
|
+
dataTransfer.items.add(fileObj)
|
|
1652
|
+
el.dispatchEvent(new DragEvent('dragenter', { dataTransfer, bubbles: true }))
|
|
1653
|
+
el.dispatchEvent(new DragEvent('dragover', { dataTransfer, bubbles: true }))
|
|
1654
|
+
el.dispatchEvent(new DragEvent('drop', { dataTransfer, bubbles: true }))
|
|
1655
|
+
}, { base64Content, fileName, mimeType })
|
|
1613
1656
|
return this._waitForAction()
|
|
1614
1657
|
}
|
|
1615
1658
|
|
|
1616
1659
|
/**
|
|
1617
1660
|
* {{> selectOption }}
|
|
1618
1661
|
*/
|
|
1619
|
-
async selectOption(select, option) {
|
|
1620
|
-
const
|
|
1662
|
+
async selectOption(select, option, context = null) {
|
|
1663
|
+
const pageContext = await this._getContext()
|
|
1621
1664
|
const matchedLocator = new Locator(select)
|
|
1622
1665
|
|
|
1666
|
+
let contextEl
|
|
1667
|
+
if (context) {
|
|
1668
|
+
const contextEls = await findElements.call(this, pageContext, context)
|
|
1669
|
+
assertElementExists(contextEls, context, 'Context element')
|
|
1670
|
+
contextEl = contextEls[0]
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1623
1673
|
// Strict locator
|
|
1624
1674
|
if (!matchedLocator.isFuzzy()) {
|
|
1625
1675
|
this.debugSection('SelectOption', `Strict: ${JSON.stringify(select)}`)
|
|
1626
|
-
const els = await this._locate(select)
|
|
1676
|
+
const els = contextEl ? await findElements.call(this, contextEl, select) : await this._locate(select)
|
|
1627
1677
|
assertElementExists(els, select, 'Selectable element')
|
|
1628
|
-
return proceedSelect.call(this,
|
|
1678
|
+
return proceedSelect.call(this, pageContext, els[0], option)
|
|
1629
1679
|
}
|
|
1630
1680
|
|
|
1631
1681
|
// Fuzzy: try combobox
|
|
1632
1682
|
this.debugSection('SelectOption', `Fuzzy: "${matchedLocator.value}"`)
|
|
1633
|
-
|
|
1634
|
-
|
|
1683
|
+
const comboboxSearchCtx = contextEl || pageContext
|
|
1684
|
+
let els = await findByRole(comboboxSearchCtx, { role: 'combobox', name: matchedLocator.value })
|
|
1685
|
+
if (els?.length) return proceedSelect.call(this, pageContext, els[0], option)
|
|
1635
1686
|
|
|
1636
1687
|
// Fuzzy: try listbox
|
|
1637
|
-
els = await findByRole(
|
|
1638
|
-
if (els?.length) return proceedSelect.call(this,
|
|
1688
|
+
els = await findByRole(comboboxSearchCtx, { role: 'listbox', name: matchedLocator.value })
|
|
1689
|
+
if (els?.length) return proceedSelect.call(this, pageContext, els[0], option)
|
|
1639
1690
|
|
|
1640
1691
|
// Fuzzy: try native select
|
|
1641
|
-
const visibleEls = await findVisibleFields.call(this, select)
|
|
1692
|
+
const visibleEls = await findVisibleFields.call(this, select, context)
|
|
1642
1693
|
assertElementExists(visibleEls, select, 'Selectable field')
|
|
1643
|
-
return proceedSelect.call(this,
|
|
1694
|
+
return proceedSelect.call(this, pageContext, visibleEls[0], option)
|
|
1644
1695
|
}
|
|
1645
1696
|
|
|
1646
1697
|
/**
|
|
@@ -1684,6 +1735,26 @@ class Puppeteer extends Helper {
|
|
|
1684
1735
|
urlEquals(this.options.url).negate(url, await this._getPageUrl())
|
|
1685
1736
|
}
|
|
1686
1737
|
|
|
1738
|
+
/**
|
|
1739
|
+
* {{> seeCurrentPathEquals }}
|
|
1740
|
+
*/
|
|
1741
|
+
async seeCurrentPathEquals(path) {
|
|
1742
|
+
const currentUrl = await this._getPageUrl()
|
|
1743
|
+
const baseUrl = this.options.url || 'http://localhost'
|
|
1744
|
+
const actualPath = new URL(currentUrl, baseUrl).pathname
|
|
1745
|
+
return equals('url path').assert(normalizePath(path), normalizePath(actualPath))
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
/**
|
|
1749
|
+
* {{> dontSeeCurrentPathEquals }}
|
|
1750
|
+
*/
|
|
1751
|
+
async dontSeeCurrentPathEquals(path) {
|
|
1752
|
+
const currentUrl = await this._getPageUrl()
|
|
1753
|
+
const baseUrl = this.options.url || 'http://localhost'
|
|
1754
|
+
const actualPath = new URL(currentUrl, baseUrl).pathname
|
|
1755
|
+
return equals('url path').negate(normalizePath(path), normalizePath(actualPath))
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1687
1758
|
/**
|
|
1688
1759
|
* {{> see }}
|
|
1689
1760
|
*
|
|
@@ -2421,6 +2492,7 @@ class Puppeteer extends Helper {
|
|
|
2421
2492
|
*/
|
|
2422
2493
|
async waitInUrl(urlPart, sec = null) {
|
|
2423
2494
|
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
|
|
2495
|
+
const expectedUrl = resolveUrl(urlPart, this.options.url)
|
|
2424
2496
|
|
|
2425
2497
|
return this.page
|
|
2426
2498
|
.waitForFunction(
|
|
@@ -2429,12 +2501,12 @@ class Puppeteer extends Helper {
|
|
|
2429
2501
|
return currUrl.indexOf(urlPart) > -1
|
|
2430
2502
|
},
|
|
2431
2503
|
{ timeout: waitTimeout },
|
|
2432
|
-
|
|
2504
|
+
expectedUrl,
|
|
2433
2505
|
)
|
|
2434
2506
|
.catch(async e => {
|
|
2435
|
-
const currUrl = await this._getPageUrl()
|
|
2507
|
+
const currUrl = await this._getPageUrl()
|
|
2436
2508
|
if (/Waiting failed:/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2437
|
-
throw new Error(`expected url to include ${
|
|
2509
|
+
throw new Error(`expected url to include ${expectedUrl}, but found ${currUrl}`)
|
|
2438
2510
|
} else {
|
|
2439
2511
|
throw e
|
|
2440
2512
|
}
|
|
@@ -2446,18 +2518,13 @@ class Puppeteer extends Helper {
|
|
|
2446
2518
|
*/
|
|
2447
2519
|
async waitUrlEquals(urlPart, sec = null) {
|
|
2448
2520
|
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
|
|
2449
|
-
|
|
2450
|
-
const baseUrl = this.options.url
|
|
2451
|
-
let expectedUrl = urlPart
|
|
2452
|
-
if (urlPart.indexOf('http') < 0) {
|
|
2453
|
-
expectedUrl = baseUrl + urlPart
|
|
2454
|
-
}
|
|
2521
|
+
const expectedUrl = resolveUrl(urlPart, this.options.url)
|
|
2455
2522
|
|
|
2456
2523
|
return this.page
|
|
2457
2524
|
.waitForFunction(
|
|
2458
2525
|
url => {
|
|
2459
2526
|
const currUrl = decodeURIComponent(window.location.href)
|
|
2460
|
-
return currUrl
|
|
2527
|
+
return currUrl === url
|
|
2461
2528
|
},
|
|
2462
2529
|
{ timeout: waitTimeout },
|
|
2463
2530
|
expectedUrl,
|
|
@@ -2465,11 +2532,36 @@ class Puppeteer extends Helper {
|
|
|
2465
2532
|
.catch(async e => {
|
|
2466
2533
|
const currUrl = await this._getPageUrl()
|
|
2467
2534
|
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2535
|
+
throw new Error(`expected url to be ${expectedUrl}, but found ${currUrl}`)
|
|
2536
|
+
} else {
|
|
2537
|
+
throw e
|
|
2538
|
+
}
|
|
2539
|
+
})
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
/**
|
|
2543
|
+
* {{> waitCurrentPathEquals }}
|
|
2544
|
+
*/
|
|
2545
|
+
async waitCurrentPathEquals(path, sec = null) {
|
|
2546
|
+
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
|
|
2547
|
+
const normalizedPath = normalizePath(path)
|
|
2548
|
+
|
|
2549
|
+
return this.page
|
|
2550
|
+
.waitForFunction(
|
|
2551
|
+
expectedPath => {
|
|
2552
|
+
const actualPath = window.location.pathname
|
|
2553
|
+
const normalizePath = p => (p === '' || p === '/' ? '/' : p.replace(/\/+/g, '/').replace(/\/$/, '') || '/')
|
|
2554
|
+
return normalizePath(actualPath) === expectedPath
|
|
2555
|
+
},
|
|
2556
|
+
{ timeout: waitTimeout },
|
|
2557
|
+
normalizedPath,
|
|
2558
|
+
)
|
|
2559
|
+
.catch(async e => {
|
|
2560
|
+
const currUrl = await this._getPageUrl()
|
|
2561
|
+
const baseUrl = this.options.url || 'http://localhost'
|
|
2562
|
+
const actualPath = new URL(currUrl, baseUrl).pathname
|
|
2563
|
+
if (/Waiting failed/i.test(e.message) || /failed: timeout/i.test(e.message)) {
|
|
2564
|
+
throw new Error(`expected path to be ${normalizedPath}, but found ${normalizePath(actualPath)}`)
|
|
2473
2565
|
} else {
|
|
2474
2566
|
throw e
|
|
2475
2567
|
}
|
|
@@ -3140,43 +3232,57 @@ async function proceedIsChecked(assertType, option) {
|
|
|
3140
3232
|
return truth(`checkable ${option}`, 'to be checked')[assertType](selected)
|
|
3141
3233
|
}
|
|
3142
3234
|
|
|
3143
|
-
async function findVisibleFields(locator) {
|
|
3144
|
-
const els = await findFields.call(this, locator)
|
|
3235
|
+
async function findVisibleFields(locator, context = null) {
|
|
3236
|
+
const els = await findFields.call(this, locator, context)
|
|
3145
3237
|
const visible = await Promise.all(els.map(el => el.boundingBox()))
|
|
3146
3238
|
return els.filter((el, index) => visible[index])
|
|
3147
3239
|
}
|
|
3148
3240
|
|
|
3149
|
-
async function findFields(locator) {
|
|
3241
|
+
async function findFields(locator, context = null) {
|
|
3242
|
+
let contextEl
|
|
3243
|
+
if (context) {
|
|
3244
|
+
const contextPage = await this.context
|
|
3245
|
+
const contextEls = await findElements.call(this, contextPage, context)
|
|
3246
|
+
assertElementExists(contextEls, context, 'Context element')
|
|
3247
|
+
contextEl = contextEls[0]
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
const locateFn = contextEl
|
|
3251
|
+
? loc => findElements.call(this, contextEl, loc)
|
|
3252
|
+
: loc => this._locate(loc)
|
|
3253
|
+
|
|
3150
3254
|
const matchedLocator = new Locator(locator)
|
|
3151
3255
|
if (!matchedLocator.isFuzzy()) {
|
|
3152
|
-
return
|
|
3256
|
+
return locateFn(matchedLocator)
|
|
3153
3257
|
}
|
|
3154
3258
|
const literal = xpathLocator.literal(matchedLocator.value)
|
|
3155
3259
|
|
|
3156
|
-
let els = await
|
|
3260
|
+
let els = await locateFn({ xpath: Locator.field.labelEquals(literal) })
|
|
3157
3261
|
if (els.length) {
|
|
3158
3262
|
return els
|
|
3159
3263
|
}
|
|
3160
3264
|
|
|
3161
|
-
els = await
|
|
3265
|
+
els = await locateFn({ xpath: Locator.field.labelContains(literal) })
|
|
3162
3266
|
if (els.length) {
|
|
3163
3267
|
return els
|
|
3164
3268
|
}
|
|
3165
|
-
els = await
|
|
3269
|
+
els = await locateFn({ xpath: Locator.field.byName(literal) })
|
|
3166
3270
|
if (els.length) {
|
|
3167
3271
|
return els
|
|
3168
3272
|
}
|
|
3169
3273
|
|
|
3170
3274
|
// Try ARIA selector for accessible name
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3275
|
+
if (!contextEl) {
|
|
3276
|
+
try {
|
|
3277
|
+
const page = await this.context
|
|
3278
|
+
els = await page.$$(`::-p-aria(${matchedLocator.value})`)
|
|
3279
|
+
if (els.length) return els
|
|
3280
|
+
} catch (err) {
|
|
3281
|
+
// ARIA selector not supported or failed
|
|
3282
|
+
}
|
|
3177
3283
|
}
|
|
3178
3284
|
|
|
3179
|
-
return
|
|
3285
|
+
return locateFn({ css: matchedLocator.value })
|
|
3180
3286
|
}
|
|
3181
3287
|
|
|
3182
3288
|
async function proceedDragAndDrop(sourceLocator, destinationLocator) {
|
|
@@ -3205,8 +3311,8 @@ async function proceedDragAndDrop(sourceLocator, destinationLocator) {
|
|
|
3205
3311
|
await this._waitForAction()
|
|
3206
3312
|
}
|
|
3207
3313
|
|
|
3208
|
-
async function proceedSeeInField(assertType, field, value) {
|
|
3209
|
-
const els = await findVisibleFields.call(this, field)
|
|
3314
|
+
async function proceedSeeInField(assertType, field, value, context) {
|
|
3315
|
+
const els = await findVisibleFields.call(this, field, context)
|
|
3210
3316
|
assertElementExists(els, field, 'Field')
|
|
3211
3317
|
const el = els[0]
|
|
3212
3318
|
const tag = await el.getProperty('tagName').then(el => el.jsonValue())
|