codeceptjs 4.0.0-beta.5 → 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 +0 -45
- package/bin/codecept.js +46 -57
- package/lib/actor.js +15 -11
- package/lib/ai.js +6 -5
- package/lib/assert/empty.js +9 -8
- package/lib/assert/equal.js +15 -17
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +9 -11
- package/lib/assert/throws.js +1 -1
- package/lib/assert/truth.js +8 -5
- package/lib/assert.js +18 -18
- package/lib/codecept.js +66 -107
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +32 -27
- package/lib/command/configMigrate.js +11 -10
- package/lib/command/definitions.js +16 -10
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +29 -26
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +14 -14
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +8 -8
- package/lib/command/init.js +34 -31
- package/lib/command/interactive.js +11 -10
- package/lib/command/list.js +10 -9
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +16 -13
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +10 -24
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +20 -18
- package/lib/command/workers/runTests.js +117 -269
- package/lib/config.js +111 -49
- package/lib/container.js +299 -102
- package/lib/data/context.js +6 -5
- package/lib/data/dataScenarioConfig.js +1 -1
- package/lib/data/dataTableArgument.js +1 -1
- package/lib/data/table.js +1 -1
- package/lib/effects.js +94 -10
- package/lib/els.js +11 -9
- package/lib/event.js +11 -10
- package/lib/globals.js +141 -0
- package/lib/heal.js +12 -12
- package/lib/helper/AI.js +1 -1
- package/lib/helper/ApiDataFactory.js +16 -13
- package/lib/helper/FileSystem.js +32 -12
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +1 -1
- package/lib/helper/JSONResponse.js +19 -30
- package/lib/helper/Mochawesome.js +9 -28
- package/lib/helper/Playwright.js +668 -265
- package/lib/helper/Puppeteer.js +284 -169
- package/lib/helper/REST.js +29 -12
- package/lib/helper/WebDriver.js +191 -71
- 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 +1 -1
- 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 +6 -7
- package/lib/listener/exit.js +4 -3
- package/lib/listener/globalRetry.js +5 -5
- package/lib/listener/globalTimeout.js +11 -10
- package/lib/listener/helpers.js +33 -14
- package/lib/listener/mocha.js +3 -4
- package/lib/listener/result.js +4 -5
- package/lib/listener/steps.js +7 -18
- package/lib/listener/store.js +3 -3
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +108 -75
- package/lib/mocha/bdd.js +99 -13
- package/lib/mocha/cli.js +60 -27
- package/lib/mocha/factory.js +75 -19
- package/lib/mocha/featureConfig.js +1 -1
- package/lib/mocha/gherkin.js +57 -25
- package/lib/mocha/hooks.js +12 -3
- package/lib/mocha/index.js +13 -4
- package/lib/mocha/inject.js +22 -5
- package/lib/mocha/scenarioConfig.js +2 -2
- package/lib/mocha/suite.js +9 -2
- package/lib/mocha/test.js +10 -13
- package/lib/mocha/ui.js +28 -31
- package/lib/output.js +11 -9
- package/lib/parser.js +44 -44
- package/lib/pause.js +15 -16
- package/lib/plugin/analyze.js +19 -12
- package/lib/plugin/auth.js +20 -21
- package/lib/plugin/autoDelay.js +12 -8
- package/lib/plugin/coverage.js +12 -8
- package/lib/plugin/customLocator.js +3 -3
- package/lib/plugin/customReporter.js +3 -2
- package/lib/plugin/heal.js +14 -9
- package/lib/plugin/pageInfo.js +10 -10
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +47 -5
- package/lib/plugin/screenshotOnFail.js +75 -37
- package/lib/plugin/stepByStepReport.js +14 -14
- package/lib/plugin/stepTimeout.js +4 -3
- package/lib/plugin/subtitles.js +6 -5
- package/lib/recorder.js +33 -23
- package/lib/rerun.js +69 -26
- package/lib/result.js +4 -4
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +6 -6
- package/lib/step/config.js +1 -1
- package/lib/step/func.js +3 -3
- package/lib/step/helper.js +3 -3
- package/lib/step/meta.js +4 -4
- package/lib/step/record.js +11 -11
- package/lib/step/retry.js +3 -3
- package/lib/step/section.js +3 -3
- package/lib/step.js +7 -10
- package/lib/steps.js +9 -5
- package/lib/store.js +1 -1
- package/lib/timeout.js +1 -7
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +68 -97
- package/lib/workerStorage.js +16 -17
- package/lib/workers.js +145 -171
- package/package.json +63 -57
- package/translations/de-DE.js +2 -2
- package/translations/fr-FR.js +2 -2
- package/translations/index.js +23 -10
- package/translations/it-IT.js +2 -2
- package/translations/ja-JP.js +2 -2
- package/translations/nl-NL.js +2 -2
- package/translations/pl-PL.js +2 -2
- package/translations/pt-BR.js +2 -2
- package/translations/ru-RU.js +2 -2
- package/translations/utils.js +11 -2
- package/translations/zh-CN.js +2 -2
- package/translations/zh-TW.js +2 -2
- package/typings/index.d.ts +7 -18
- package/typings/promiseBasedTypes.d.ts +3769 -5450
- package/typings/types.d.ts +3953 -5778
- package/bin/test-server.js +0 -53
- package/lib/element/WebElement.js +0 -327
- package/lib/helper/Nightmare.js +0 -1486
- package/lib/helper/Protractor.js +0 -1840
- package/lib/helper/TestCafe.js +0 -1391
- 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 -61
- package/lib/listener/retryEnhancer.js +0 -85
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/autoLogin.js +0 -5
- package/lib/plugin/commentStep.js +0 -141
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/htmlReporter.js +0 -1947
- package/lib/plugin/retryTo.js +0 -16
- package/lib/plugin/selenoid.js +0 -364
- package/lib/plugin/standardActingHelpers.js +0 -6
- package/lib/plugin/tryTo.js +0 -16
- package/lib/plugin/wdio.js +0 -247
- package/lib/test-server.js +0 -323
- package/lib/within.js +0 -90
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -1,77 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import { isInTraffic, createAdvancedTestResults, getTrafficDump } from './utils.js'
|
|
3
3
|
|
|
4
4
|
function dontSeeTraffic({ name, url }) {
|
|
5
5
|
if (!this.recordedAtLeastOnce) {
|
|
6
|
-
throw new Error('Failure in test automation. You use "I.dontSeeTraffic", but "I.startRecordingTraffic" was never called before.')
|
|
6
|
+
throw new Error('Failure in test automation. You use "I.dontSeeTraffic", but "I.startRecordingTraffic" was never called before.')
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
if (!name) {
|
|
10
|
-
throw new Error('Missing required key "name" in object given to "I.dontSeeTraffic".')
|
|
10
|
+
throw new Error('Missing required key "name" in object given to "I.dontSeeTraffic".')
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
if (!url) {
|
|
14
|
-
throw new Error('Missing required key "url" in object given to "I.dontSeeTraffic".')
|
|
14
|
+
throw new Error('Missing required key "url" in object given to "I.dontSeeTraffic".')
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if (isInTraffic.call(this, url)) {
|
|
18
|
-
assert.fail(`Traffic with name "${name}" (URL: "${url}') found, but was not expected to be found.`)
|
|
18
|
+
assert.fail(`Traffic with name "${name}" (URL: "${url}') found, but was not expected to be found.`)
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
async function seeTraffic({
|
|
23
|
-
name, url, parameters, requestPostData, timeout = 10,
|
|
24
|
-
}) {
|
|
22
|
+
async function seeTraffic({ name, url, parameters, requestPostData, timeout = 10 }) {
|
|
25
23
|
if (!name) {
|
|
26
|
-
throw new Error('Missing required key "name" in object given to "I.seeTraffic".')
|
|
24
|
+
throw new Error('Missing required key "name" in object given to "I.seeTraffic".')
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
if (!url) {
|
|
30
|
-
throw new Error('Missing required key "url" in object given to "I.seeTraffic".')
|
|
28
|
+
throw new Error('Missing required key "url" in object given to "I.seeTraffic".')
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
if (!this.recording || !this.recordedAtLeastOnce) {
|
|
34
|
-
throw new Error('Failure in test automation. You use "I.seeTraffic", but "I.startRecordingTraffic" was never called before.')
|
|
32
|
+
throw new Error('Failure in test automation. You use "I.seeTraffic", but "I.startRecordingTraffic" was never called before.')
|
|
35
33
|
}
|
|
36
34
|
|
|
37
35
|
for (let i = 0; i <= timeout * 2; i++) {
|
|
38
|
-
const found = isInTraffic.call(this, url, parameters)
|
|
36
|
+
const found = isInTraffic.call(this, url, parameters)
|
|
39
37
|
if (found) {
|
|
40
|
-
return true
|
|
38
|
+
return true
|
|
41
39
|
}
|
|
42
|
-
await new Promise(
|
|
43
|
-
setTimeout(done, 1000)
|
|
44
|
-
})
|
|
40
|
+
await new Promise(done => {
|
|
41
|
+
setTimeout(done, 1000)
|
|
42
|
+
})
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
// check request post data
|
|
48
46
|
if (requestPostData && isInTraffic.call(this, url)) {
|
|
49
|
-
const advancedTestResults = createAdvancedTestResults(url, requestPostData, this.requests)
|
|
47
|
+
const advancedTestResults = createAdvancedTestResults(url, requestPostData, this.requests)
|
|
50
48
|
|
|
51
|
-
assert.equal(advancedTestResults, true, `Traffic named "${name}" found correct URL ${url}, BUT the post data did not match:\n ${advancedTestResults}`)
|
|
49
|
+
assert.equal(advancedTestResults, true, `Traffic named "${name}" found correct URL ${url}, BUT the post data did not match:\n ${advancedTestResults}`)
|
|
52
50
|
} else if (parameters && isInTraffic.call(this, url)) {
|
|
53
|
-
const advancedTestResults = createAdvancedTestResults(url, parameters, this.requests)
|
|
51
|
+
const advancedTestResults = createAdvancedTestResults(url, parameters, this.requests)
|
|
54
52
|
|
|
55
|
-
assert.fail(
|
|
56
|
-
`Traffic named "${name}" found correct URL ${url}, BUT the query parameters did not match:\n`
|
|
57
|
-
+ `${advancedTestResults}`,
|
|
58
|
-
);
|
|
53
|
+
assert.fail(`Traffic named "${name}" found correct URL ${url}, BUT the query parameters did not match:\n` + `${advancedTestResults}`)
|
|
59
54
|
} else {
|
|
60
|
-
assert.fail(
|
|
61
|
-
`Traffic named "${name}" not found in recorded traffic within ${timeout} seconds.\n`
|
|
62
|
-
+ `Expected url: ${url}.\n`
|
|
63
|
-
+ `Recorded traffic:\n${getTrafficDump.call(this)}`,
|
|
64
|
-
);
|
|
55
|
+
assert.fail(`Traffic named "${name}" not found in recorded traffic within ${timeout} seconds.\n` + `Expected url: ${url}.\n` + `Recorded traffic:\n${getTrafficDump.call(this)}`)
|
|
65
56
|
}
|
|
66
57
|
}
|
|
67
58
|
|
|
68
59
|
async function grabRecordedNetworkTraffics() {
|
|
69
60
|
if (!this.recording || !this.recordedAtLeastOnce) {
|
|
70
|
-
throw new Error('Failure in test automation. You use "I.grabRecordedNetworkTraffics", but "I.startRecordingTraffic" was never called before.')
|
|
61
|
+
throw new Error('Failure in test automation. You use "I.grabRecordedNetworkTraffics", but "I.startRecordingTraffic" was never called before.')
|
|
71
62
|
}
|
|
72
63
|
|
|
73
|
-
const promises = this.requests.map(async
|
|
74
|
-
const resp = await request.response
|
|
64
|
+
const promises = this.requests.map(async request => {
|
|
65
|
+
const resp = await request.response
|
|
75
66
|
|
|
76
67
|
if (!resp) {
|
|
77
68
|
return {
|
|
@@ -81,13 +72,13 @@ async function grabRecordedNetworkTraffics() {
|
|
|
81
72
|
statusText: '',
|
|
82
73
|
body: '',
|
|
83
74
|
},
|
|
84
|
-
}
|
|
75
|
+
}
|
|
85
76
|
}
|
|
86
77
|
|
|
87
|
-
let body
|
|
78
|
+
let body
|
|
88
79
|
try {
|
|
89
80
|
// There's no 'body' for some requests (redirect etc...)
|
|
90
|
-
body = JSON.parse((await resp.body()).toString())
|
|
81
|
+
body = JSON.parse((await resp.body()).toString())
|
|
91
82
|
} catch (e) {
|
|
92
83
|
// only interested in JSON, not HTML responses.
|
|
93
84
|
}
|
|
@@ -99,25 +90,19 @@ async function grabRecordedNetworkTraffics() {
|
|
|
99
90
|
statusText: resp.statusText(),
|
|
100
91
|
body,
|
|
101
92
|
},
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
return Promise.all(promises)
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
return Promise.all(promises)
|
|
105
96
|
}
|
|
106
97
|
|
|
107
98
|
function stopRecordingTraffic() {
|
|
108
99
|
// @ts-ignore
|
|
109
|
-
this.page.removeAllListeners('request')
|
|
110
|
-
this.recording = false
|
|
100
|
+
this.page.removeAllListeners('request')
|
|
101
|
+
this.recording = false
|
|
111
102
|
}
|
|
112
103
|
|
|
113
104
|
function flushNetworkTraffics() {
|
|
114
|
-
this.requests = []
|
|
105
|
+
this.requests = []
|
|
115
106
|
}
|
|
116
107
|
|
|
117
|
-
|
|
118
|
-
dontSeeTraffic,
|
|
119
|
-
seeTraffic,
|
|
120
|
-
grabRecordedNetworkTraffics,
|
|
121
|
-
stopRecordingTraffic,
|
|
122
|
-
flushNetworkTraffics,
|
|
123
|
-
};
|
|
108
|
+
export { dontSeeTraffic, seeTraffic, grabRecordedNetworkTraffics, stopRecordingTraffic, flushNetworkTraffics }
|