codeceptjs 4.0.0-beta.2 → 4.0.0-beta.21
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 +133 -120
- package/bin/codecept.js +107 -96
- package/bin/test-server.js +64 -0
- package/docs/webapi/clearCookie.mustache +1 -1
- package/docs/webapi/click.mustache +5 -1
- package/lib/actor.js +73 -103
- package/lib/ai.js +159 -188
- package/lib/assert/empty.js +22 -24
- package/lib/assert/equal.js +30 -37
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +43 -48
- package/lib/assert/throws.js +11 -11
- package/lib/assert/truth.js +22 -22
- package/lib/assert.js +20 -18
- package/lib/codecept.js +262 -162
- package/lib/colorUtils.js +50 -52
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +56 -51
- package/lib/command/definitions.js +96 -109
- package/lib/command/dryRun.js +77 -79
- package/lib/command/generate.js +234 -194
- package/lib/command/gherkin/init.js +42 -33
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +20 -17
- package/lib/command/info.js +74 -38
- package/lib/command/init.js +301 -290
- package/lib/command/interactive.js +41 -32
- package/lib/command/list.js +28 -27
- package/lib/command/run-multiple/chunk.js +51 -48
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +5 -1
- package/lib/command/run-multiple.js +97 -97
- package/lib/command/run-rerun.js +19 -25
- package/lib/command/run-workers.js +68 -92
- package/lib/command/run.js +39 -27
- package/lib/command/utils.js +80 -64
- package/lib/command/workers/runTests.js +388 -226
- package/lib/config.js +109 -50
- package/lib/container.js +765 -261
- package/lib/data/context.js +60 -61
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +32 -32
- package/lib/data/table.js +22 -22
- package/lib/effects.js +307 -0
- package/lib/element/WebElement.js +327 -0
- package/lib/els.js +160 -0
- package/lib/event.js +173 -163
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -85
- package/lib/helper/AI.js +131 -41
- package/lib/helper/ApiDataFactory.js +107 -75
- package/lib/helper/Appium.js +542 -404
- package/lib/helper/FileSystem.js +100 -79
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +52 -52
- package/lib/helper/JSONResponse.js +126 -88
- package/lib/helper/Mochawesome.js +54 -29
- package/lib/helper/Playwright.js +2547 -1316
- package/lib/helper/Puppeteer.js +1578 -1181
- package/lib/helper/REST.js +209 -68
- package/lib/helper/WebDriver.js +1482 -1342
- 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/PlaywrightReactVueLocator.js +17 -8
- package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +27 -28
- package/lib/helper/network/actions.js +36 -42
- package/lib/helper/network/utils.js +78 -84
- package/lib/helper/scripts/blurElement.js +5 -5
- package/lib/helper/scripts/focusElement.js +5 -5
- package/lib/helper/scripts/highlightElement.js +8 -8
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -3
- package/lib/history.js +23 -19
- package/lib/hooks.js +8 -8
- package/lib/html.js +94 -104
- package/lib/index.js +38 -27
- package/lib/listener/config.js +30 -23
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/enhancedGlobalRetry.js +110 -0
- package/lib/listener/exit.js +16 -18
- package/lib/listener/globalRetry.js +70 -0
- package/lib/listener/globalTimeout.js +181 -0
- package/lib/listener/helpers.js +76 -51
- package/lib/listener/mocha.js +10 -11
- package/lib/listener/result.js +11 -0
- package/lib/listener/retryEnhancer.js +85 -0
- package/lib/listener/steps.js +71 -59
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +214 -197
- package/lib/mocha/asyncWrapper.js +274 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +163 -0
- package/lib/mocha/featureConfig.js +89 -0
- package/lib/mocha/gherkin.js +231 -0
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +184 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +242 -0
- package/lib/output.js +141 -71
- package/lib/parser.js +54 -44
- package/lib/pause.js +173 -145
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +178 -79
- package/lib/plugin/autoDelay.js +36 -40
- package/lib/plugin/coverage.js +131 -78
- package/lib/plugin/customLocator.js +22 -21
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/enhancedRetryFailedStep.js +99 -0
- package/lib/plugin/heal.js +101 -110
- package/lib/plugin/htmlReporter.js +3648 -0
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +12 -11
- package/lib/plugin/retryFailedStep.js +82 -47
- package/lib/plugin/screenshotOnFail.js +111 -92
- package/lib/plugin/stepByStepReport.js +159 -101
- package/lib/plugin/stepTimeout.js +20 -25
- package/lib/plugin/subtitles.js +38 -38
- package/lib/recorder.js +193 -130
- package/lib/rerun.js +94 -49
- package/lib/result.js +238 -0
- package/lib/retryCoordinator.js +207 -0
- package/lib/secret.js +20 -18
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -329
- package/lib/steps.js +54 -0
- package/lib/store.js +38 -7
- package/lib/template/heal.js +3 -12
- package/lib/template/prompts/generatePageObject.js +31 -0
- package/lib/template/prompts/healStep.js +13 -0
- package/lib/template/prompts/writeStep.js +9 -0
- package/lib/test-server.js +334 -0
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +34 -21
- package/lib/utils/loaderCheck.js +124 -0
- package/lib/utils/mask_data.js +47 -0
- package/lib/utils/typescript.js +237 -0
- package/lib/utils.js +411 -228
- package/lib/workerStorage.js +37 -34
- package/lib/workers.js +532 -296
- package/package.json +124 -95
- package/translations/de-DE.js +5 -3
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +22 -12
- package/translations/it-IT.js +4 -3
- package/translations/ja-JP.js +4 -3
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +4 -3
- package/translations/pt-BR.js +4 -3
- package/translations/ru-RU.js +4 -3
- package/translations/utils.js +10 -0
- package/translations/zh-CN.js +4 -3
- package/translations/zh-TW.js +4 -3
- package/typings/index.d.ts +546 -185
- package/typings/promiseBasedTypes.d.ts +150 -875
- package/typings/types.d.ts +547 -992
- package/lib/cli.js +0 -249
- package/lib/dirname.js +0 -5
- package/lib/helper/Expect.js +0 -425
- package/lib/helper/ExpectHelper.js +0 -399
- package/lib/helper/MockServer.js +0 -223
- package/lib/helper/Nightmare.js +0 -1411
- package/lib/helper/Protractor.js +0 -1835
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1410
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -63
- package/lib/interfaces/bdd.js +0 -98
- package/lib/interfaces/featureConfig.js +0 -69
- package/lib/interfaces/gherkin.js +0 -195
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/retry.js +0 -68
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -110
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -121
- package/lib/plugin/selenoid.js +0 -371
- package/lib/plugin/standardActingHelpers.js +0 -9
- package/lib/plugin/tryTo.js +0 -105
- package/lib/plugin/wdio.js +0 -246
- package/lib/scenario.js +0 -222
- package/lib/ui.js +0 -238
- package/lib/within.js +0 -70
package/lib/output.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import colors from 'chalk'
|
|
2
|
-
import figures from 'figures'
|
|
1
|
+
import colors from 'chalk'
|
|
2
|
+
import figures from 'figures'
|
|
3
|
+
import { maskData, shouldMaskData, getMaskConfig } from './utils/mask_data.js'
|
|
3
4
|
|
|
4
5
|
const styles = {
|
|
5
6
|
error: colors.bgRed.white.bold,
|
|
@@ -9,17 +10,18 @@ const styles = {
|
|
|
9
10
|
debug: colors.cyan,
|
|
10
11
|
log: colors.grey,
|
|
11
12
|
bold: colors.bold,
|
|
12
|
-
|
|
13
|
+
section: colors.white.dim.bold,
|
|
14
|
+
}
|
|
13
15
|
|
|
14
|
-
let outputLevel = 0
|
|
15
|
-
let outputProcess = ''
|
|
16
|
-
let newline = true
|
|
16
|
+
let outputLevel = 0
|
|
17
|
+
let outputProcess = ''
|
|
18
|
+
let newline = true
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* @alias output
|
|
20
22
|
* @namespace
|
|
21
23
|
*/
|
|
22
|
-
|
|
24
|
+
const output = {
|
|
23
25
|
colors,
|
|
24
26
|
styles,
|
|
25
27
|
print,
|
|
@@ -27,7 +29,7 @@ export const output = {
|
|
|
27
29
|
stepShift: 0,
|
|
28
30
|
|
|
29
31
|
standWithUkraine() {
|
|
30
|
-
return `#${colors.bold.yellow('StandWith')}${colors.bold.cyan('Ukraine')}
|
|
32
|
+
return `#${colors.bold.yellow('StandWith')}${colors.bold.cyan('Ukraine')}`
|
|
31
33
|
},
|
|
32
34
|
|
|
33
35
|
/**
|
|
@@ -36,8 +38,8 @@ export const output = {
|
|
|
36
38
|
* @returns {number}
|
|
37
39
|
*/
|
|
38
40
|
level(level) {
|
|
39
|
-
if (level !== undefined) outputLevel = level
|
|
40
|
-
return outputLevel
|
|
41
|
+
if (level !== undefined) outputLevel = level
|
|
42
|
+
return outputLevel
|
|
41
43
|
},
|
|
42
44
|
|
|
43
45
|
/**
|
|
@@ -47,9 +49,42 @@ export const output = {
|
|
|
47
49
|
* @returns {string}
|
|
48
50
|
*/
|
|
49
51
|
process(process) {
|
|
50
|
-
if (process === null) return outputProcess = ''
|
|
51
|
-
if (process)
|
|
52
|
-
|
|
52
|
+
if (process === null) return (outputProcess = '')
|
|
53
|
+
if (process) {
|
|
54
|
+
// Handle objects by converting to empty string or extracting properties
|
|
55
|
+
let processValue = process
|
|
56
|
+
if (typeof process === 'object') {
|
|
57
|
+
// If it's an object, try to extract a numeric value or use empty string
|
|
58
|
+
processValue = process.id || process.index || process.worker || ''
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check if this is a run-multiple process (contains : or .)
|
|
62
|
+
// Format: "1.runName:browserName" from run-multiple
|
|
63
|
+
if (String(processValue).includes(':') || (String(processValue).includes('.') && String(processValue).split('.').length > 1)) {
|
|
64
|
+
// Keep original format for run-multiple
|
|
65
|
+
outputProcess = colors.cyan.bold(`[${processValue}]`)
|
|
66
|
+
} else {
|
|
67
|
+
// Standard worker format for run-workers
|
|
68
|
+
const processNum = parseInt(processValue, 10)
|
|
69
|
+
const processStr = !isNaN(processNum) ? String(processNum).padStart(2, '0') : String(processValue).padStart(2, '0')
|
|
70
|
+
|
|
71
|
+
// Assign different colors to different workers for better identification
|
|
72
|
+
const workerColors = [
|
|
73
|
+
colors.cyan, // Worker 01 - Cyan
|
|
74
|
+
colors.magenta, // Worker 02 - Magenta
|
|
75
|
+
colors.green, // Worker 03 - Green
|
|
76
|
+
colors.yellow, // Worker 04 - Yellow
|
|
77
|
+
colors.blue, // Worker 05 - Blue
|
|
78
|
+
colors.red, // Worker 06 - Red
|
|
79
|
+
colors.white, // Worker 07 - White
|
|
80
|
+
colors.gray, // Worker 08 - Gray
|
|
81
|
+
]
|
|
82
|
+
const workerIndex = !isNaN(processNum) ? processNum - 1 : -1
|
|
83
|
+
const colorFn = workerIndex >= 0 && workerColors[workerIndex % workerColors.length] ? workerColors[workerIndex % workerColors.length] : colors.cyan
|
|
84
|
+
outputProcess = colorFn.bold(`[Worker ${processStr}]`)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return outputProcess
|
|
53
88
|
},
|
|
54
89
|
|
|
55
90
|
/**
|
|
@@ -57,22 +92,20 @@ export const output = {
|
|
|
57
92
|
* @param {string} msg
|
|
58
93
|
*/
|
|
59
94
|
debug(msg) {
|
|
95
|
+
const _msg = shouldMaskData() ? maskData(msg, getMaskConfig()) : msg
|
|
60
96
|
if (outputLevel >= 2) {
|
|
61
|
-
print(' '.repeat(
|
|
97
|
+
print(' '.repeat(output.stepShift), styles.debug(`${figures.pointerSmall} ${_msg}`))
|
|
62
98
|
}
|
|
63
99
|
},
|
|
64
100
|
|
|
65
|
-
debugSection(section, msg) {
|
|
66
|
-
this.debug(`[${section}] ${msg}`);
|
|
67
|
-
},
|
|
68
|
-
|
|
69
101
|
/**
|
|
70
102
|
* Print information in --verbose mode
|
|
71
103
|
* @param {string} msg
|
|
72
104
|
*/
|
|
73
105
|
log(msg) {
|
|
106
|
+
const _msg = shouldMaskData() ? maskData(msg, getMaskConfig()) : msg
|
|
74
107
|
if (outputLevel >= 3) {
|
|
75
|
-
print(' '.repeat(
|
|
108
|
+
print(' '.repeat(output.stepShift), styles.log(truncate(` ${_msg}`, output.stepShift)))
|
|
76
109
|
}
|
|
77
110
|
},
|
|
78
111
|
|
|
@@ -81,7 +114,8 @@ export const output = {
|
|
|
81
114
|
* @param {string} msg
|
|
82
115
|
*/
|
|
83
116
|
error(msg) {
|
|
84
|
-
|
|
117
|
+
const _msg = shouldMaskData() ? maskData(msg, getMaskConfig()) : msg
|
|
118
|
+
print(styles.error(_msg))
|
|
85
119
|
},
|
|
86
120
|
|
|
87
121
|
/**
|
|
@@ -89,7 +123,8 @@ export const output = {
|
|
|
89
123
|
* @param {string} msg
|
|
90
124
|
*/
|
|
91
125
|
success(msg) {
|
|
92
|
-
|
|
126
|
+
const _msg = shouldMaskData() ? maskData(msg, getMaskConfig()) : msg
|
|
127
|
+
print(styles.success(_msg))
|
|
93
128
|
},
|
|
94
129
|
|
|
95
130
|
/**
|
|
@@ -98,7 +133,7 @@ export const output = {
|
|
|
98
133
|
* @param {string} msg
|
|
99
134
|
*/
|
|
100
135
|
plugin(pluginName, msg = '') {
|
|
101
|
-
|
|
136
|
+
output.debug(`<${pluginName}> ${msg}`)
|
|
102
137
|
},
|
|
103
138
|
|
|
104
139
|
/**
|
|
@@ -106,25 +141,26 @@ export const output = {
|
|
|
106
141
|
* @param {CodeceptJS.Step} step
|
|
107
142
|
*/
|
|
108
143
|
step(step) {
|
|
109
|
-
if (outputLevel === 0) return
|
|
110
|
-
if (!step) return
|
|
144
|
+
if (outputLevel === 0) return
|
|
145
|
+
if (!step) return
|
|
111
146
|
// Avoid to print non-gherkin steps, when gherkin is running for --steps mode
|
|
112
147
|
if (outputLevel === 1) {
|
|
113
148
|
if (typeof step === 'object' && step.hasBDDAncestor()) {
|
|
114
|
-
return
|
|
149
|
+
return
|
|
115
150
|
}
|
|
116
151
|
}
|
|
117
152
|
|
|
118
|
-
let stepLine = step.toString()
|
|
153
|
+
let stepLine = step.toCliStyled ? step.toCliStyled() : step.toString()
|
|
119
154
|
if (step.metaStep && outputLevel >= 1) {
|
|
120
|
-
this.stepShift += 2;
|
|
121
|
-
stepLine = colors.
|
|
155
|
+
// this.stepShift += 2;
|
|
156
|
+
stepLine = colors.dim(truncate(stepLine, output.stepShift))
|
|
122
157
|
}
|
|
123
158
|
if (step.comment) {
|
|
124
|
-
stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4)))
|
|
159
|
+
stepLine += colors.grey(step.comment.split('\n').join('\n' + ' '.repeat(4)))
|
|
125
160
|
}
|
|
126
161
|
|
|
127
|
-
|
|
162
|
+
const _stepLine = shouldMaskData() ? maskData(stepLine, getMaskConfig()) : stepLine
|
|
163
|
+
print(' '.repeat(this.stepShift), truncate(_stepLine, this.spaceShift))
|
|
128
164
|
},
|
|
129
165
|
|
|
130
166
|
/** @namespace */
|
|
@@ -132,10 +168,11 @@ export const output = {
|
|
|
132
168
|
/**
|
|
133
169
|
* @param {Mocha.Suite} suite
|
|
134
170
|
*/
|
|
135
|
-
started:
|
|
136
|
-
if (!suite.title) return
|
|
137
|
-
print(`${colors.bold(suite.title)} --`)
|
|
138
|
-
if (suite.
|
|
171
|
+
started: suite => {
|
|
172
|
+
if (!suite.title) return
|
|
173
|
+
print(`${colors.bold(suite.title)} --`)
|
|
174
|
+
if (suite.file && outputLevel >= 1) print(colors.underline.grey(suite.file))
|
|
175
|
+
if (suite.comment) print(suite.comment)
|
|
139
176
|
},
|
|
140
177
|
},
|
|
141
178
|
|
|
@@ -145,25 +182,38 @@ export const output = {
|
|
|
145
182
|
* @param {Mocha.Test} test
|
|
146
183
|
*/
|
|
147
184
|
started(test) {
|
|
148
|
-
|
|
185
|
+
// Only show feature name in workers mode (when outputProcess is set)
|
|
186
|
+
const featureName = outputProcess && test.parent?.title ? `${colors.cyan.bold(test.parent.title)} › ` : ''
|
|
187
|
+
print(` ${featureName}${colors.magenta.bold(test.title)}`)
|
|
149
188
|
},
|
|
150
189
|
/**
|
|
151
190
|
* @param {Mocha.Test} test
|
|
152
191
|
*/
|
|
153
192
|
passed(test) {
|
|
154
|
-
|
|
193
|
+
// Only show feature name in workers mode (when outputProcess is set)
|
|
194
|
+
const featureName = outputProcess && test.parent?.title ? `${colors.cyan(test.parent.title)} › ` : ''
|
|
195
|
+
const scenarioName = colors.bold(test.title)
|
|
196
|
+
const executionTime = colors.cyan(`in ${test.duration}ms`)
|
|
197
|
+
print(` ${colors.green.bold(figures.tick)} ${featureName}${scenarioName} ${executionTime}`)
|
|
155
198
|
},
|
|
156
199
|
/**
|
|
157
200
|
* @param {Mocha.Test} test
|
|
158
201
|
*/
|
|
159
202
|
failed(test) {
|
|
160
|
-
|
|
203
|
+
// Only show feature name in workers mode (when outputProcess is set)
|
|
204
|
+
const featureName = outputProcess && test.parent?.title ? `${colors.yellow(test.parent.title)} › ` : ''
|
|
205
|
+
const scenarioName = colors.bold(test.title)
|
|
206
|
+
const executionTime = colors.yellow(`in ${test.duration}ms`)
|
|
207
|
+
print(` ${colors.red.bold(figures.cross)} ${featureName}${scenarioName} ${executionTime}`)
|
|
161
208
|
},
|
|
162
209
|
/**
|
|
163
210
|
* @param {Mocha.Test} test
|
|
164
211
|
*/
|
|
165
212
|
skipped(test) {
|
|
166
|
-
|
|
213
|
+
// Only show feature name in workers mode (when outputProcess is set)
|
|
214
|
+
const featureName = outputProcess && test.parent?.title ? `${colors.gray(test.parent.title)} › ` : ''
|
|
215
|
+
const scenarioName = colors.bold(test.title)
|
|
216
|
+
print(` ${colors.yellow.bold('S')} ${featureName}${scenarioName}`)
|
|
167
217
|
},
|
|
168
218
|
},
|
|
169
219
|
|
|
@@ -172,22 +222,40 @@ export const output = {
|
|
|
172
222
|
/**
|
|
173
223
|
* @param {Mocha.Test} test
|
|
174
224
|
*/
|
|
175
|
-
|
|
176
|
-
started(test) {
|
|
177
|
-
|
|
225
|
+
|
|
226
|
+
started(test) {
|
|
227
|
+
if (outputLevel < 1) return
|
|
228
|
+
print(` ${colors.dim.bold('Scenario()')}`)
|
|
229
|
+
},
|
|
230
|
+
|
|
178
231
|
/**
|
|
179
232
|
* @param {Mocha.Test} test
|
|
180
233
|
*/
|
|
181
234
|
passed(test) {
|
|
182
|
-
print(` ${colors.green.bold(`${figures.tick} OK`)} ${colors.grey(`in ${test.duration}ms`)}`)
|
|
183
|
-
print()
|
|
235
|
+
print(` ${colors.green.bold(`${figures.tick} OK`)} ${colors.grey(`in ${test.duration}ms`)}`)
|
|
236
|
+
print()
|
|
184
237
|
},
|
|
185
238
|
/**
|
|
186
239
|
* @param {Mocha.Test} test
|
|
187
240
|
*/
|
|
188
241
|
failed(test) {
|
|
189
|
-
print(` ${colors.red.bold(`${figures.cross} FAILED`)} ${colors.grey(`in ${test.duration}ms`)}`)
|
|
190
|
-
print()
|
|
242
|
+
print(` ${colors.red.bold(`${figures.cross} FAILED`)} ${colors.grey(`in ${test.duration}ms`)}`)
|
|
243
|
+
print()
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
hook: {
|
|
248
|
+
started(hook) {
|
|
249
|
+
if (outputLevel < 1) return
|
|
250
|
+
print(` ${colors.dim.bold(hook.toCode())}`)
|
|
251
|
+
},
|
|
252
|
+
passed(hook) {
|
|
253
|
+
if (outputLevel < 1) return
|
|
254
|
+
print()
|
|
255
|
+
},
|
|
256
|
+
failed(hook) {
|
|
257
|
+
if (outputLevel < 1) return
|
|
258
|
+
print(` ${colors.red.bold(hook.toCode())}`)
|
|
191
259
|
},
|
|
192
260
|
},
|
|
193
261
|
|
|
@@ -199,9 +267,9 @@ export const output = {
|
|
|
199
267
|
*/
|
|
200
268
|
say(message, color = 'cyan') {
|
|
201
269
|
if (colors[color] === undefined) {
|
|
202
|
-
color = 'cyan'
|
|
270
|
+
color = 'cyan'
|
|
203
271
|
}
|
|
204
|
-
if (outputLevel >= 1) print(` ${colors[color].bold(message)}`)
|
|
272
|
+
if (outputLevel >= 1) print(` ${colors[color].bold(message)}`)
|
|
205
273
|
},
|
|
206
274
|
|
|
207
275
|
/**
|
|
@@ -211,50 +279,52 @@ export const output = {
|
|
|
211
279
|
* @param {number|string} duration
|
|
212
280
|
*/
|
|
213
281
|
result(passed, failed, skipped, duration, failedHooks = 0) {
|
|
214
|
-
let style = colors.bgGreen
|
|
215
|
-
let msg = ` ${passed || 0} passed
|
|
216
|
-
let status = style.bold(' OK ')
|
|
282
|
+
let style = colors.bgGreen
|
|
283
|
+
let msg = ` ${passed || 0} passed`
|
|
284
|
+
let status = style.bold(' OK ')
|
|
217
285
|
if (failed) {
|
|
218
|
-
style = style.bgRed
|
|
219
|
-
status = style.bold(' FAIL ')
|
|
220
|
-
msg += `, ${failed} failed
|
|
286
|
+
style = style.bgRed
|
|
287
|
+
status = style.bold(' FAIL ')
|
|
288
|
+
msg += `, ${failed} failed`
|
|
221
289
|
}
|
|
222
290
|
|
|
223
291
|
if (failedHooks > 0) {
|
|
224
|
-
style = style.bgRed
|
|
225
|
-
status = style.bold(' FAIL ')
|
|
226
|
-
msg += `, ${failedHooks} failedHooks
|
|
292
|
+
style = style.bgRed
|
|
293
|
+
status = style.bold(' FAIL ')
|
|
294
|
+
msg += `, ${failedHooks} failedHooks`
|
|
227
295
|
}
|
|
228
|
-
status += style.grey(' |')
|
|
296
|
+
status += style.grey(' |')
|
|
229
297
|
|
|
230
298
|
if (skipped) {
|
|
231
|
-
if (!failed) style = style.bgYellow
|
|
232
|
-
msg += `, ${skipped} skipped
|
|
299
|
+
if (!failed) style = style.bgYellow
|
|
300
|
+
msg += `, ${skipped} skipped`
|
|
233
301
|
}
|
|
234
|
-
msg += ' '
|
|
235
|
-
print(status + style(msg) + colors.grey(` // ${duration}`))
|
|
302
|
+
msg += ' '
|
|
303
|
+
print(status + style(msg) + colors.grey(` // ${duration}`))
|
|
236
304
|
},
|
|
237
|
-
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export default output
|
|
238
308
|
|
|
239
|
-
|
|
309
|
+
function print(...msg) {
|
|
240
310
|
if (outputProcess) {
|
|
241
|
-
msg.unshift(outputProcess)
|
|
311
|
+
msg.unshift(outputProcess)
|
|
242
312
|
}
|
|
243
313
|
if (!newline) {
|
|
244
|
-
console.log()
|
|
245
|
-
newline = true
|
|
314
|
+
console.log()
|
|
315
|
+
newline = true
|
|
246
316
|
}
|
|
247
317
|
|
|
248
|
-
console.log.apply(this, msg)
|
|
318
|
+
console.log.apply(this, msg)
|
|
249
319
|
}
|
|
250
320
|
|
|
251
321
|
function truncate(msg, gap = 0) {
|
|
252
322
|
if (msg.indexOf('\n') > 0 || outputLevel >= 3) {
|
|
253
|
-
return msg
|
|
323
|
+
return msg // don't cut multi line steps or on verbose log level
|
|
254
324
|
}
|
|
255
|
-
const width = (process.stdout.columns || 200) - gap - 4
|
|
325
|
+
const width = (process.stdout.columns || 200) - gap - 4
|
|
256
326
|
if (msg.length > width) {
|
|
257
|
-
msg = msg.substr(0, width - 1) + figures.ellipsis
|
|
327
|
+
msg = msg.substr(0, width - 1) + figures.ellipsis
|
|
258
328
|
}
|
|
259
|
-
return msg
|
|
329
|
+
return msg
|
|
260
330
|
}
|
package/lib/parser.js
CHANGED
|
@@ -1,71 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
function _interopDefault(ex) {
|
|
2
|
+
return ex && typeof ex === 'object' && 'default' in ex ? ex.default : ex
|
|
3
|
+
}
|
|
4
|
+
import * as acorn from 'acorn'
|
|
5
|
+
import parseFunctionModule from 'parse-function'
|
|
6
|
+
const parseFunction = _interopDefault(parseFunctionModule)
|
|
7
|
+
const parser = parseFunction({ parse: acorn.parse, ecmaVersion: 11, plugins: ['objectRestSpread'] })
|
|
8
|
+
import output from './output.js'
|
|
9
|
+
|
|
10
|
+
parser.use(destructuredArgs)
|
|
4
11
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const newFn = fn.toString().replace(/^async/, 'async function');
|
|
9
|
-
return getParams(newFn).join(', ');
|
|
12
|
+
export const getParamsToString = function (fn) {
|
|
13
|
+
const newFn = fn.toString().replace(/^async/, 'async function')
|
|
14
|
+
return getParams(newFn).join(', ')
|
|
10
15
|
}
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
if (fn.isSinonProxy) return []
|
|
17
|
+
function getParams(fn) {
|
|
18
|
+
if (fn.isSinonProxy) return []
|
|
14
19
|
try {
|
|
15
|
-
|
|
20
|
+
// Convert arrow functions to regular functions for parsing
|
|
21
|
+
let fnString = fn.toString()
|
|
22
|
+
// Handle async arrow functions: async (...) => { becomes async function(...) {
|
|
23
|
+
fnString = fnString.replace(/^async\s*(\([^)]*\))\s*=>/, 'async function$1')
|
|
24
|
+
// Handle regular arrow functions: (...) => { becomes function(...) {
|
|
25
|
+
fnString = fnString.replace(/^(\([^)]*\))\s*=>/, 'function$1')
|
|
26
|
+
|
|
27
|
+
const reflected = parser.parse(fnString)
|
|
16
28
|
if (reflected.args.length > 1 || reflected.args[0] === 'I') {
|
|
17
|
-
output.
|
|
29
|
+
output.error('Error: old CodeceptJS v2 format detected. Upgrade your project to the new format -> https://bit.ly/codecept3Up')
|
|
18
30
|
}
|
|
19
|
-
if (reflected.destructuredArgs.length > 0) reflected.args = [...reflected.destructuredArgs]
|
|
20
|
-
const params = reflected.args.map(
|
|
21
|
-
const def = reflected.defaults[p]
|
|
31
|
+
if (reflected.destructuredArgs.length > 0) reflected.args = [...reflected.destructuredArgs]
|
|
32
|
+
const params = reflected.args.map(p => {
|
|
33
|
+
const def = reflected.defaults[p]
|
|
22
34
|
if (def) {
|
|
23
|
-
return `${p}=${def}
|
|
35
|
+
return `${p}=${def}`
|
|
24
36
|
}
|
|
25
|
-
return p
|
|
26
|
-
})
|
|
27
|
-
return params
|
|
37
|
+
return p
|
|
38
|
+
})
|
|
39
|
+
return params
|
|
28
40
|
} catch (err) {
|
|
29
|
-
console.log(`Error in ${fn.toString()}`)
|
|
30
|
-
output.
|
|
41
|
+
console.log(`Error in ${fn.toString()}`)
|
|
42
|
+
output.error(err)
|
|
31
43
|
}
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
export
|
|
46
|
+
export { getParams }
|
|
47
|
+
|
|
48
|
+
function destructuredArgs() {
|
|
35
49
|
return (node, result) => {
|
|
36
|
-
result.destructuredArgs = result.destructuredArgs || []
|
|
50
|
+
result.destructuredArgs = result.destructuredArgs || []
|
|
37
51
|
|
|
38
52
|
if (node.type === 'ObjectExpression' && node.properties.length > 0) {
|
|
39
|
-
node.properties.forEach(
|
|
53
|
+
node.properties.forEach(prop => {
|
|
40
54
|
if (prop.value && prop.value.params.length > 0) {
|
|
41
|
-
result.destructuredArgs = parseDestructuredArgs(prop.value)
|
|
55
|
+
result.destructuredArgs = parseDestructuredArgs(prop.value)
|
|
42
56
|
}
|
|
43
|
-
})
|
|
57
|
+
})
|
|
44
58
|
|
|
45
|
-
return result
|
|
59
|
+
return result
|
|
46
60
|
}
|
|
47
61
|
|
|
48
|
-
if (!Array.isArray(node.params)) return result
|
|
49
|
-
result.destructuredArgs = parseDestructuredArgs(node)
|
|
62
|
+
if (!Array.isArray(node.params)) return result
|
|
63
|
+
result.destructuredArgs = parseDestructuredArgs(node)
|
|
50
64
|
|
|
51
|
-
return result
|
|
52
|
-
}
|
|
65
|
+
return result
|
|
66
|
+
}
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
function parseDestructuredArgs(node) {
|
|
56
|
-
const destructuredArgs = []
|
|
57
|
-
node.params.forEach(
|
|
58
|
-
if (
|
|
59
|
-
param.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
param.properties.forEach((prop) => {
|
|
64
|
-
const { name } = prop.value;
|
|
65
|
-
destructuredArgs.push(name);
|
|
66
|
-
});
|
|
70
|
+
const destructuredArgs = []
|
|
71
|
+
node.params.forEach(param => {
|
|
72
|
+
if (param.type === 'ObjectPattern' && param.properties && param.properties.length > 0) {
|
|
73
|
+
param.properties.forEach(prop => {
|
|
74
|
+
const { name } = prop.value
|
|
75
|
+
destructuredArgs.push(name)
|
|
76
|
+
})
|
|
67
77
|
}
|
|
68
|
-
})
|
|
78
|
+
})
|
|
69
79
|
|
|
70
|
-
return destructuredArgs
|
|
80
|
+
return destructuredArgs
|
|
71
81
|
}
|