codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.esm-aria
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 +89 -119
- package/bin/codecept.js +53 -54
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +70 -102
- package/lib/ai.js +131 -121
- package/lib/assert/empty.js +11 -12
- package/lib/assert/equal.js +16 -21
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +11 -15
- package/lib/assert/throws.js +3 -5
- package/lib/assert/truth.js +10 -7
- package/lib/assert.js +18 -18
- package/lib/codecept.js +112 -101
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +13 -14
- package/lib/command/definitions.js +24 -36
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +38 -39
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +49 -15
- package/lib/command/init.js +41 -37
- package/lib/command/interactive.js +22 -13
- package/lib/command/list.js +11 -10
- package/lib/command/run-multiple/chunk.js +50 -47
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +27 -47
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +15 -66
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +22 -21
- package/lib/command/workers/runTests.js +131 -241
- package/lib/config.js +111 -49
- package/lib/container.js +589 -244
- package/lib/data/context.js +16 -18
- package/lib/data/dataScenarioConfig.js +9 -9
- package/lib/data/dataTableArgument.js +7 -7
- package/lib/data/table.js +6 -12
- package/lib/effects.js +307 -0
- package/lib/els.js +160 -0
- package/lib/event.js +24 -19
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -81
- package/lib/helper/AI.js +3 -2
- package/lib/helper/ApiDataFactory.js +19 -19
- package/lib/helper/Appium.js +47 -51
- package/lib/helper/FileSystem.js +35 -15
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +72 -45
- package/lib/helper/Mochawesome.js +14 -11
- package/lib/helper/Playwright.js +832 -434
- package/lib/helper/Puppeteer.js +393 -292
- package/lib/helper/REST.js +32 -27
- package/lib/helper/WebDriver.js +320 -219
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/exit.js +10 -12
- package/lib/listener/{retry.js → globalRetry.js} +10 -10
- package/lib/listener/globalTimeout.js +166 -0
- package/lib/listener/helpers.js +43 -24
- package/lib/listener/mocha.js +4 -5
- package/lib/listener/result.js +11 -0
- package/lib/listener/steps.js +26 -23
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +264 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +160 -0
- package/lib/{interfaces → mocha}/featureConfig.js +33 -13
- package/lib/{interfaces → mocha}/gherkin.js +75 -45
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +178 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +229 -0
- package/lib/output.js +86 -64
- package/lib/parser.js +44 -44
- package/lib/pause.js +160 -139
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +137 -43
- package/lib/plugin/autoDelay.js +19 -15
- package/lib/plugin/coverage.js +22 -27
- package/lib/plugin/customLocator.js +5 -5
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/heal.js +49 -17
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +60 -19
- package/lib/plugin/screenshotOnFail.js +80 -83
- package/lib/plugin/stepByStepReport.js +70 -31
- package/lib/plugin/stepTimeout.js +7 -13
- package/lib/plugin/subtitles.js +10 -9
- package/lib/recorder.js +167 -126
- package/lib/rerun.js +94 -50
- package/lib/result.js +161 -0
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -332
- package/lib/steps.js +54 -0
- package/lib/store.js +37 -5
- package/lib/template/heal.js +2 -11
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +354 -250
- package/lib/workerStorage.js +16 -16
- package/lib/workers.js +366 -282
- package/package.json +107 -95
- package/translations/de-DE.js +5 -4
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +23 -9
- package/translations/it-IT.js +5 -4
- package/translations/ja-JP.js +5 -4
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +5 -4
- package/translations/pt-BR.js +5 -4
- package/translations/ru-RU.js +5 -4
- package/translations/utils.js +18 -0
- package/translations/zh-CN.js +5 -4
- package/translations/zh-TW.js +5 -4
- package/typings/index.d.ts +177 -186
- package/typings/promiseBasedTypes.d.ts +3573 -5941
- package/typings/types.d.ts +4042 -6370
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/Nightmare.js +0 -1504
- package/lib/helper/Protractor.js +0 -1863
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1414
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -62
- package/lib/interfaces/bdd.js +0 -81
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -113
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -127
- package/lib/plugin/selenoid.js +0 -384
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/plugin/tryTo.js +0 -115
- package/lib/plugin/wdio.js +0 -249
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
- package/lib/within.js +0 -70
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
function ConnectionRefused(err) {
|
|
2
|
-
this.message = "Can't connect to WebDriver.\n"
|
|
3
|
-
this.message += `${err}\n\n
|
|
4
|
-
this.message += 'Please make sure Selenium Server is running and accessible'
|
|
5
|
-
this.stack = err.stack
|
|
2
|
+
this.message = "Can't connect to WebDriver.\n"
|
|
3
|
+
this.message += `${err}\n\n`
|
|
4
|
+
this.message += 'Please make sure Selenium Server is running and accessible'
|
|
5
|
+
this.stack = err.stack
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
ConnectionRefused.prototype = Object.create(Error.prototype)
|
|
8
|
+
ConnectionRefused.prototype = Object.create(Error.prototype)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
export default ConnectionRefused
|
|
@@ -1,38 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
import Locator from '../../locator.js'
|
|
2
2
|
|
|
3
|
-
const prefixMessage = 'Element'
|
|
3
|
+
const prefixMessage = 'Element'
|
|
4
4
|
|
|
5
5
|
function seeElementError(locator) {
|
|
6
6
|
if (typeof locator === 'object') {
|
|
7
|
-
locator = JSON.stringify(locator)
|
|
7
|
+
locator = JSON.stringify(locator)
|
|
8
8
|
}
|
|
9
|
-
throw new Error(`${prefixMessage} "${
|
|
9
|
+
throw new Error(`${prefixMessage} "${new Locator(locator)}" is still visible on page.`)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function seeElementInDOMError(locator) {
|
|
13
13
|
if (typeof locator === 'object') {
|
|
14
|
-
locator = JSON.stringify(locator)
|
|
14
|
+
locator = JSON.stringify(locator)
|
|
15
15
|
}
|
|
16
|
-
throw new Error(`${prefixMessage} "${
|
|
16
|
+
throw new Error(`${prefixMessage} "${new Locator(locator)}" is still seen in DOM.`)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function dontSeeElementError(locator) {
|
|
20
20
|
if (typeof locator === 'object') {
|
|
21
|
-
locator = JSON.stringify(locator)
|
|
21
|
+
locator = JSON.stringify(locator)
|
|
22
22
|
}
|
|
23
|
-
throw new Error(`${prefixMessage} "${
|
|
23
|
+
throw new Error(`${prefixMessage} "${new Locator(locator)}" is not visible on page.`)
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function dontSeeElementInDOMError(locator) {
|
|
27
27
|
if (typeof locator === 'object') {
|
|
28
|
-
locator = JSON.stringify(locator)
|
|
28
|
+
locator = JSON.stringify(locator)
|
|
29
29
|
}
|
|
30
|
-
throw new Error(`${prefixMessage} "${
|
|
30
|
+
throw new Error(`${prefixMessage} "${new Locator(locator)}" is not seen in DOM.`)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
seeElementError,
|
|
35
|
-
dontSeeElementError,
|
|
36
|
-
seeElementInDOMError,
|
|
37
|
-
dontSeeElementInDOMError,
|
|
38
|
-
};
|
|
33
|
+
export { seeElementError, dontSeeElementError, seeElementInDOMError, dontSeeElementInDOMError }
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import Locator from '../../locator.js'
|
|
2
2
|
/**
|
|
3
3
|
* Uses to throw readable element not found error
|
|
4
4
|
* Stringify object's locators
|
|
5
5
|
*/
|
|
6
6
|
class ElementNotFound {
|
|
7
|
-
constructor(
|
|
8
|
-
locator,
|
|
9
|
-
prefixMessage = 'Element',
|
|
10
|
-
postfixMessage = 'was not found by text|CSS|XPath',
|
|
11
|
-
) {
|
|
7
|
+
constructor(locator, prefixMessage = 'Element', postfixMessage = 'was not found by text|CSS|XPath') {
|
|
12
8
|
if (typeof locator === 'object') {
|
|
13
|
-
locator = JSON.stringify(locator)
|
|
9
|
+
locator = JSON.stringify(locator)
|
|
14
10
|
}
|
|
15
|
-
throw new Error(`${prefixMessage} "${
|
|
11
|
+
throw new Error(`${prefixMessage} "${new Locator(locator)}" ${postfixMessage}`)
|
|
16
12
|
}
|
|
17
13
|
}
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
export default ElementNotFound
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
function RemoteBrowserConnectionRefused(err) {
|
|
2
|
-
this.message = 'Cannot connect to websocket endpoint.\n\n'
|
|
3
|
-
this.message += 'Please make sure remote browser is running and accessible.'
|
|
4
|
-
this.stack = err.error || err
|
|
2
|
+
this.message = 'Cannot connect to websocket endpoint.\n\n'
|
|
3
|
+
this.message += 'Please make sure remote browser is running and accessible.'
|
|
4
|
+
this.stack = err.error || err
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
RemoteBrowserConnectionRefused.prototype = Object.create(Error.prototype)
|
|
7
|
+
RemoteBrowserConnectionRefused.prototype = Object.create(Error.prototype)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
export default RemoteBrowserConnectionRefused
|
|
@@ -3,31 +3,31 @@
|
|
|
3
3
|
*/
|
|
4
4
|
class Console {
|
|
5
5
|
constructor() {
|
|
6
|
-
this._logEntries = []
|
|
6
|
+
this._logEntries = []
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
get entries() {
|
|
10
|
-
return this._logEntries
|
|
10
|
+
return this._logEntries
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
clear() {
|
|
14
|
-
this._logEntries = []
|
|
14
|
+
this._logEntries = []
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
includes(msg) {
|
|
18
|
-
const prev = this._logEntries[this._logEntries.length - 1]
|
|
19
|
-
if (!prev) return false
|
|
20
|
-
const text = msg.text && msg.text() || msg._text || ''
|
|
21
|
-
const prevText = prev.text && prev.text() || prev._text || ''
|
|
22
|
-
return text === prevText
|
|
18
|
+
const prev = this._logEntries[this._logEntries.length - 1]
|
|
19
|
+
if (!prev) return false
|
|
20
|
+
const text = (msg.text && msg.text()) || msg._text || ''
|
|
21
|
+
const prevText = (prev.text && prev.text()) || prev._text || ''
|
|
22
|
+
return text === prevText
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
add(entry) {
|
|
26
26
|
if (Array.isArray(entry)) {
|
|
27
|
-
this._logEntries = this._logEntries.concat(entry)
|
|
27
|
+
this._logEntries = this._logEntries.concat(entry)
|
|
28
28
|
}
|
|
29
|
-
this._logEntries.push(entry)
|
|
29
|
+
this._logEntries.push(entry)
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
export default Console
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import Locator from '../../locator.js'
|
|
2
|
+
|
|
3
|
+
function buildLocatorString(locator) {
|
|
4
|
+
if (locator.isCustom()) {
|
|
5
|
+
return `${locator.type}=${locator.value}`
|
|
6
|
+
}
|
|
7
|
+
if (locator.isXPath()) {
|
|
8
|
+
return `xpath=${locator.value}`
|
|
9
|
+
}
|
|
10
|
+
return locator.simplify()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function findElements(matcher, locator) {
|
|
14
|
+
const matchedLocator = new Locator(locator, 'css')
|
|
15
|
+
|
|
16
|
+
if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
|
|
17
|
+
if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
|
|
18
|
+
if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator)
|
|
19
|
+
if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator)
|
|
20
|
+
|
|
21
|
+
return matcher.locator(buildLocatorString(matchedLocator)).all()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function findElement(matcher, locator) {
|
|
25
|
+
const matchedLocator = new Locator(locator, 'css')
|
|
26
|
+
|
|
27
|
+
if (matchedLocator.type === 'react') return findReact(matcher, matchedLocator)
|
|
28
|
+
if (matchedLocator.type === 'vue') return findVue(matcher, matchedLocator)
|
|
29
|
+
if (matchedLocator.type === 'pw') return findByPlaywrightLocator(matcher, matchedLocator, { first: true })
|
|
30
|
+
if (matchedLocator.isRole()) return findByRole(matcher, matchedLocator, { first: true })
|
|
31
|
+
|
|
32
|
+
return matcher.locator(buildLocatorString(matchedLocator)).first()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function getVisibleElements(elements) {
|
|
36
|
+
const visibleElements = []
|
|
37
|
+
for (const element of elements) {
|
|
38
|
+
if (await element.isVisible()) {
|
|
39
|
+
visibleElements.push(element)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (visibleElements.length === 0) {
|
|
43
|
+
return elements
|
|
44
|
+
}
|
|
45
|
+
return visibleElements
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function findReact(matcher, locator) {
|
|
49
|
+
const details = locator.locator ?? { react: locator.value }
|
|
50
|
+
let locatorString = `_react=${details.react}`
|
|
51
|
+
|
|
52
|
+
if (details.props) {
|
|
53
|
+
locatorString += propBuilder(details.props)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return matcher.locator(locatorString).all()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function findVue(matcher, locator) {
|
|
60
|
+
const details = locator.locator ?? { vue: locator.value }
|
|
61
|
+
let locatorString = `_vue=${details.vue}`
|
|
62
|
+
|
|
63
|
+
if (details.props) {
|
|
64
|
+
locatorString += propBuilder(details.props)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return matcher.locator(locatorString).all()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function findByPlaywrightLocator(matcher, locator, { first = false } = {}) {
|
|
71
|
+
const details = locator.locator ?? { pw: locator.value }
|
|
72
|
+
const locatorValue = details.pw
|
|
73
|
+
|
|
74
|
+
const handle = matcher.locator(locatorValue)
|
|
75
|
+
return first ? handle.first() : handle.all()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function findByRole(matcher, locator, { first = false } = {}) {
|
|
79
|
+
const details = locator.locator ?? { role: locator.value }
|
|
80
|
+
const { role, text, name, exact, includeHidden, ...rest } = details
|
|
81
|
+
const options = { ...rest }
|
|
82
|
+
|
|
83
|
+
if (includeHidden !== undefined) options.includeHidden = includeHidden
|
|
84
|
+
|
|
85
|
+
const accessibleName = name ?? text
|
|
86
|
+
if (accessibleName !== undefined) {
|
|
87
|
+
options.name = accessibleName
|
|
88
|
+
if (exact === true) options.exact = true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const roleLocator = matcher.getByRole(role, options)
|
|
92
|
+
return first ? roleLocator.first() : roleLocator.all()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function propBuilder(props) {
|
|
96
|
+
let _props = ''
|
|
97
|
+
|
|
98
|
+
for (const [key, value] of Object.entries(props)) {
|
|
99
|
+
if (typeof value === 'object') {
|
|
100
|
+
for (const [k, v] of Object.entries(value)) {
|
|
101
|
+
_props += `[${key}.${k} = "${v}"]`
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
_props += `[${key} = "${value}"]`
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return _props
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export { buildLocatorString, findElements, findElement, getVisibleElements, findReact, findVue, findByPlaywrightLocator, findByRole }
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
|
|
1
|
+
export const createValueEngine = () => {
|
|
2
2
|
return {
|
|
3
3
|
// Creates a selector that matches given target when queried at the root.
|
|
4
4
|
// Can return undefined if unable to create one.
|
|
5
5
|
|
|
6
6
|
create(root, target) {
|
|
7
|
-
return null
|
|
7
|
+
return null
|
|
8
8
|
},
|
|
9
9
|
|
|
10
10
|
// Returns the first element matching given selector in the root's subtree.
|
|
11
11
|
query(root, selector) {
|
|
12
12
|
if (!root) {
|
|
13
|
-
return null
|
|
13
|
+
return null
|
|
14
14
|
}
|
|
15
|
-
return `${root.value}`.includes(selector) ? root : null
|
|
15
|
+
return `${root.value}`.includes(selector) ? root : null
|
|
16
16
|
},
|
|
17
17
|
|
|
18
18
|
// Returns all elements matching given selector in the root's subtree.
|
|
19
19
|
queryAll(root, selector) {
|
|
20
20
|
if (!root) {
|
|
21
|
-
return null
|
|
21
|
+
return null
|
|
22
22
|
}
|
|
23
|
-
return `${root.value}`.includes(selector) ? root : null
|
|
23
|
+
return `${root.value}`.includes(selector) ? root : null
|
|
24
24
|
},
|
|
25
|
-
}
|
|
26
|
-
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
export const createDisabledEngine = () => {
|
|
29
29
|
return {
|
|
30
30
|
// Creates a selector that matches given target when queried at the root.
|
|
31
31
|
// Can return undefined if unable to create one.
|
|
32
32
|
|
|
33
33
|
create(root, target) {
|
|
34
|
-
return null
|
|
34
|
+
return null
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
// Returns the first element matching given selector in the root's subtree.
|
|
38
38
|
query(root, value) {
|
|
39
|
-
const bool = value === 'true'
|
|
39
|
+
const bool = value === 'true'
|
|
40
40
|
if (!root) {
|
|
41
|
-
return null
|
|
41
|
+
return null
|
|
42
42
|
}
|
|
43
|
-
return root.disabled === bool ? root : null
|
|
43
|
+
return root.disabled === bool ? root : null
|
|
44
44
|
},
|
|
45
45
|
|
|
46
46
|
// Returns all elements matching given selector in the root's subtree.
|
|
47
47
|
queryAll(root, value) {
|
|
48
|
-
const bool = value === 'true'
|
|
48
|
+
const bool = value === 'true'
|
|
49
49
|
if (!root) {
|
|
50
|
-
return null
|
|
50
|
+
return null
|
|
51
51
|
}
|
|
52
|
-
return root.disabled === bool ? root : null
|
|
52
|
+
return root.disabled === bool ? root : null
|
|
53
53
|
},
|
|
54
|
-
}
|
|
55
|
-
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
const RESTART_OPTS = {
|
|
2
2
|
session: 'keep',
|
|
3
|
-
browser: true,
|
|
4
3
|
context: false,
|
|
5
|
-
}
|
|
4
|
+
}
|
|
6
5
|
|
|
7
|
-
let restarts = null
|
|
6
|
+
let restarts = null
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
export function setRestartStrategy(options) {
|
|
9
|
+
const { restart } = options
|
|
10
|
+
const stringOpts = Object.keys(RESTART_OPTS)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
if (stringOpts.includes(restart)) {
|
|
13
|
+
return (restarts = restart)
|
|
14
|
+
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
// When restart is false, don't restart anything
|
|
17
|
+
if (restart === false) {
|
|
18
|
+
restarts = null
|
|
19
|
+
return
|
|
20
|
+
}
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
restarts = Object.keys(RESTART_OPTS).find(key => RESTART_OPTS[key] === restart)
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
if (restarts === null || restarts === undefined) throw new Error('No restart strategy set, use the following values for restart: session, context')
|
|
25
|
+
}
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return restarts === 'browser';
|
|
32
|
-
},
|
|
33
|
-
};
|
|
27
|
+
export function restartsSession() {
|
|
28
|
+
return restarts === 'session'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function restartsContext() {
|
|
32
|
+
return restarts === 'context'
|
|
33
|
+
}
|
|
@@ -2,66 +2,66 @@
|
|
|
2
2
|
* Class to handle the interaction with the Dialog (Popup) Class from Puppeteer
|
|
3
3
|
*/
|
|
4
4
|
class Popup {
|
|
5
|
-
constructor(popup, defaultAction) {
|
|
6
|
-
this._popup = popup
|
|
7
|
-
this._actionType = ''
|
|
8
|
-
this._defaultAction = defaultAction
|
|
5
|
+
constructor(popup = null, defaultAction = '') {
|
|
6
|
+
this._popup = popup
|
|
7
|
+
this._actionType = ''
|
|
8
|
+
this._defaultAction = defaultAction
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
_assertValidActionType(action) {
|
|
12
12
|
if (['accept', 'cancel'].indexOf(action) === -1) {
|
|
13
|
-
throw new Error('Invalid Popup action type. Only "accept" or "cancel" actions are accepted')
|
|
13
|
+
throw new Error('Invalid Popup action type. Only "accept" or "cancel" actions are accepted')
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
set defaultAction(action) {
|
|
18
|
-
this._assertValidActionType(action)
|
|
19
|
-
this._defaultAction = action
|
|
18
|
+
this._assertValidActionType(action)
|
|
19
|
+
this._defaultAction = action
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
get defaultAction() {
|
|
23
|
-
return this._defaultAction
|
|
23
|
+
return this._defaultAction
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
get popup() {
|
|
27
|
-
return this._popup
|
|
27
|
+
return this._popup
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
set popup(popup) {
|
|
31
31
|
if (this._popup) {
|
|
32
|
-
|
|
32
|
+
return
|
|
33
33
|
}
|
|
34
|
-
this._popup = popup
|
|
34
|
+
this._popup = popup
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
get actionType() {
|
|
38
|
-
return this._actionType
|
|
38
|
+
return this._actionType
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
set actionType(action) {
|
|
42
|
-
this._assertValidActionType(action)
|
|
43
|
-
this._actionType = action
|
|
42
|
+
this._assertValidActionType(action)
|
|
43
|
+
this._actionType = action
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
clear() {
|
|
47
|
-
this._popup = null
|
|
48
|
-
this._actionType = ''
|
|
47
|
+
this._popup = null
|
|
48
|
+
this._actionType = ''
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
assertPopupVisible() {
|
|
52
52
|
if (!this._popup) {
|
|
53
|
-
throw new Error('There is no Popup visible')
|
|
53
|
+
throw new Error('There is no Popup visible')
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
assertPopupActionType(type) {
|
|
58
|
-
this.assertPopupVisible()
|
|
59
|
-
const expectedAction = this._actionType || this._defaultAction
|
|
58
|
+
this.assertPopupVisible()
|
|
59
|
+
const expectedAction = this._actionType || this._defaultAction
|
|
60
60
|
if (expectedAction !== type) {
|
|
61
|
-
throw new Error(`Popup action does not fit the expected action type. Expected popup action to be '${expectedAction}' not '${type}`)
|
|
61
|
+
throw new Error(`Popup action does not fit the expected action type. Expected popup action to be '${expectedAction}' not '${type}`)
|
|
62
62
|
}
|
|
63
|
-
this.clear()
|
|
63
|
+
this.clear()
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
export default Popup
|
|
@@ -1,66 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from 'fs'
|
|
2
2
|
|
|
3
|
-
let resqScript
|
|
3
|
+
let resqScript
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
if (!resqScript) resqScript = fs.readFileSync(
|
|
7
|
-
await matcher.evaluate(resqScript.toString())
|
|
8
|
-
await matcher
|
|
9
|
-
.evaluate(() => window.resq.waitToLoadReact());
|
|
5
|
+
export default async function findReact(matcher, locator) {
|
|
6
|
+
if (!resqScript) resqScript = fs.readFileSync(new URL('resq', import.meta.resolve('resq')).pathname)
|
|
7
|
+
await matcher.evaluate(resqScript.toString())
|
|
8
|
+
await matcher.evaluate(() => window.resq.waitToLoadReact())
|
|
10
9
|
const arrayHandle = await matcher.evaluateHandle(
|
|
11
|
-
|
|
12
|
-
const { selector, props, state } = obj
|
|
10
|
+
obj => {
|
|
11
|
+
const { selector, props, state } = obj
|
|
13
12
|
|
|
14
|
-
let elements = window.resq.resq$$(selector)
|
|
13
|
+
let elements = window.resq.resq$$(selector)
|
|
15
14
|
if (Object.keys(props).length) {
|
|
16
|
-
elements = elements.byProps(props)
|
|
15
|
+
elements = elements.byProps(props)
|
|
17
16
|
}
|
|
18
17
|
if (Object.keys(state).length) {
|
|
19
|
-
elements = elements.byState(state)
|
|
18
|
+
elements = elements.byState(state)
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
if (!elements.length) {
|
|
23
|
-
return []
|
|
22
|
+
return []
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
// resq returns an array of HTMLElements if the React component is a fragment
|
|
27
26
|
// this avoids having nested arrays of nodes which the driver does not understand
|
|
28
27
|
// [[div, div], [div, div]] => [div, div, div, div]
|
|
29
|
-
let nodes = []
|
|
28
|
+
let nodes = []
|
|
30
29
|
|
|
31
|
-
elements.forEach(
|
|
32
|
-
let { node, isFragment } = element
|
|
30
|
+
elements.forEach(element => {
|
|
31
|
+
let { node, isFragment } = element
|
|
33
32
|
|
|
34
33
|
if (!node) {
|
|
35
|
-
isFragment = true
|
|
36
|
-
node = element.children
|
|
34
|
+
isFragment = true
|
|
35
|
+
node = element.children
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
if (isFragment) {
|
|
40
|
-
nodes = nodes.concat(node)
|
|
39
|
+
nodes = nodes.concat(node)
|
|
41
40
|
} else {
|
|
42
|
-
nodes.push(node)
|
|
41
|
+
nodes.push(node)
|
|
43
42
|
}
|
|
44
|
-
})
|
|
43
|
+
})
|
|
45
44
|
|
|
46
|
-
return [...nodes]
|
|
45
|
+
return [...nodes]
|
|
47
46
|
},
|
|
48
47
|
{
|
|
49
48
|
selector: locator.react,
|
|
50
49
|
props: locator.props || {},
|
|
51
50
|
state: locator.state || {},
|
|
52
51
|
},
|
|
53
|
-
)
|
|
52
|
+
)
|
|
54
53
|
|
|
55
|
-
const properties = await arrayHandle.getProperties()
|
|
56
|
-
await arrayHandle.dispose()
|
|
57
|
-
const result = []
|
|
54
|
+
const properties = await arrayHandle.getProperties()
|
|
55
|
+
await arrayHandle.dispose()
|
|
56
|
+
const result = []
|
|
58
57
|
for (const property of properties.values()) {
|
|
59
|
-
const elementHandle = property.asElement()
|
|
58
|
+
const elementHandle = property.asElement()
|
|
60
59
|
if (elementHandle) {
|
|
61
|
-
result.push(elementHandle)
|
|
60
|
+
result.push(elementHandle)
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
return result
|
|
66
|
-
}
|
|
64
|
+
return result
|
|
65
|
+
}
|