codeceptjs 3.6.10 → 3.7.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -110
- package/bin/codecept.js +2 -2
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +46 -36
- package/lib/assert/empty.js +3 -5
- package/lib/assert/equal.js +4 -7
- package/lib/assert/include.js +4 -6
- package/lib/assert/throws.js +2 -4
- package/lib/assert/truth.js +2 -2
- package/lib/codecept.js +87 -83
- package/lib/command/configMigrate.js +2 -4
- package/lib/command/definitions.js +5 -25
- package/lib/command/generate.js +10 -14
- package/lib/command/gherkin/snippets.js +10 -8
- package/lib/command/gherkin/steps.js +1 -1
- package/lib/command/info.js +1 -3
- package/lib/command/init.js +8 -12
- package/lib/command/interactive.js +1 -1
- package/lib/command/list.js +1 -1
- package/lib/command/run-multiple.js +12 -35
- package/lib/command/run-workers.js +10 -10
- package/lib/command/utils.js +5 -6
- package/lib/command/workers/runTests.js +14 -17
- package/lib/container.js +327 -237
- package/lib/data/context.js +10 -13
- package/lib/data/dataScenarioConfig.js +8 -8
- package/lib/data/dataTableArgument.js +6 -6
- package/lib/data/table.js +5 -11
- package/lib/els.js +177 -0
- package/lib/event.js +1 -0
- package/lib/heal.js +78 -80
- package/lib/helper/ApiDataFactory.js +3 -6
- package/lib/helper/Appium.js +15 -30
- package/lib/helper/FileSystem.js +3 -3
- package/lib/helper/GraphQLDataFactory.js +3 -3
- package/lib/helper/JSONResponse.js +57 -37
- package/lib/helper/Nightmare.js +35 -53
- package/lib/helper/Playwright.js +189 -251
- package/lib/helper/Protractor.js +54 -77
- package/lib/helper/Puppeteer.js +134 -232
- package/lib/helper/REST.js +5 -17
- package/lib/helper/TestCafe.js +21 -44
- package/lib/helper/WebDriver.js +103 -162
- package/lib/helper/testcafe/testcafe-utils.js +26 -27
- package/lib/listener/artifacts.js +2 -2
- package/lib/listener/emptyRun.js +58 -0
- package/lib/listener/exit.js +4 -4
- package/lib/listener/{retry.js → globalRetry.js} +5 -5
- package/lib/listener/{timeout.js → globalTimeout.js} +9 -8
- package/lib/listener/helpers.js +15 -15
- package/lib/listener/mocha.js +1 -1
- package/lib/listener/steps.js +17 -12
- package/lib/listener/store.js +12 -0
- package/lib/mocha/asyncWrapper.js +204 -0
- package/lib/{interfaces → mocha}/bdd.js +3 -3
- package/lib/mocha/cli.js +257 -0
- package/lib/mocha/factory.js +104 -0
- package/lib/{interfaces → mocha}/featureConfig.js +11 -12
- package/lib/{interfaces → mocha}/gherkin.js +26 -28
- package/lib/mocha/hooks.js +83 -0
- package/lib/mocha/index.js +12 -0
- package/lib/mocha/inject.js +24 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +10 -6
- package/lib/mocha/suite.js +55 -0
- package/lib/mocha/test.js +60 -0
- package/lib/mocha/types.d.ts +31 -0
- package/lib/mocha/ui.js +219 -0
- package/lib/output.js +28 -10
- package/lib/pause.js +159 -135
- package/lib/plugin/autoDelay.js +4 -4
- package/lib/plugin/autoLogin.js +6 -7
- package/lib/plugin/commentStep.js +1 -1
- package/lib/plugin/coverage.js +10 -19
- package/lib/plugin/customLocator.js +3 -3
- package/lib/plugin/debugErrors.js +2 -2
- package/lib/plugin/eachElement.js +1 -1
- package/lib/plugin/fakerTransform.js +1 -1
- package/lib/plugin/heal.js +6 -9
- package/lib/plugin/retryFailedStep.js +4 -4
- package/lib/plugin/retryTo.js +2 -2
- package/lib/plugin/screenshotOnFail.js +9 -36
- package/lib/plugin/selenoid.js +15 -35
- package/lib/plugin/stepByStepReport.js +51 -13
- package/lib/plugin/stepTimeout.js +4 -11
- package/lib/plugin/subtitles.js +4 -4
- package/lib/plugin/tryTo.js +1 -1
- package/lib/plugin/wdio.js +8 -10
- package/lib/recorder.js +142 -121
- package/lib/secret.js +1 -1
- package/lib/step.js +160 -144
- package/lib/store.js +6 -2
- package/lib/template/heal.js +2 -11
- package/lib/utils.js +224 -216
- package/lib/within.js +73 -55
- package/lib/workers.js +265 -261
- package/package.json +46 -47
- package/typings/index.d.ts +172 -184
- package/typings/promiseBasedTypes.d.ts +95 -516
- package/typings/types.d.ts +169 -587
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/mochaFactory.js +0 -113
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
package/lib/codecept.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
const { existsSync, readFileSync } = require('fs')
|
|
2
|
-
const glob = require('glob')
|
|
3
|
-
const fsPath = require('path')
|
|
4
|
-
const { resolve } = require('path')
|
|
5
|
-
|
|
6
|
-
const container = require('./container')
|
|
7
|
-
const Config = require('./config')
|
|
8
|
-
const event = require('./event')
|
|
9
|
-
const runHook = require('./hooks')
|
|
10
|
-
const output = require('./output')
|
|
11
|
-
const { emptyFolder } = require('./utils')
|
|
1
|
+
const { existsSync, readFileSync } = require('fs')
|
|
2
|
+
const glob = require('glob')
|
|
3
|
+
const fsPath = require('path')
|
|
4
|
+
const { resolve } = require('path')
|
|
5
|
+
|
|
6
|
+
const container = require('./container')
|
|
7
|
+
const Config = require('./config')
|
|
8
|
+
const event = require('./event')
|
|
9
|
+
const runHook = require('./hooks')
|
|
10
|
+
const output = require('./output')
|
|
11
|
+
const { emptyFolder } = require('./utils')
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* CodeceptJS runner
|
|
@@ -22,10 +22,10 @@ class Codecept {
|
|
|
22
22
|
* @param {*} opts
|
|
23
23
|
*/
|
|
24
24
|
constructor(config, opts) {
|
|
25
|
-
this.config = Config.create(config)
|
|
26
|
-
this.opts = opts
|
|
27
|
-
this.testFiles = new Array(0)
|
|
28
|
-
this.requireModules(config.require)
|
|
25
|
+
this.config = Config.create(config)
|
|
26
|
+
this.opts = opts
|
|
27
|
+
this.testFiles = new Array(0)
|
|
28
|
+
this.requireModules(config.require)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -35,13 +35,13 @@ class Codecept {
|
|
|
35
35
|
*/
|
|
36
36
|
requireModules(requiringModules) {
|
|
37
37
|
if (requiringModules) {
|
|
38
|
-
requiringModules.forEach(
|
|
39
|
-
const isLocalFile = existsSync(requiredModule) || existsSync(`${requiredModule}.js`)
|
|
38
|
+
requiringModules.forEach(requiredModule => {
|
|
39
|
+
const isLocalFile = existsSync(requiredModule) || existsSync(`${requiredModule}.js`)
|
|
40
40
|
if (isLocalFile) {
|
|
41
|
-
requiredModule = resolve(requiredModule)
|
|
41
|
+
requiredModule = resolve(requiredModule)
|
|
42
42
|
}
|
|
43
|
-
require(requiredModule)
|
|
44
|
-
})
|
|
43
|
+
require(requiredModule)
|
|
44
|
+
})
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -52,10 +52,10 @@ class Codecept {
|
|
|
52
52
|
* @param {string} dir
|
|
53
53
|
*/
|
|
54
54
|
init(dir) {
|
|
55
|
-
this.initGlobals(dir)
|
|
55
|
+
this.initGlobals(dir)
|
|
56
56
|
// initializing listeners
|
|
57
|
-
container.create(this.config, this.opts)
|
|
58
|
-
this.runHooks()
|
|
57
|
+
container.create(this.config, this.opts)
|
|
58
|
+
this.runHooks()
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -64,37 +64,37 @@ class Codecept {
|
|
|
64
64
|
* @param {string} dir
|
|
65
65
|
*/
|
|
66
66
|
initGlobals(dir) {
|
|
67
|
-
global.codecept_dir = dir
|
|
68
|
-
global.output_dir = fsPath.resolve(dir, this.config.output)
|
|
67
|
+
global.codecept_dir = dir
|
|
68
|
+
global.output_dir = fsPath.resolve(dir, this.config.output)
|
|
69
69
|
|
|
70
|
-
if (this.config.emptyOutputFolder) emptyFolder(global.output_dir)
|
|
70
|
+
if (this.config.emptyOutputFolder) emptyFolder(global.output_dir)
|
|
71
71
|
|
|
72
72
|
if (!this.config.noGlobals) {
|
|
73
|
-
global.Helper = global.codecept_helper = require('@codeceptjs/helper')
|
|
74
|
-
global.actor = global.codecept_actor = require('./actor')
|
|
75
|
-
global.pause = require('./pause')
|
|
76
|
-
global.within = require('./within')
|
|
77
|
-
global.session = require('./session')
|
|
78
|
-
global.DataTable = require('./data/table')
|
|
79
|
-
global.locate = locator => require('./locator').build(locator)
|
|
80
|
-
global.inject = container.support
|
|
81
|
-
global.share = container.share
|
|
82
|
-
global.secret = require('./secret').secret
|
|
83
|
-
global.codecept_debug = output.debug
|
|
84
|
-
global.codeceptjs = require('./index')
|
|
73
|
+
global.Helper = global.codecept_helper = require('@codeceptjs/helper')
|
|
74
|
+
global.actor = global.codecept_actor = require('./actor')
|
|
75
|
+
global.pause = require('./pause')
|
|
76
|
+
global.within = require('./within')
|
|
77
|
+
global.session = require('./session')
|
|
78
|
+
global.DataTable = require('./data/table')
|
|
79
|
+
global.locate = locator => require('./locator').build(locator)
|
|
80
|
+
global.inject = container.support
|
|
81
|
+
global.share = container.share
|
|
82
|
+
global.secret = require('./secret').secret
|
|
83
|
+
global.codecept_debug = output.debug
|
|
84
|
+
global.codeceptjs = require('./index') // load all objects
|
|
85
85
|
|
|
86
86
|
// BDD
|
|
87
|
-
const stepDefinitions = require('./
|
|
88
|
-
global.Given = stepDefinitions.Given
|
|
89
|
-
global.When = stepDefinitions.When
|
|
90
|
-
global.Then = stepDefinitions.Then
|
|
91
|
-
global.DefineParameterType = stepDefinitions.defineParameterType
|
|
87
|
+
const stepDefinitions = require('./mocha/bdd')
|
|
88
|
+
global.Given = stepDefinitions.Given
|
|
89
|
+
global.When = stepDefinitions.When
|
|
90
|
+
global.Then = stepDefinitions.Then
|
|
91
|
+
global.DefineParameterType = stepDefinitions.defineParameterType
|
|
92
92
|
|
|
93
93
|
// debug mode
|
|
94
|
-
global.debugMode = false
|
|
94
|
+
global.debugMode = false
|
|
95
95
|
|
|
96
96
|
// mask sensitive data
|
|
97
|
-
global.maskSensitiveData = this.config.maskSensitiveData || false
|
|
97
|
+
global.maskSensitiveData = this.config.maskSensitiveData || false
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -103,16 +103,18 @@ class Codecept {
|
|
|
103
103
|
*/
|
|
104
104
|
runHooks() {
|
|
105
105
|
// default hooks
|
|
106
|
-
runHook(require('./listener/
|
|
107
|
-
runHook(require('./listener/
|
|
108
|
-
runHook(require('./listener/
|
|
109
|
-
runHook(require('./listener/
|
|
110
|
-
runHook(require('./listener/
|
|
111
|
-
runHook(require('./listener/
|
|
112
|
-
runHook(require('./listener/
|
|
106
|
+
runHook(require('./listener/store'))
|
|
107
|
+
runHook(require('./listener/steps'))
|
|
108
|
+
runHook(require('./listener/artifacts'))
|
|
109
|
+
runHook(require('./listener/config'))
|
|
110
|
+
runHook(require('./listener/helpers'))
|
|
111
|
+
runHook(require('./listener/globalTimeout'))
|
|
112
|
+
runHook(require('./listener/globalRetry'))
|
|
113
|
+
runHook(require('./listener/exit'))
|
|
114
|
+
runHook(require('./listener/emptyRun'))
|
|
113
115
|
|
|
114
116
|
// custom hooks (previous iteration of plugins)
|
|
115
|
-
this.config.hooks.forEach(hook => runHook(hook))
|
|
117
|
+
this.config.hooks.forEach(hook => runHook(hook))
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
/**
|
|
@@ -120,7 +122,7 @@ class Codecept {
|
|
|
120
122
|
*
|
|
121
123
|
*/
|
|
122
124
|
async bootstrap() {
|
|
123
|
-
return runHook(this.config.bootstrap, 'bootstrap')
|
|
125
|
+
return runHook(this.config.bootstrap, 'bootstrap')
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
/**
|
|
@@ -128,7 +130,7 @@ class Codecept {
|
|
|
128
130
|
|
|
129
131
|
*/
|
|
130
132
|
async teardown() {
|
|
131
|
-
return runHook(this.config.teardown, 'teardown')
|
|
133
|
+
return runHook(this.config.teardown, 'teardown')
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
/**
|
|
@@ -139,42 +141,42 @@ class Codecept {
|
|
|
139
141
|
loadTests(pattern) {
|
|
140
142
|
const options = {
|
|
141
143
|
cwd: global.codecept_dir,
|
|
142
|
-
}
|
|
144
|
+
}
|
|
143
145
|
|
|
144
|
-
let patterns = [pattern]
|
|
146
|
+
let patterns = [pattern]
|
|
145
147
|
if (!pattern) {
|
|
146
|
-
patterns = []
|
|
148
|
+
patterns = []
|
|
147
149
|
|
|
148
150
|
// If the user wants to test a specific set of test files as an array or string.
|
|
149
151
|
if (this.config.tests && !this.opts.features) {
|
|
150
152
|
if (Array.isArray(this.config.tests)) {
|
|
151
|
-
patterns.push(...this.config.tests)
|
|
153
|
+
patterns.push(...this.config.tests)
|
|
152
154
|
} else {
|
|
153
|
-
patterns.push(this.config.tests)
|
|
155
|
+
patterns.push(this.config.tests)
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
if (this.config.gherkin.features && !this.opts.tests) {
|
|
158
160
|
if (Array.isArray(this.config.gherkin.features)) {
|
|
159
161
|
this.config.gherkin.features.forEach(feature => {
|
|
160
|
-
patterns.push(feature)
|
|
161
|
-
})
|
|
162
|
+
patterns.push(feature)
|
|
163
|
+
})
|
|
162
164
|
} else {
|
|
163
|
-
patterns.push(this.config.gherkin.features)
|
|
165
|
+
patterns.push(this.config.gherkin.features)
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
for (pattern of patterns) {
|
|
169
|
-
glob.sync(pattern, options).forEach(
|
|
170
|
-
if (file.includes('node_modules')) return
|
|
171
|
+
glob.sync(pattern, options).forEach(file => {
|
|
172
|
+
if (file.includes('node_modules')) return
|
|
171
173
|
if (!fsPath.isAbsolute(file)) {
|
|
172
|
-
file = fsPath.join(global.codecept_dir, file)
|
|
174
|
+
file = fsPath.join(global.codecept_dir, file)
|
|
173
175
|
}
|
|
174
176
|
if (!this.testFiles.includes(fsPath.resolve(file))) {
|
|
175
|
-
this.testFiles.push(fsPath.resolve(file))
|
|
177
|
+
this.testFiles.push(fsPath.resolve(file))
|
|
176
178
|
}
|
|
177
|
-
})
|
|
179
|
+
})
|
|
178
180
|
}
|
|
179
181
|
}
|
|
180
182
|
|
|
@@ -185,34 +187,36 @@ class Codecept {
|
|
|
185
187
|
* @returns {Promise<void>}
|
|
186
188
|
*/
|
|
187
189
|
async run(test) {
|
|
190
|
+
await container.started()
|
|
191
|
+
|
|
188
192
|
return new Promise((resolve, reject) => {
|
|
189
|
-
const mocha = container.mocha()
|
|
190
|
-
mocha.files = this.testFiles
|
|
193
|
+
const mocha = container.mocha()
|
|
194
|
+
mocha.files = this.testFiles
|
|
191
195
|
if (test) {
|
|
192
196
|
if (!fsPath.isAbsolute(test)) {
|
|
193
|
-
test = fsPath.join(global.codecept_dir, test)
|
|
197
|
+
test = fsPath.join(global.codecept_dir, test)
|
|
194
198
|
}
|
|
195
|
-
mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test)
|
|
199
|
+
mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test)
|
|
196
200
|
}
|
|
197
201
|
const done = () => {
|
|
198
|
-
event.emit(event.all.result, this)
|
|
199
|
-
event.emit(event.all.after, this)
|
|
200
|
-
resolve()
|
|
201
|
-
}
|
|
202
|
+
event.emit(event.all.result, this)
|
|
203
|
+
event.emit(event.all.after, this)
|
|
204
|
+
resolve()
|
|
205
|
+
}
|
|
202
206
|
|
|
203
207
|
try {
|
|
204
|
-
event.emit(event.all.before, this)
|
|
205
|
-
mocha.run(() => done())
|
|
208
|
+
event.emit(event.all.before, this)
|
|
209
|
+
mocha.run(() => done())
|
|
206
210
|
} catch (e) {
|
|
207
|
-
output.error(e.stack)
|
|
208
|
-
reject(e)
|
|
211
|
+
output.error(e.stack)
|
|
212
|
+
reject(e)
|
|
209
213
|
}
|
|
210
|
-
})
|
|
214
|
+
})
|
|
211
215
|
}
|
|
212
216
|
|
|
213
217
|
static version() {
|
|
214
|
-
return JSON.parse(readFileSync(`${__dirname}/../package.json`, 'utf8')).version
|
|
218
|
+
return JSON.parse(readFileSync(`${__dirname}/../package.json`, 'utf8')).version
|
|
215
219
|
}
|
|
216
220
|
}
|
|
217
221
|
|
|
218
|
-
module.exports = Codecept
|
|
222
|
+
module.exports = Codecept
|
|
@@ -14,9 +14,7 @@ module.exports = function (initPath) {
|
|
|
14
14
|
|
|
15
15
|
print()
|
|
16
16
|
print(` Welcome to ${colors.magenta.bold('CodeceptJS')} configuration migration tool`)
|
|
17
|
-
print(
|
|
18
|
-
` It will help you switch from ${colors.cyan.bold('.json')} to ${colors.magenta.bold('.js')} config format at ease`,
|
|
19
|
-
)
|
|
17
|
+
print(` It will help you switch from ${colors.cyan.bold('.json')} to ${colors.magenta.bold('.js')} config format at ease`)
|
|
20
18
|
print()
|
|
21
19
|
|
|
22
20
|
if (!path) {
|
|
@@ -53,7 +51,7 @@ module.exports = function (initPath) {
|
|
|
53
51
|
default: true,
|
|
54
52
|
},
|
|
55
53
|
])
|
|
56
|
-
.then(
|
|
54
|
+
.then(result => {
|
|
57
55
|
if (result.configFile) {
|
|
58
56
|
const jsonConfigFile = path.join(testsPath, 'codecept.js')
|
|
59
57
|
const config = JSON.parse(fs.readFileSync(jsonConfigFile, 'utf8'))
|
|
@@ -21,14 +21,7 @@ const actingHelpers = [...require('../plugin/standardActingHelpers'), 'REST']
|
|
|
21
21
|
*
|
|
22
22
|
* @returns {string}
|
|
23
23
|
*/
|
|
24
|
-
const getDefinitionsFileContent = ({
|
|
25
|
-
hasCustomHelper,
|
|
26
|
-
hasCustomStepsFile,
|
|
27
|
-
helperNames,
|
|
28
|
-
supportObject,
|
|
29
|
-
importPaths,
|
|
30
|
-
translations,
|
|
31
|
-
}) => {
|
|
24
|
+
const getDefinitionsFileContent = ({ hasCustomHelper, hasCustomStepsFile, helperNames, supportObject, importPaths, translations }) => {
|
|
32
25
|
const getHelperListFragment = ({ hasCustomHelper, hasCustomStepsFile }) => {
|
|
33
26
|
if (hasCustomHelper && hasCustomStepsFile) {
|
|
34
27
|
return `${['ReturnType<steps_file>', 'WithTranslation<Methods>'].join(', ')}`
|
|
@@ -73,13 +66,7 @@ const getDefinitionsFileContent = ({
|
|
|
73
66
|
*
|
|
74
67
|
* @returns {string}
|
|
75
68
|
*/
|
|
76
|
-
const generateDefinitionsContent = ({
|
|
77
|
-
importPathsFragment,
|
|
78
|
-
supportObjectsTypeFragment,
|
|
79
|
-
methodsTypeFragment,
|
|
80
|
-
helpersListFragment,
|
|
81
|
-
translatedActionsFragment,
|
|
82
|
-
}) => {
|
|
69
|
+
const generateDefinitionsContent = ({ importPathsFragment, supportObjectsTypeFragment, methodsTypeFragment, helpersListFragment, translatedActionsFragment }) => {
|
|
83
70
|
return `/// <reference types='codeceptjs' />
|
|
84
71
|
${importPathsFragment}
|
|
85
72
|
|
|
@@ -185,15 +172,12 @@ module.exports = function (genPath, options) {
|
|
|
185
172
|
namespaceTranslationAliases.push(`interface ${translations.vocabulary.I} extends WithTranslation<Methods> {}`)
|
|
186
173
|
|
|
187
174
|
namespaceTranslationAliases.push(' namespace Translation {')
|
|
188
|
-
definitionsFileContent = definitionsFileContent.replace(
|
|
189
|
-
'namespace Translation {',
|
|
190
|
-
namespaceTranslationAliases.join('\n'),
|
|
191
|
-
)
|
|
175
|
+
definitionsFileContent = definitionsFileContent.replace('namespace Translation {', namespaceTranslationAliases.join('\n'))
|
|
192
176
|
|
|
193
177
|
const translationAliases = []
|
|
194
178
|
|
|
195
179
|
if (translations.vocabulary.contexts) {
|
|
196
|
-
Object.keys(translations.vocabulary.contexts).forEach(
|
|
180
|
+
Object.keys(translations.vocabulary.contexts).forEach(k => {
|
|
197
181
|
translationAliases.push(`declare const ${translations.vocabulary.contexts[k]}: typeof ${k};`)
|
|
198
182
|
})
|
|
199
183
|
}
|
|
@@ -222,11 +206,7 @@ function getPath(originalPath, targetFolderPath, testsPath) {
|
|
|
222
206
|
if (!parsedPath.dir.startsWith('.')) return path.posix.join(parsedPath.dir, parsedPath.base)
|
|
223
207
|
const relativePath = path.posix.relative(
|
|
224
208
|
targetFolderPath.split(path.sep).join(path.posix.sep),
|
|
225
|
-
path.posix.join(
|
|
226
|
-
testsPath.split(path.sep).join(path.posix.sep),
|
|
227
|
-
parsedPath.dir.split(path.sep).join(path.posix.sep),
|
|
228
|
-
parsedPath.base.split(path.sep).join(path.posix.sep),
|
|
229
|
-
),
|
|
209
|
+
path.posix.join(testsPath.split(path.sep).join(path.posix.sep), parsedPath.dir.split(path.sep).join(path.posix.sep), parsedPath.base.split(path.sep).join(path.posix.sep)),
|
|
230
210
|
)
|
|
231
211
|
|
|
232
212
|
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`
|
package/lib/command/generate.js
CHANGED
|
@@ -35,7 +35,7 @@ module.exports.test = function (genPath) {
|
|
|
35
35
|
type: 'input',
|
|
36
36
|
name: 'feature',
|
|
37
37
|
message: 'Feature which is being tested (ex: account, login, etc)',
|
|
38
|
-
validate:
|
|
38
|
+
validate: val => !!val,
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
type: 'input',
|
|
@@ -46,7 +46,7 @@ module.exports.test = function (genPath) {
|
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
])
|
|
49
|
-
.then(
|
|
49
|
+
.then(result => {
|
|
50
50
|
const testFilePath = path.dirname(path.join(testsPath, config.tests)).replace(/\*\*$/, '')
|
|
51
51
|
let testFile = path.join(testFilePath, result.filename)
|
|
52
52
|
const ext = path.extname(testFile)
|
|
@@ -63,9 +63,7 @@ module.exports.test = function (genPath) {
|
|
|
63
63
|
testContent = testContent.replace('{{actor}}', container.translation().I)
|
|
64
64
|
if (vocabulary.contexts.Feature) testContent = testContent.replace('Feature', vocabulary.contexts.Feature)
|
|
65
65
|
if (vocabulary.contexts.Scenario) testContent = testContent.replace('Scenario', vocabulary.contexts.Scenario)
|
|
66
|
-
output.print(
|
|
67
|
-
`Test was created in ${colors.bold(config.translation)} localization. See: https://codecept.io/translation/`,
|
|
68
|
-
)
|
|
66
|
+
output.print(`Test was created in ${colors.bold(config.translation)} localization. See: https://codecept.io/translation/`)
|
|
69
67
|
} else {
|
|
70
68
|
testContent = testContent.replace('{{actor}}', 'I')
|
|
71
69
|
}
|
|
@@ -128,13 +126,13 @@ module.exports.pageObject = function (genPath, opts) {
|
|
|
128
126
|
type: 'input',
|
|
129
127
|
name: 'name',
|
|
130
128
|
message: `Name of a ${kind} object`,
|
|
131
|
-
validate:
|
|
129
|
+
validate: val => !!val,
|
|
132
130
|
},
|
|
133
131
|
{
|
|
134
132
|
type: 'input',
|
|
135
133
|
name: 'filename',
|
|
136
134
|
message: 'Where should it be stored',
|
|
137
|
-
default:
|
|
135
|
+
default: answers => `./${kind}s/${answers.name}.${extension}`,
|
|
138
136
|
},
|
|
139
137
|
{
|
|
140
138
|
type: 'list',
|
|
@@ -144,7 +142,7 @@ module.exports.pageObject = function (genPath, opts) {
|
|
|
144
142
|
default: 'module',
|
|
145
143
|
},
|
|
146
144
|
])
|
|
147
|
-
.then(
|
|
145
|
+
.then(result => {
|
|
148
146
|
const pageObjectFile = path.join(testsPath, result.filename)
|
|
149
147
|
const dir = path.dirname(pageObjectFile)
|
|
150
148
|
if (!fileExists(dir)) fs.mkdirSync(dir)
|
|
@@ -194,9 +192,7 @@ module.exports.pageObject = function (genPath, opts) {
|
|
|
194
192
|
try {
|
|
195
193
|
generateDefinitions(testsPath, {})
|
|
196
194
|
} catch (_err) {
|
|
197
|
-
output.print(
|
|
198
|
-
`Run ${colors.green('npx codeceptjs def')} to update your types to get auto-completion for object.`,
|
|
199
|
-
)
|
|
195
|
+
output.print(`Run ${colors.green('npx codeceptjs def')} to update your types to get auto-completion for object.`)
|
|
200
196
|
}
|
|
201
197
|
})
|
|
202
198
|
}
|
|
@@ -241,16 +237,16 @@ module.exports.helper = function (genPath) {
|
|
|
241
237
|
type: 'input',
|
|
242
238
|
name: 'name',
|
|
243
239
|
message: 'Name of a Helper',
|
|
244
|
-
validate:
|
|
240
|
+
validate: val => !!val,
|
|
245
241
|
},
|
|
246
242
|
{
|
|
247
243
|
type: 'input',
|
|
248
244
|
name: 'filename',
|
|
249
245
|
message: 'Where should it be stored',
|
|
250
|
-
default:
|
|
246
|
+
default: answers => `./${answers.name.toLowerCase()}_helper.${extension}`,
|
|
251
247
|
},
|
|
252
248
|
])
|
|
253
|
-
.then(
|
|
249
|
+
.then(result => {
|
|
254
250
|
const name = ucfirst(result.name)
|
|
255
251
|
const helperFile = path.join(testsPath, result.filename)
|
|
256
252
|
const dir = path.dirname(helperFile)
|
|
@@ -8,7 +8,7 @@ const fsPath = require('path');
|
|
|
8
8
|
const { getConfig, getTestRoot } = require('../utils');
|
|
9
9
|
const Codecept = require('../../codecept');
|
|
10
10
|
const output = require('../../output');
|
|
11
|
-
const { matchStep } = require('../../
|
|
11
|
+
const { matchStep } = require('../../mocha/bdd');
|
|
12
12
|
|
|
13
13
|
const uuidFn = Messages.IdGenerator.uuid();
|
|
14
14
|
const builder = new Gherkin.AstBuilder(uuidFn);
|
|
@@ -43,7 +43,7 @@ module.exports = function (genPath, options) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const files = [];
|
|
46
|
-
glob.sync(options.feature || config.gherkin.features, { cwd: options.feature ? '.' : global.codecept_dir }).forEach(
|
|
46
|
+
glob.sync(options.feature || config.gherkin.features, { cwd: options.feature ? '.' : global.codecept_dir }).forEach(file => {
|
|
47
47
|
if (!fsPath.isAbsolute(file)) {
|
|
48
48
|
file = fsPath.join(global.codecept_dir, file);
|
|
49
49
|
}
|
|
@@ -53,7 +53,7 @@ module.exports = function (genPath, options) {
|
|
|
53
53
|
|
|
54
54
|
const newSteps = new Map();
|
|
55
55
|
|
|
56
|
-
const parseSteps =
|
|
56
|
+
const parseSteps = steps => {
|
|
57
57
|
const newSteps = [];
|
|
58
58
|
let currentKeyword = '';
|
|
59
59
|
for (const step of steps) {
|
|
@@ -86,13 +86,15 @@ module.exports = function (genPath, options) {
|
|
|
86
86
|
return newSteps;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
-
const parseFile =
|
|
89
|
+
const parseFile = file => {
|
|
90
90
|
const ast = parser.parse(fs.readFileSync(file).toString());
|
|
91
91
|
for (const child of ast.feature.children) {
|
|
92
92
|
if (child.scenario.keyword === 'Scenario Outline') continue; // skip scenario outline
|
|
93
|
-
parseSteps(child.scenario.steps)
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
parseSteps(child.scenario.steps)
|
|
94
|
+
.map(step => {
|
|
95
|
+
return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) });
|
|
96
|
+
})
|
|
97
|
+
.map(step => newSteps.set(`${step.type}(${step})`, step));
|
|
96
98
|
}
|
|
97
99
|
};
|
|
98
100
|
|
|
@@ -110,7 +112,7 @@ module.exports = function (genPath, options) {
|
|
|
110
112
|
|
|
111
113
|
const snippets = [...newSteps.values()]
|
|
112
114
|
.filter((value, index, self) => self.indexOf(value) === index)
|
|
113
|
-
.map(
|
|
115
|
+
.map(step => {
|
|
114
116
|
return `
|
|
115
117
|
${step.type}(${step.regexp ? '/^' : "'"}${step}${step.regexp ? '$/' : "'"}, () => {
|
|
116
118
|
// From "${step.file}" ${JSON.stringify(step.location)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { getConfig, getTestRoot } = require('../utils');
|
|
2
2
|
const Codecept = require('../../codecept');
|
|
3
3
|
const output = require('../../output');
|
|
4
|
-
const { getSteps } = require('../../
|
|
4
|
+
const { getSteps } = require('../../mocha/bdd');
|
|
5
5
|
|
|
6
6
|
module.exports = function (genPath, options) {
|
|
7
7
|
const configFile = options.config || genPath;
|
package/lib/command/info.js
CHANGED
|
@@ -34,9 +34,7 @@ module.exports = async function (path) {
|
|
|
34
34
|
output.print('***************************************')
|
|
35
35
|
output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs')
|
|
36
36
|
output.print('Or ask them on our discussion board: https://codecept.discourse.group/')
|
|
37
|
-
output.print(
|
|
38
|
-
'Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues',
|
|
39
|
-
)
|
|
37
|
+
output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues')
|
|
40
38
|
output.print('***************************************')
|
|
41
39
|
}
|
|
42
40
|
|
package/lib/command/init.js
CHANGED
|
@@ -117,7 +117,7 @@ module.exports = function (initPath) {
|
|
|
117
117
|
{
|
|
118
118
|
name: 'tests',
|
|
119
119
|
type: 'input',
|
|
120
|
-
default:
|
|
120
|
+
default: answers => `./*_test.${answers.typescript ? 'ts' : 'js'}`,
|
|
121
121
|
message: 'Where are your tests located?',
|
|
122
122
|
},
|
|
123
123
|
{
|
|
@@ -132,7 +132,7 @@ module.exports = function (initPath) {
|
|
|
132
132
|
type: 'confirm',
|
|
133
133
|
default: true,
|
|
134
134
|
message: 'Do you want to use JSONResponse helper for assertions on JSON responses? http://bit.ly/3ASVPy9',
|
|
135
|
-
when:
|
|
135
|
+
when: answers => ['GraphQL', 'REST'].includes(answers.helper) === true,
|
|
136
136
|
},
|
|
137
137
|
{
|
|
138
138
|
name: 'output',
|
|
@@ -146,7 +146,7 @@ module.exports = function (initPath) {
|
|
|
146
146
|
choices: translations,
|
|
147
147
|
},
|
|
148
148
|
])
|
|
149
|
-
.then(
|
|
149
|
+
.then(result => {
|
|
150
150
|
if (result.typescript === true) {
|
|
151
151
|
isTypeScript = true
|
|
152
152
|
extension = isTypeScript === true ? 'ts' : 'js'
|
|
@@ -189,7 +189,7 @@ module.exports = function (initPath) {
|
|
|
189
189
|
|
|
190
190
|
if (!Helper._config()) return
|
|
191
191
|
helperConfigs = helperConfigs.concat(
|
|
192
|
-
Helper._config().map(
|
|
192
|
+
Helper._config().map(config => {
|
|
193
193
|
config.message = `[${helperName}] ${config.message}`
|
|
194
194
|
config.name = `${helperName}_${config.name}`
|
|
195
195
|
config.type = config.type || 'input'
|
|
@@ -225,9 +225,7 @@ module.exports = function (initPath) {
|
|
|
225
225
|
fs.writeFileSync(typeScriptconfigFile, configSource, 'utf-8')
|
|
226
226
|
print(`Config created at ${typeScriptconfigFile}`)
|
|
227
227
|
} else {
|
|
228
|
-
configSource = beautify(
|
|
229
|
-
`/** @type {CodeceptJS.MainConfig} */\nexports.config = ${inspect(config, false, 4, false)}`,
|
|
230
|
-
)
|
|
228
|
+
configSource = beautify(`/** @type {CodeceptJS.MainConfig} */\nexports.config = ${inspect(config, false, 4, false)}`)
|
|
231
229
|
|
|
232
230
|
if (hasConfigure) configSource = requireCodeceptConfigure + configHeader + configSource
|
|
233
231
|
|
|
@@ -286,9 +284,7 @@ module.exports = function (initPath) {
|
|
|
286
284
|
}
|
|
287
285
|
}
|
|
288
286
|
|
|
289
|
-
const generateDefinitionsManually = colors.bold(
|
|
290
|
-
`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`,
|
|
291
|
-
)
|
|
287
|
+
const generateDefinitionsManually = colors.bold(`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`)
|
|
292
288
|
|
|
293
289
|
if (packages) {
|
|
294
290
|
try {
|
|
@@ -330,7 +326,7 @@ module.exports = function (initPath) {
|
|
|
330
326
|
}
|
|
331
327
|
|
|
332
328
|
print('Configure helpers...')
|
|
333
|
-
inquirer.prompt(helperConfigs).then(async
|
|
329
|
+
inquirer.prompt(helperConfigs).then(async helperResult => {
|
|
334
330
|
if (helperResult.Playwright_browser === 'electron') {
|
|
335
331
|
delete helperResult.Playwright_url
|
|
336
332
|
delete helperResult.Playwright_show
|
|
@@ -341,7 +337,7 @@ module.exports = function (initPath) {
|
|
|
341
337
|
}
|
|
342
338
|
}
|
|
343
339
|
|
|
344
|
-
Object.keys(helperResult).forEach(
|
|
340
|
+
Object.keys(helperResult).forEach(key => {
|
|
345
341
|
const parts = key.split('_')
|
|
346
342
|
const helperName = parts[0]
|
|
347
343
|
const configName = parts[1]
|
|
@@ -39,7 +39,7 @@ module.exports = async function (path, options) {
|
|
|
39
39
|
if (webHelpers.includes(helperName)) {
|
|
40
40
|
const I = enabledHelpers[helperName]
|
|
41
41
|
recorder.add(() => I.amOnPage('/'))
|
|
42
|
-
recorder.catchWithoutStop(
|
|
42
|
+
recorder.catchWithoutStop(e => output.print(`Error while loading home page: ${e.message}}`))
|
|
43
43
|
break
|
|
44
44
|
}
|
|
45
45
|
}
|
package/lib/command/list.js
CHANGED
|
@@ -17,7 +17,7 @@ module.exports = function (path) {
|
|
|
17
17
|
const actions = []
|
|
18
18
|
for (const name in helpers) {
|
|
19
19
|
const helper = helpers[name]
|
|
20
|
-
methodsOfObject(helper).forEach(
|
|
20
|
+
methodsOfObject(helper).forEach(action => {
|
|
21
21
|
const params = getParamsToString(helper[action])
|
|
22
22
|
actions[action] = 1
|
|
23
23
|
output.print(` ${output.colors.grey(name)} I.${output.colors.bold(action)}(${params})`)
|