codeceptjs 4.0.0-beta.2 → 4.0.0-beta.4
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 +2 -2
- package/bin/codecept.js +84 -81
- package/lib/actor.js +13 -13
- package/lib/ai.js +10 -13
- package/lib/assert/empty.js +20 -21
- package/lib/assert/equal.js +37 -39
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +46 -47
- package/lib/assert/throws.js +13 -11
- package/lib/assert/truth.js +19 -22
- package/lib/assert.js +4 -2
- package/lib/cli.js +56 -49
- package/lib/codecept.js +145 -155
- package/lib/colorUtils.js +3 -3
- package/lib/command/configMigrate.js +58 -52
- package/lib/command/definitions.js +88 -89
- package/lib/command/dryRun.js +79 -81
- package/lib/command/generate.js +197 -188
- package/lib/command/gherkin/init.js +27 -16
- package/lib/command/gherkin/snippets.js +21 -21
- package/lib/command/gherkin/steps.js +8 -8
- package/lib/command/info.js +40 -38
- package/lib/command/init.js +290 -288
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple/chunk.js +5 -5
- package/lib/command/run-multiple/collection.js +3 -3
- package/lib/command/run-multiple/run.js +6 -2
- package/lib/command/run-multiple.js +113 -93
- package/lib/command/run-rerun.js +20 -25
- package/lib/command/run-workers.js +64 -66
- package/lib/command/run.js +26 -29
- package/lib/command/utils.js +80 -65
- package/lib/command/workers/runTests.js +11 -12
- package/lib/config.js +10 -9
- package/lib/container.js +40 -48
- package/lib/data/context.js +60 -59
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +26 -20
- package/lib/event.js +163 -167
- package/lib/heal.js +14 -18
- package/lib/helper/AI.js +130 -41
- package/lib/helper/ApiDataFactory.js +74 -70
- package/lib/helper/Appium.js +416 -388
- package/lib/helper/ExpectHelper.js +40 -48
- package/lib/helper/FileSystem.js +80 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +51 -51
- package/lib/helper/JSONResponse.js +65 -62
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/Nightmare.js +664 -571
- package/lib/helper/Playwright.js +1367 -1222
- package/lib/helper/Protractor.js +663 -635
- package/lib/helper/Puppeteer.js +1232 -1132
- package/lib/helper/REST.js +183 -68
- package/lib/helper/SoftExpectHelper.js +2 -2
- package/lib/helper/TestCafe.js +490 -486
- package/lib/helper/WebDriver.js +1246 -1297
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/helper/errors/ConnectionRefused.js +1 -1
- package/lib/helper/errors/ElementAssertion.js +2 -2
- package/lib/helper/errors/ElementNotFound.js +2 -2
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
- package/lib/helper/extras/Console.js +1 -1
- package/lib/helper/extras/PlaywrightPropEngine.js +4 -4
- package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
- package/lib/helper/extras/PlaywrightRestartOpts.js +21 -18
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +3 -3
- package/lib/helper/network/actions.js +14 -7
- package/lib/helper/network/utils.js +4 -3
- package/lib/helper/scripts/blurElement.js +1 -1
- package/lib/helper/scripts/focusElement.js +1 -1
- package/lib/helper/scripts/highlightElement.js +1 -1
- package/lib/helper/scripts/isElementClickable.js +1 -1
- package/lib/helper/testcafe/testControllerHolder.js +1 -1
- package/lib/helper/testcafe/testcafe-utils.js +7 -8
- package/lib/helper.js +1 -3
- package/lib/history.js +6 -5
- package/lib/hooks.js +6 -6
- package/lib/html.js +7 -7
- package/lib/index.js +25 -41
- package/lib/interfaces/bdd.js +47 -64
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +124 -118
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -24
- package/lib/listener/exit.js +12 -12
- package/lib/listener/helpers.js +42 -42
- package/lib/listener/mocha.js +11 -11
- package/lib/listener/retry.js +32 -30
- package/lib/listener/steps.js +50 -53
- package/lib/listener/timeout.js +54 -54
- package/lib/locator.js +7 -11
- package/lib/mochaFactory.js +18 -15
- package/lib/output.js +19 -15
- package/lib/parser.js +15 -12
- package/lib/pause.js +45 -38
- package/lib/plugin/allure.js +15 -15
- package/lib/plugin/autoDelay.js +29 -37
- package/lib/plugin/autoLogin.js +70 -65
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +112 -67
- package/lib/plugin/customLocator.js +21 -20
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +38 -38
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +67 -108
- package/lib/plugin/pauseOnFail.js +11 -11
- package/lib/plugin/retryFailedStep.js +32 -39
- package/lib/plugin/retryTo.js +46 -40
- package/lib/plugin/screenshotOnFail.js +109 -87
- package/lib/plugin/selenoid.js +131 -118
- package/lib/plugin/standardActingHelpers.js +2 -8
- package/lib/plugin/stepByStepReport.js +110 -91
- package/lib/plugin/stepTimeout.js +24 -23
- package/lib/plugin/subtitles.js +34 -35
- package/lib/plugin/tryTo.js +40 -30
- package/lib/plugin/wdio.js +78 -75
- package/lib/recorder.js +14 -17
- package/lib/rerun.js +11 -10
- package/lib/scenario.js +25 -23
- package/lib/secret.js +4 -3
- package/lib/session.js +10 -10
- package/lib/step.js +12 -9
- package/lib/store.js +2 -3
- package/lib/transform.js +1 -1
- package/lib/translation.js +7 -8
- package/lib/ui.js +12 -14
- package/lib/utils.js +70 -72
- package/lib/within.js +10 -10
- package/lib/workerStorage.js +27 -25
- package/lib/workers.js +29 -33
- package/package.json +67 -68
- package/translations/de-DE.js +2 -1
- package/translations/fr-FR.js +2 -2
- package/translations/index.js +9 -13
- package/translations/it-IT.js +1 -1
- package/translations/ja-JP.js +1 -1
- package/translations/pl-PL.js +1 -1
- package/translations/pt-BR.js +1 -1
- package/translations/ru-RU.js +1 -1
- package/translations/zh-CN.js +1 -1
- package/translations/zh-TW.js +1 -1
- package/typings/index.d.ts +423 -65
- package/typings/promiseBasedTypes.d.ts +41 -172
- package/typings/types.d.ts +43 -178
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/MockServer.js +0 -223
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const recorder = require('../recorder')
|
|
3
|
+
const { MetaStep } = require('../step')
|
|
4
4
|
|
|
5
|
-
let currentCommentStep
|
|
5
|
+
let currentCommentStep
|
|
6
6
|
|
|
7
|
-
const defaultGlobalName = '__'
|
|
7
|
+
const defaultGlobalName = '__'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Add descriptive nested steps for your tests:
|
|
@@ -99,38 +99,38 @@ const defaultGlobalName = '__';
|
|
|
99
99
|
* });
|
|
100
100
|
* ```
|
|
101
101
|
*/
|
|
102
|
-
|
|
102
|
+
module.exports = function (config) {
|
|
103
103
|
event.dispatcher.on(event.test.started, () => {
|
|
104
|
-
currentCommentStep = null
|
|
105
|
-
})
|
|
104
|
+
currentCommentStep = null
|
|
105
|
+
})
|
|
106
106
|
|
|
107
107
|
event.dispatcher.on(event.step.started, (step) => {
|
|
108
108
|
if (currentCommentStep) {
|
|
109
|
-
const metaStep = getRootMetaStep(step)
|
|
109
|
+
const metaStep = getRootMetaStep(step)
|
|
110
110
|
|
|
111
111
|
if (metaStep !== currentCommentStep) {
|
|
112
|
-
metaStep.metaStep = currentCommentStep
|
|
112
|
+
metaStep.metaStep = currentCommentStep
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
})
|
|
115
|
+
})
|
|
116
116
|
|
|
117
117
|
if (config.registerGlobal) {
|
|
118
118
|
if (config.registerGlobal === true) {
|
|
119
|
-
config.registerGlobal = defaultGlobalName
|
|
119
|
+
config.registerGlobal = defaultGlobalName
|
|
120
120
|
}
|
|
121
|
-
global[config.registerGlobal] = setCommentString
|
|
121
|
+
global[config.registerGlobal] = setCommentString
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
return setCommentString
|
|
124
|
+
return setCommentString
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
function getRootMetaStep(step) {
|
|
128
|
-
if (step.metaStep) return getRootMetaStep(step.metaStep)
|
|
129
|
-
return step
|
|
128
|
+
if (step.metaStep) return getRootMetaStep(step.metaStep)
|
|
129
|
+
return step
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
function setCommentString(string) {
|
|
133
133
|
recorder.add('set comment metastep', () => {
|
|
134
|
-
currentCommentStep = new MetaStep(String.raw(string), '')
|
|
135
|
-
})
|
|
134
|
+
currentCommentStep = new MetaStep(String.raw(string), '')
|
|
135
|
+
})
|
|
136
136
|
}
|
package/lib/plugin/coverage.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
const debugModule = require('debug')
|
|
2
|
+
const { CoverageReport } = require('monocart-coverage-reports')
|
|
3
|
+
const Container = require('../container')
|
|
4
|
+
const recorder = require('../recorder')
|
|
5
|
+
const event = require('../event')
|
|
6
|
+
const output = require('../output')
|
|
7
|
+
const { deepMerge } = require('../utils')
|
|
8
8
|
|
|
9
9
|
const defaultConfig = {
|
|
10
10
|
name: 'CodeceptJS Coverage Report',
|
|
11
11
|
outputDir: 'output/coverage',
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
const supportedHelpers = ['Puppeteer', 'Playwright']
|
|
14
|
+
const supportedHelpers = ['Puppeteer', 'Playwright', 'WebDriver']
|
|
15
15
|
|
|
16
16
|
const v8CoverageHelpers = {
|
|
17
17
|
Playwright: {
|
|
@@ -23,15 +23,15 @@ const v8CoverageHelpers = {
|
|
|
23
23
|
page.coverage.startCSSCoverage({
|
|
24
24
|
resetOnNavigation: false,
|
|
25
25
|
}),
|
|
26
|
-
])
|
|
26
|
+
])
|
|
27
27
|
},
|
|
28
28
|
takeCoverage: async (page, coverageReport) => {
|
|
29
29
|
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
30
30
|
page.coverage.stopJSCoverage(),
|
|
31
31
|
page.coverage.stopCSSCoverage(),
|
|
32
|
-
])
|
|
33
|
-
const coverageList = [...jsCoverage, ...cssCoverage]
|
|
34
|
-
await coverageReport.add(coverageList)
|
|
32
|
+
])
|
|
33
|
+
const coverageList = [...jsCoverage, ...cssCoverage]
|
|
34
|
+
await coverageReport.add(coverageList)
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
Puppeteer: {
|
|
@@ -44,24 +44,57 @@ const v8CoverageHelpers = {
|
|
|
44
44
|
page.coverage.startCSSCoverage({
|
|
45
45
|
resetOnNavigation: false,
|
|
46
46
|
}),
|
|
47
|
-
])
|
|
47
|
+
])
|
|
48
|
+
},
|
|
49
|
+
takeCoverage: async (page, coverageReport) => {
|
|
50
|
+
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
51
|
+
page.coverage.stopJSCoverage(),
|
|
52
|
+
page.coverage.stopCSSCoverage(),
|
|
53
|
+
])
|
|
54
|
+
// to raw V8 script coverage
|
|
55
|
+
const coverageList = [
|
|
56
|
+
...jsCoverage.map((it) => {
|
|
57
|
+
return {
|
|
58
|
+
source: it.text,
|
|
59
|
+
...it.rawScriptCoverage,
|
|
60
|
+
}
|
|
61
|
+
}),
|
|
62
|
+
...cssCoverage,
|
|
63
|
+
]
|
|
64
|
+
await coverageReport.add(coverageList)
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
WebDriver: {
|
|
68
|
+
startCoverage: async (page) => {
|
|
69
|
+
await Promise.all([
|
|
70
|
+
page.coverage.startJSCoverage({
|
|
71
|
+
resetOnNavigation: false,
|
|
72
|
+
includeRawScriptCoverage: true,
|
|
73
|
+
}),
|
|
74
|
+
page.coverage.startCSSCoverage({
|
|
75
|
+
resetOnNavigation: false,
|
|
76
|
+
}),
|
|
77
|
+
])
|
|
48
78
|
},
|
|
49
79
|
takeCoverage: async (page, coverageReport) => {
|
|
50
80
|
const [jsCoverage, cssCoverage] = await Promise.all([
|
|
51
81
|
page.coverage.stopJSCoverage(),
|
|
52
82
|
page.coverage.stopCSSCoverage(),
|
|
53
|
-
])
|
|
83
|
+
])
|
|
54
84
|
// to raw V8 script coverage
|
|
55
|
-
const coverageList = [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
85
|
+
const coverageList = [
|
|
86
|
+
...jsCoverage.map((it) => {
|
|
87
|
+
return {
|
|
88
|
+
source: it.text,
|
|
89
|
+
...it.rawScriptCoverage,
|
|
90
|
+
}
|
|
91
|
+
}),
|
|
92
|
+
...cssCoverage,
|
|
93
|
+
]
|
|
94
|
+
await coverageReport.add(coverageList)
|
|
62
95
|
},
|
|
63
96
|
},
|
|
64
|
-
}
|
|
97
|
+
}
|
|
65
98
|
|
|
66
99
|
/**
|
|
67
100
|
* Dumps code coverage from Playwright/Puppeteer after every test.
|
|
@@ -89,67 +122,79 @@ const v8CoverageHelpers = {
|
|
|
89
122
|
* * `sourcePath`: option to resolve a custom path.
|
|
90
123
|
*
|
|
91
124
|
*/
|
|
125
|
+
module.exports = function (config) {
|
|
126
|
+
config = deepMerge(defaultConfig, config)
|
|
127
|
+
|
|
128
|
+
if (config.debug) config.logging = 'debug'
|
|
92
129
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (config.debug) config.logging = 'debug';
|
|
96
|
-
const helpers = container.helpers();
|
|
97
|
-
console.log(helpers);
|
|
98
|
-
let coverageRunning = false;
|
|
130
|
+
const helpers = Container.helpers()
|
|
131
|
+
let coverageRunning = false
|
|
99
132
|
|
|
100
|
-
const v8Names = Object.keys(v8CoverageHelpers)
|
|
101
|
-
const helperName = Object.keys(helpers).find((it) => v8Names.includes(it))
|
|
133
|
+
const v8Names = Object.keys(v8CoverageHelpers)
|
|
134
|
+
const helperName = Object.keys(helpers).find((it) => v8Names.includes(it))
|
|
102
135
|
if (!helperName) {
|
|
103
|
-
console.error(`Coverage is only supported in ${supportedHelpers.join(' or ')}`)
|
|
136
|
+
console.error(`Coverage is only supported in ${supportedHelpers.join(' or ')}`)
|
|
104
137
|
// no helpers for screenshot
|
|
105
|
-
return
|
|
138
|
+
return
|
|
106
139
|
}
|
|
107
140
|
|
|
108
|
-
config.name = `${config.name} - in ${helperName}
|
|
109
|
-
const
|
|
141
|
+
config.name = `${config.name} - in ${helperName}`
|
|
142
|
+
const debug = debugModule(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`)
|
|
143
|
+
|
|
144
|
+
const helper = helpers[helperName]
|
|
110
145
|
|
|
111
|
-
const
|
|
112
|
-
const v8Helper = v8CoverageHelpers[helperName];
|
|
146
|
+
const v8Helper = v8CoverageHelpers[helperName]
|
|
113
147
|
|
|
114
148
|
const coverageOptions = {
|
|
115
149
|
...config,
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (helperName === 'WebDriver') coverageOptions.coverageProvider = 'v8'
|
|
153
|
+
|
|
154
|
+
const coverageReport = new CoverageReport(coverageOptions)
|
|
155
|
+
coverageReport.cleanCache()
|
|
119
156
|
|
|
120
157
|
event.dispatcher.on(event.all.after, async () => {
|
|
121
|
-
output.print(`writing ${coverageOptions.outputDir}`)
|
|
122
|
-
await coverageReport.generate()
|
|
123
|
-
})
|
|
158
|
+
output.print(`writing ${coverageOptions.outputDir}`)
|
|
159
|
+
await coverageReport.generate()
|
|
160
|
+
})
|
|
124
161
|
|
|
125
162
|
// we're going to try to "start" coverage before each step because this is
|
|
126
163
|
// when the browser is already up and is ready to start coverage.
|
|
127
164
|
event.dispatcher.on(event.step.before, () => {
|
|
128
|
-
recorder.add(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
165
|
+
recorder.add(
|
|
166
|
+
'start coverage',
|
|
167
|
+
async () => {
|
|
168
|
+
if (coverageRunning) {
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
if (!helper.page || !helper.page.coverage) {
|
|
172
|
+
return
|
|
173
|
+
}
|
|
174
|
+
coverageRunning = true
|
|
175
|
+
debug('--> starting coverage <--')
|
|
176
|
+
await v8Helper.startCoverage(helper.page)
|
|
177
|
+
},
|
|
178
|
+
true,
|
|
179
|
+
)
|
|
180
|
+
})
|
|
140
181
|
|
|
141
182
|
// Save coverage data after every test run
|
|
142
183
|
event.dispatcher.on(event.test.after, (test) => {
|
|
143
|
-
recorder.add(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
184
|
+
recorder.add(
|
|
185
|
+
'take coverage',
|
|
186
|
+
async () => {
|
|
187
|
+
if (!coverageRunning) {
|
|
188
|
+
return
|
|
189
|
+
}
|
|
190
|
+
if (!helper.page || !helper.page.coverage) {
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
coverageRunning = false
|
|
194
|
+
debug('--> stopping coverage <--')
|
|
195
|
+
await v8Helper.takeCoverage(helper.page, coverageReport)
|
|
196
|
+
},
|
|
197
|
+
true,
|
|
198
|
+
)
|
|
199
|
+
})
|
|
155
200
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const Locator = require('../locator')
|
|
2
|
+
const { xpathLocator } = require('../utils')
|
|
3
3
|
|
|
4
4
|
const defaultConfig = {
|
|
5
5
|
prefix: '$',
|
|
6
6
|
attribute: 'data-test-id',
|
|
7
7
|
strategy: 'xpath',
|
|
8
8
|
showActual: false,
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Creates a [custom locator](https://codecept.io/locators#custom-locators) by using special attributes in HTML.
|
|
@@ -111,34 +111,35 @@ const defaultConfig = {
|
|
|
111
111
|
* I.click('=sign-up'); // matches => [data-qa=sign-up],[data-test=sign-up]
|
|
112
112
|
* ```
|
|
113
113
|
*/
|
|
114
|
-
|
|
115
|
-
config = { ...defaultConfig, ...config }
|
|
114
|
+
module.exports = (config) => {
|
|
115
|
+
config = { ...defaultConfig, ...config }
|
|
116
116
|
|
|
117
117
|
Locator.addFilter((value, locatorObj) => {
|
|
118
|
-
if (typeof value !== 'string') return
|
|
119
|
-
if (!value.startsWith(config.prefix)) return
|
|
118
|
+
if (typeof value !== 'string') return
|
|
119
|
+
if (!value.startsWith(config.prefix)) return
|
|
120
120
|
|
|
121
|
-
if (!['String', 'Array'].includes(config.attribute.constructor.name)) return
|
|
121
|
+
if (!['String', 'Array'].includes(config.attribute.constructor.name)) return
|
|
122
122
|
|
|
123
|
-
const val = value.substr(config.prefix.length)
|
|
123
|
+
const val = value.substr(config.prefix.length)
|
|
124
124
|
|
|
125
125
|
if (config.strategy.toLowerCase() === 'xpath') {
|
|
126
|
-
locatorObj.value = `.//*[${
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
locatorObj.type = 'xpath'
|
|
126
|
+
locatorObj.value = `.//*[${[]
|
|
127
|
+
.concat(config.attribute)
|
|
128
|
+
.map((attr) => `@${attr}=${xpathLocator.literal(val)}`)
|
|
129
|
+
.join(' or ')}]`
|
|
130
|
+
locatorObj.type = 'xpath'
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
if (config.strategy.toLowerCase() === 'css') {
|
|
134
|
-
locatorObj.value = []
|
|
134
|
+
locatorObj.value = []
|
|
135
|
+
.concat(config.attribute)
|
|
135
136
|
.map((attr) => `[${attr}=${val}]`)
|
|
136
|
-
.join(',')
|
|
137
|
-
locatorObj.type = 'css'
|
|
137
|
+
.join(',')
|
|
138
|
+
locatorObj.type = 'css'
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
if (config.showActual) {
|
|
141
|
-
locatorObj.output = locatorObj.value
|
|
142
|
+
locatorObj.output = locatorObj.value
|
|
142
143
|
}
|
|
143
|
-
})
|
|
144
|
-
}
|
|
144
|
+
})
|
|
145
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
const Container = require('../container')
|
|
2
|
+
const recorder = require('../recorder')
|
|
3
|
+
const event = require('../event')
|
|
4
|
+
const supportedHelpers = require('./standardActingHelpers')
|
|
5
|
+
const { scanForErrorMessages } = require('../html')
|
|
6
|
+
const { output } = require('..')
|
|
7
7
|
|
|
8
8
|
const defaultConfig = {
|
|
9
9
|
errorClasses: ['error', 'warning', 'alert', 'danger'],
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Prints errors found in HTML code after each failed test.
|
|
@@ -29,39 +29,39 @@ const defaultConfig = {
|
|
|
29
29
|
* * `errorClasses` - list of classes to search for errors (default: `['error', 'warning', 'alert', 'danger']`)
|
|
30
30
|
*
|
|
31
31
|
*/
|
|
32
|
-
|
|
33
|
-
const helpers = Container.helpers()
|
|
34
|
-
let helper
|
|
32
|
+
module.exports = function (config = {}) {
|
|
33
|
+
const helpers = Container.helpers()
|
|
34
|
+
let helper
|
|
35
35
|
|
|
36
|
-
config = Object.assign(defaultConfig, config)
|
|
36
|
+
config = Object.assign(defaultConfig, config)
|
|
37
37
|
|
|
38
38
|
for (const helperName of supportedHelpers) {
|
|
39
39
|
if (Object.keys(helpers).indexOf(helperName) > -1) {
|
|
40
|
-
helper = helpers[helperName]
|
|
40
|
+
helper = helpers[helperName]
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
if (!helper) return
|
|
44
|
+
if (!helper) return // no helpers for screenshot
|
|
45
45
|
|
|
46
46
|
event.dispatcher.on(event.test.failed, (test) => {
|
|
47
47
|
recorder.add('HTML snapshot failed test', async () => {
|
|
48
48
|
try {
|
|
49
|
-
const currentOutputLevel = output.level()
|
|
50
|
-
output.level(0)
|
|
51
|
-
const html = await helper.grabHTMLFrom('body')
|
|
52
|
-
output.level(currentOutputLevel)
|
|
49
|
+
const currentOutputLevel = output.level()
|
|
50
|
+
output.level(0)
|
|
51
|
+
const html = await helper.grabHTMLFrom('body')
|
|
52
|
+
output.level(currentOutputLevel)
|
|
53
53
|
|
|
54
|
-
if (!html) return
|
|
54
|
+
if (!html) return
|
|
55
55
|
|
|
56
|
-
const errors = scanForErrorMessages(html, config.errorClasses)
|
|
56
|
+
const errors = scanForErrorMessages(html, config.errorClasses)
|
|
57
57
|
if (errors.length) {
|
|
58
|
-
output.debug('Detected errors in HTML code')
|
|
59
|
-
errors.forEach((error) => output.debug(error))
|
|
60
|
-
test.artifacts.errors = errors
|
|
58
|
+
output.debug('Detected errors in HTML code')
|
|
59
|
+
errors.forEach((error) => output.debug(error))
|
|
60
|
+
test.artifacts.errors = errors
|
|
61
61
|
}
|
|
62
62
|
} catch (err) {
|
|
63
63
|
// not really needed
|
|
64
64
|
}
|
|
65
|
-
})
|
|
66
|
-
})
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
67
|
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
const output = require('../output')
|
|
2
|
+
const store = require('../store')
|
|
3
|
+
const recorder = require('../recorder')
|
|
4
|
+
const container = require('../container')
|
|
5
|
+
const event = require('../event')
|
|
6
|
+
const Step = require('../step')
|
|
7
|
+
const { isAsyncFunction } = require('../utils')
|
|
8
8
|
|
|
9
9
|
const defaultConfig = {
|
|
10
10
|
registerGlobal: true,
|
|
11
|
-
}
|
|
11
|
+
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Provides `eachElement` global function to iterate over found elements to perform actions on them.
|
|
15
15
|
*
|
|
16
16
|
* `eachElement` takes following args:
|
|
17
|
-
* * `purpose` - the goal of an action. A comment text that will be displayed in output.
|
|
17
|
+
* * `purpose` - the goal of an action. A comment text that will be displayed in output.
|
|
18
18
|
* * `locator` - a CSS/XPath locator to match elements
|
|
19
19
|
* * `fn(element, index)` - **asynchronous** function which will be executed for each matched element.
|
|
20
20
|
*
|
|
@@ -69,59 +69,59 @@ const defaultConfig = {
|
|
|
69
69
|
* @return {Promise<*> | undefined}
|
|
70
70
|
*/
|
|
71
71
|
function eachElement(purpose, locator, fn) {
|
|
72
|
-
if (store.dryRun) return
|
|
73
|
-
const helpers = Object.values(container.helpers())
|
|
72
|
+
if (store.dryRun) return
|
|
73
|
+
const helpers = Object.values(container.helpers())
|
|
74
74
|
|
|
75
|
-
const helper = helpers.filter(h => !!h._locate)[0]
|
|
75
|
+
const helper = helpers.filter((h) => !!h._locate)[0]
|
|
76
76
|
|
|
77
77
|
if (!helper) {
|
|
78
|
-
throw new Error('No helper enabled with _locate method with returns a list of elements.')
|
|
78
|
+
throw new Error('No helper enabled with _locate method with returns a list of elements.')
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
if (!isAsyncFunction(fn)) {
|
|
82
|
-
throw new Error('Async function should be passed into each element')
|
|
82
|
+
throw new Error('Async function should be passed into each element')
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
const step = new Step(helper, `${purpose || 'each element'} within "${locator}"`)
|
|
86
|
-
step.helperMethod = '_locate'
|
|
85
|
+
const step = new Step(helper, `${purpose || 'each element'} within "${locator}"`)
|
|
86
|
+
step.helperMethod = '_locate'
|
|
87
87
|
// eachElement('select all users', 'locator', async (el) => {
|
|
88
|
-
event.dispatcher.emit(event.step.before, step)
|
|
88
|
+
event.dispatcher.emit(event.step.before, step)
|
|
89
89
|
|
|
90
90
|
return recorder.add('register each element wrapper', async () => {
|
|
91
|
-
event.emit(event.step.started, step)
|
|
92
|
-
const els = await helper._locate(locator)
|
|
93
|
-
output.
|
|
91
|
+
event.emit(event.step.started, step)
|
|
92
|
+
const els = await helper._locate(locator)
|
|
93
|
+
output.debug(`Found ${els.length} elements for each elements to iterate`)
|
|
94
94
|
|
|
95
|
-
const errs = []
|
|
96
|
-
let i = 0
|
|
95
|
+
const errs = []
|
|
96
|
+
let i = 0
|
|
97
97
|
for (const el of els) {
|
|
98
98
|
try {
|
|
99
|
-
await fn(el, i)
|
|
99
|
+
await fn(el, i)
|
|
100
100
|
} catch (err) {
|
|
101
|
-
output.
|
|
102
|
-
errs.push(err)
|
|
101
|
+
output.error(`eachElement: failed operation on element #${i} ${el}`)
|
|
102
|
+
errs.push(err)
|
|
103
103
|
}
|
|
104
|
-
i
|
|
104
|
+
i++
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
if (errs.length) {
|
|
108
|
-
event.dispatcher.emit(event.step.after, step)
|
|
109
|
-
event.emit(event.step.failed, step, errs[0])
|
|
110
|
-
event.emit(event.step.finished, step)
|
|
111
|
-
throw errs[0]
|
|
108
|
+
event.dispatcher.emit(event.step.after, step)
|
|
109
|
+
event.emit(event.step.failed, step, errs[0])
|
|
110
|
+
event.emit(event.step.finished, step)
|
|
111
|
+
throw errs[0]
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
event.dispatcher.emit(event.step.after, step)
|
|
115
|
-
event.emit(event.step.passed, step, null)
|
|
116
|
-
event.emit(event.step.finished, step)
|
|
117
|
-
})
|
|
114
|
+
event.dispatcher.emit(event.step.after, step)
|
|
115
|
+
event.emit(event.step.passed, step, null)
|
|
116
|
+
event.emit(event.step.finished, step)
|
|
117
|
+
})
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
config = Object.assign(defaultConfig, config)
|
|
120
|
+
module.exports = function (config) {
|
|
121
|
+
config = Object.assign(defaultConfig, config)
|
|
122
122
|
|
|
123
123
|
if (config.registerGlobal) {
|
|
124
|
-
global.eachElement = eachElement
|
|
124
|
+
global.eachElement = eachElement
|
|
125
125
|
}
|
|
126
|
-
return eachElement
|
|
126
|
+
return eachElement
|
|
127
127
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const { faker } = require('@faker-js/faker')
|
|
2
|
+
const transform = require('../transform')
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Use the `@faker-js/faker` package to generate fake data inside examples on your gherkin tests
|
|
@@ -39,11 +39,11 @@ import transform from '../transform';
|
|
|
39
39
|
* ```
|
|
40
40
|
*
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
module.exports = function (config) {
|
|
43
43
|
transform.addTransformerBeforeAll('gherkin.examples', (value) => {
|
|
44
44
|
if (typeof value === 'string' && value.length > 0) {
|
|
45
|
-
return faker.helpers.fake(value)
|
|
45
|
+
return faker.helpers.fake(value)
|
|
46
46
|
}
|
|
47
|
-
return value
|
|
48
|
-
})
|
|
47
|
+
return value
|
|
48
|
+
})
|
|
49
49
|
}
|