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
|
@@ -11,20 +11,7 @@ const { getConfig, getTestRoot, fail } = require('./utils')
|
|
|
11
11
|
const runner = path.join(__dirname, '/../../bin/codecept')
|
|
12
12
|
let config
|
|
13
13
|
const childOpts = {}
|
|
14
|
-
const copyOptions = [
|
|
15
|
-
'override',
|
|
16
|
-
'steps',
|
|
17
|
-
'reporter',
|
|
18
|
-
'verbose',
|
|
19
|
-
'config',
|
|
20
|
-
'reporter-options',
|
|
21
|
-
'grep',
|
|
22
|
-
'fgrep',
|
|
23
|
-
'invert',
|
|
24
|
-
'debug',
|
|
25
|
-
'plugins',
|
|
26
|
-
'colors',
|
|
27
|
-
]
|
|
14
|
+
const copyOptions = ['override', 'steps', 'reporter', 'verbose', 'config', 'reporter-options', 'grep', 'fgrep', 'invert', 'debug', 'plugins', 'colors']
|
|
28
15
|
let overrides = {}
|
|
29
16
|
|
|
30
17
|
// codeceptjs run-multiple smoke:chrome regression:firefox - will launch smoke run in chrome and regression in firefox
|
|
@@ -49,8 +36,8 @@ module.exports = async function (selectedRuns, options) {
|
|
|
49
36
|
|
|
50
37
|
// copy opts to run
|
|
51
38
|
Object.keys(options)
|
|
52
|
-
.filter(
|
|
53
|
-
.forEach(
|
|
39
|
+
.filter(key => copyOptions.indexOf(key) > -1)
|
|
40
|
+
.forEach(key => {
|
|
54
41
|
childOpts[key] = options[key]
|
|
55
42
|
})
|
|
56
43
|
|
|
@@ -96,12 +83,12 @@ module.exports = async function (selectedRuns, options) {
|
|
|
96
83
|
config.gherkin.features = ''
|
|
97
84
|
}
|
|
98
85
|
|
|
99
|
-
const childProcessesPromise = new Promise(
|
|
86
|
+
const childProcessesPromise = new Promise(resolve => {
|
|
100
87
|
processesDone = resolve
|
|
101
88
|
})
|
|
102
89
|
|
|
103
90
|
const runsToExecute = []
|
|
104
|
-
collection.createRuns(selectedRuns, config).forEach(
|
|
91
|
+
collection.createRuns(selectedRuns, config).forEach(run => {
|
|
105
92
|
const runName = run.getOriginalName() || run.getName()
|
|
106
93
|
const runConfig = run.getConfig()
|
|
107
94
|
runsToExecute.push(executeRun(runName, runConfig))
|
|
@@ -113,7 +100,7 @@ module.exports = async function (selectedRuns, options) {
|
|
|
113
100
|
|
|
114
101
|
// Execute all forks
|
|
115
102
|
totalSubprocessCount = runsToExecute.length
|
|
116
|
-
runsToExecute.forEach(
|
|
103
|
+
runsToExecute.forEach(runToExecute => runToExecute.call(this))
|
|
117
104
|
|
|
118
105
|
return childProcessesPromise.then(async () => {
|
|
119
106
|
// fire hook
|
|
@@ -149,11 +136,7 @@ function executeRun(runName, runConfig) {
|
|
|
149
136
|
// tweaking default output directories and for mochawesome
|
|
150
137
|
overriddenConfig = replaceValueDeep(overriddenConfig, 'output', path.join(config.output, outputDir))
|
|
151
138
|
overriddenConfig = replaceValueDeep(overriddenConfig, 'reportDir', path.join(config.output, outputDir))
|
|
152
|
-
overriddenConfig = replaceValueDeep(
|
|
153
|
-
overriddenConfig,
|
|
154
|
-
'mochaFile',
|
|
155
|
-
path.join(config.output, outputDir, `${browserName}_report.xml`),
|
|
156
|
-
)
|
|
139
|
+
overriddenConfig = replaceValueDeep(overriddenConfig, 'mochaFile', path.join(config.output, outputDir, `${browserName}_report.xml`))
|
|
157
140
|
|
|
158
141
|
// override tests configuration
|
|
159
142
|
if (overriddenConfig.tests) {
|
|
@@ -165,15 +148,9 @@ function executeRun(runName, runConfig) {
|
|
|
165
148
|
}
|
|
166
149
|
|
|
167
150
|
// override grep param and collect all params
|
|
168
|
-
const params = [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
`${runId++}.${runName}:${browserName}`,
|
|
172
|
-
'--override',
|
|
173
|
-
JSON.stringify(overriddenConfig),
|
|
174
|
-
]
|
|
175
|
-
|
|
176
|
-
Object.keys(childOpts).forEach((key) => {
|
|
151
|
+
const params = ['run', '--child', `${runId++}.${runName}:${browserName}`, '--override', JSON.stringify(overriddenConfig)]
|
|
152
|
+
|
|
153
|
+
Object.keys(childOpts).forEach(key => {
|
|
177
154
|
params.push(`--${key}`)
|
|
178
155
|
if (childOpts[key] !== true) params.push(childOpts[key])
|
|
179
156
|
})
|
|
@@ -183,7 +160,7 @@ function executeRun(runName, runConfig) {
|
|
|
183
160
|
params.push(runConfig.grep)
|
|
184
161
|
}
|
|
185
162
|
|
|
186
|
-
const onProcessEnd =
|
|
163
|
+
const onProcessEnd = errorCode => {
|
|
187
164
|
if (errorCode !== 0) {
|
|
188
165
|
process.exitCode = errorCode
|
|
189
166
|
}
|
|
@@ -197,7 +174,7 @@ function executeRun(runName, runConfig) {
|
|
|
197
174
|
// Return function of fork for later execution
|
|
198
175
|
return () =>
|
|
199
176
|
fork(runner, params, { stdio: [0, 1, 2, 'ipc'] })
|
|
200
|
-
.on('exit',
|
|
177
|
+
.on('exit', code => {
|
|
201
178
|
return onProcessEnd(code)
|
|
202
179
|
})
|
|
203
180
|
.on('error', () => {
|
|
@@ -34,29 +34,29 @@ module.exports = async function (workerCount, selectedRuns, options) {
|
|
|
34
34
|
const workers = new Workers(numberOfWorkers, config)
|
|
35
35
|
workers.overrideConfig(overrideConfigs)
|
|
36
36
|
|
|
37
|
-
workers.on(event.suite.before,
|
|
37
|
+
workers.on(event.suite.before, suite => {
|
|
38
38
|
suiteArr.push(suite)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
-
workers.on(event.step.passed,
|
|
41
|
+
workers.on(event.step.passed, step => {
|
|
42
42
|
stepArr.push(step)
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
-
workers.on(event.step.failed,
|
|
45
|
+
workers.on(event.step.failed, step => {
|
|
46
46
|
stepArr.push(step)
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
workers.on(event.test.failed,
|
|
49
|
+
workers.on(event.test.failed, test => {
|
|
50
50
|
failedTestArr.push(test)
|
|
51
51
|
output.test.failed(test)
|
|
52
52
|
})
|
|
53
53
|
|
|
54
|
-
workers.on(event.test.passed,
|
|
54
|
+
workers.on(event.test.passed, test => {
|
|
55
55
|
passedTestArr.push(test)
|
|
56
56
|
output.test.passed(test)
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
workers.on(event.test.skipped,
|
|
59
|
+
workers.on(event.test.skipped, test => {
|
|
60
60
|
skippedTestArr.push(test)
|
|
61
61
|
output.test.skipped(test)
|
|
62
62
|
})
|
|
@@ -64,21 +64,21 @@ module.exports = async function (workerCount, selectedRuns, options) {
|
|
|
64
64
|
workers.on(event.all.result, () => {
|
|
65
65
|
// expose test stats after all workers finished their execution
|
|
66
66
|
function addStepsToTest(test, stepArr) {
|
|
67
|
-
stepArr.test.steps.forEach(
|
|
67
|
+
stepArr.test.steps.forEach(step => {
|
|
68
68
|
if (test.steps.length === 0) {
|
|
69
69
|
test.steps.push(step)
|
|
70
70
|
}
|
|
71
71
|
})
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
stepArr.forEach(
|
|
75
|
-
passedTestArr.forEach(
|
|
74
|
+
stepArr.forEach(step => {
|
|
75
|
+
passedTestArr.forEach(test => {
|
|
76
76
|
if (step.test.title === test.title) {
|
|
77
77
|
addStepsToTest(test, step)
|
|
78
78
|
}
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
-
failedTestArr.forEach(
|
|
81
|
+
failedTestArr.forEach(test => {
|
|
82
82
|
if (step.test.title === test.title) {
|
|
83
83
|
addStepsToTest(test, step)
|
|
84
84
|
}
|
package/lib/command/utils.js
CHANGED
|
@@ -29,8 +29,7 @@ module.exports.readConfig = function (configFile) {
|
|
|
29
29
|
function getTestRoot(currentPath) {
|
|
30
30
|
if (!currentPath) currentPath = '.'
|
|
31
31
|
if (!path.isAbsolute(currentPath)) currentPath = path.join(process.cwd(), currentPath)
|
|
32
|
-
currentPath =
|
|
33
|
-
fs.lstatSync(currentPath).isDirectory() || !path.extname(currentPath) ? currentPath : path.dirname(currentPath)
|
|
32
|
+
currentPath = fs.lstatSync(currentPath).isDirectory() || !path.extname(currentPath) ? currentPath : path.dirname(currentPath)
|
|
34
33
|
return currentPath
|
|
35
34
|
}
|
|
36
35
|
module.exports.getTestRoot = getTestRoot
|
|
@@ -71,7 +70,7 @@ function safeFileWrite(file, contents) {
|
|
|
71
70
|
|
|
72
71
|
module.exports.safeFileWrite = safeFileWrite
|
|
73
72
|
|
|
74
|
-
module.exports.captureStream =
|
|
73
|
+
module.exports.captureStream = stream => {
|
|
75
74
|
let oldStream
|
|
76
75
|
let buffer = ''
|
|
77
76
|
|
|
@@ -79,7 +78,7 @@ module.exports.captureStream = (stream) => {
|
|
|
79
78
|
startCapture() {
|
|
80
79
|
buffer = ''
|
|
81
80
|
oldStream = stream.write.bind(stream)
|
|
82
|
-
stream.write =
|
|
81
|
+
stream.write = chunk => (buffer += chunk)
|
|
83
82
|
},
|
|
84
83
|
stopCapture() {
|
|
85
84
|
if (oldStream !== undefined) stream.write = oldStream
|
|
@@ -88,7 +87,7 @@ module.exports.captureStream = (stream) => {
|
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
module.exports.printError =
|
|
90
|
+
module.exports.printError = err => {
|
|
92
91
|
output.print('')
|
|
93
92
|
output.error(err.message)
|
|
94
93
|
output.print('')
|
|
@@ -106,7 +105,7 @@ module.exports.createOutputDir = (config, testRoot) => {
|
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
module.exports.findConfigFile =
|
|
108
|
+
module.exports.findConfigFile = testsPath => {
|
|
110
109
|
const extensions = ['js', 'ts']
|
|
111
110
|
for (const ext of extensions) {
|
|
112
111
|
const configFile = path.join(testsPath, `codecept.conf.${ext}`)
|
|
@@ -20,12 +20,14 @@ const stderr = '';
|
|
|
20
20
|
// Requiring of Codecept need to be after tty.getWindowSize is available.
|
|
21
21
|
const Codecept = require(process.env.CODECEPT_CLASS_PATH || '../../codecept');
|
|
22
22
|
|
|
23
|
-
const {
|
|
24
|
-
options, tests, testRoot, workerIndex,
|
|
25
|
-
} = workerData;
|
|
23
|
+
const { options, tests, testRoot, workerIndex } = workerData;
|
|
26
24
|
|
|
27
25
|
// hide worker output
|
|
28
|
-
if (!options.debug && !options.verbose)
|
|
26
|
+
if (!options.debug && !options.verbose)
|
|
27
|
+
process.stdout.write = string => {
|
|
28
|
+
stdout += string;
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
29
31
|
|
|
30
32
|
const overrideConfigs = tryOrDefault(() => JSON.parse(options.override), {});
|
|
31
33
|
|
|
@@ -39,11 +41,12 @@ codecept.loadTests();
|
|
|
39
41
|
const mocha = container.mocha();
|
|
40
42
|
filterTests();
|
|
41
43
|
|
|
44
|
+
// run tests
|
|
42
45
|
(async function () {
|
|
43
46
|
if (mocha.suite.total()) {
|
|
44
47
|
await runTests();
|
|
45
48
|
}
|
|
46
|
-
}()
|
|
49
|
+
})();
|
|
47
50
|
|
|
48
51
|
async function runTests() {
|
|
49
52
|
try {
|
|
@@ -74,13 +77,7 @@ function filterTests() {
|
|
|
74
77
|
function initializeListeners() {
|
|
75
78
|
function simplifyError(error) {
|
|
76
79
|
if (error) {
|
|
77
|
-
const {
|
|
78
|
-
stack,
|
|
79
|
-
uncaught,
|
|
80
|
-
message,
|
|
81
|
-
actual,
|
|
82
|
-
expected,
|
|
83
|
-
} = error;
|
|
80
|
+
const { stack, uncaught, message, actual, expected } = error;
|
|
84
81
|
|
|
85
82
|
return {
|
|
86
83
|
stack,
|
|
@@ -147,7 +144,7 @@ function initializeListeners() {
|
|
|
147
144
|
// check if arg is a JOI object
|
|
148
145
|
if (arg && arg.$_root) {
|
|
149
146
|
_args.push(JSON.stringify(arg).slice(0, 300));
|
|
150
|
-
|
|
147
|
+
// check if arg is a function
|
|
151
148
|
} else if (arg && typeof arg === 'function') {
|
|
152
149
|
_args.push(arg.name);
|
|
153
150
|
} else {
|
|
@@ -219,7 +216,7 @@ function initializeListeners() {
|
|
|
219
216
|
event.dispatcher.on(event.suite.after, suite => sendToParentThread({ event: event.suite.after, workerIndex, data: simplifyTest(suite) }));
|
|
220
217
|
|
|
221
218
|
// calculate duration
|
|
222
|
-
event.dispatcher.on(event.test.started, test => test.start = new Date());
|
|
219
|
+
event.dispatcher.on(event.test.started, test => (test.start = new Date()));
|
|
223
220
|
|
|
224
221
|
// tests
|
|
225
222
|
event.dispatcher.on(event.test.before, test => sendToParentThread({ event: event.test.before, workerIndex, data: simplifyTest(test) }));
|
|
@@ -239,7 +236,7 @@ function initializeListeners() {
|
|
|
239
236
|
|
|
240
237
|
event.dispatcher.on(event.hook.failed, (test, err) => sendToParentThread({ event: event.hook.failed, workerIndex, data: simplifyTest(test, err) }));
|
|
241
238
|
event.dispatcher.on(event.hook.passed, (test, err) => sendToParentThread({ event: event.hook.passed, workerIndex, data: simplifyTest(test, err) }));
|
|
242
|
-
event.dispatcher.on(event.all.failures,
|
|
239
|
+
event.dispatcher.on(event.all.failures, data => sendToParentThread({ event: event.all.failures, workerIndex, data }));
|
|
243
240
|
|
|
244
241
|
// all
|
|
245
242
|
event.dispatcher.once(event.all.result, () => parentPort.close());
|
|
@@ -263,7 +260,7 @@ function collectStats() {
|
|
|
263
260
|
event.dispatcher.on(event.test.passed, () => {
|
|
264
261
|
stats.passes++;
|
|
265
262
|
});
|
|
266
|
-
event.dispatcher.on(event.test.failed,
|
|
263
|
+
event.dispatcher.on(event.test.failed, test => {
|
|
267
264
|
if (test.ctx._runnable.title.includes('hook: AfterSuite')) {
|
|
268
265
|
stats.failedHooks += 1;
|
|
269
266
|
}
|
|
@@ -285,7 +282,7 @@ function sendToParentThread(data) {
|
|
|
285
282
|
}
|
|
286
283
|
|
|
287
284
|
function listenToParentThread() {
|
|
288
|
-
parentPort.on('message',
|
|
285
|
+
parentPort.on('message', eventData => {
|
|
289
286
|
container.append({ support: eventData.data });
|
|
290
287
|
});
|
|
291
288
|
}
|