codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.esm-aria
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -119
- package/bin/codecept.js +53 -54
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +70 -102
- package/lib/ai.js +131 -121
- package/lib/assert/empty.js +11 -12
- package/lib/assert/equal.js +16 -21
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +11 -15
- package/lib/assert/throws.js +3 -5
- package/lib/assert/truth.js +10 -7
- package/lib/assert.js +18 -18
- package/lib/codecept.js +112 -101
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +13 -14
- package/lib/command/definitions.js +24 -36
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +38 -39
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +49 -15
- package/lib/command/init.js +41 -37
- package/lib/command/interactive.js +22 -13
- package/lib/command/list.js +11 -10
- package/lib/command/run-multiple/chunk.js +50 -47
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +27 -47
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +15 -66
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +22 -21
- package/lib/command/workers/runTests.js +131 -241
- package/lib/config.js +111 -49
- package/lib/container.js +589 -244
- package/lib/data/context.js +16 -18
- package/lib/data/dataScenarioConfig.js +9 -9
- package/lib/data/dataTableArgument.js +7 -7
- package/lib/data/table.js +6 -12
- package/lib/effects.js +307 -0
- package/lib/els.js +160 -0
- package/lib/event.js +24 -19
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -81
- package/lib/helper/AI.js +3 -2
- package/lib/helper/ApiDataFactory.js +19 -19
- package/lib/helper/Appium.js +47 -51
- package/lib/helper/FileSystem.js +35 -15
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +72 -45
- package/lib/helper/Mochawesome.js +14 -11
- package/lib/helper/Playwright.js +832 -434
- package/lib/helper/Puppeteer.js +393 -292
- package/lib/helper/REST.js +32 -27
- package/lib/helper/WebDriver.js +320 -219
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/exit.js +10 -12
- package/lib/listener/{retry.js → globalRetry.js} +10 -10
- package/lib/listener/globalTimeout.js +166 -0
- package/lib/listener/helpers.js +43 -24
- package/lib/listener/mocha.js +4 -5
- package/lib/listener/result.js +11 -0
- package/lib/listener/steps.js +26 -23
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +264 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +160 -0
- package/lib/{interfaces → mocha}/featureConfig.js +33 -13
- package/lib/{interfaces → mocha}/gherkin.js +75 -45
- 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 +32 -8
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +178 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +229 -0
- package/lib/output.js +86 -64
- package/lib/parser.js +44 -44
- package/lib/pause.js +160 -139
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +137 -43
- package/lib/plugin/autoDelay.js +19 -15
- package/lib/plugin/coverage.js +22 -27
- package/lib/plugin/customLocator.js +5 -5
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/heal.js +49 -17
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +60 -19
- package/lib/plugin/screenshotOnFail.js +80 -83
- package/lib/plugin/stepByStepReport.js +70 -31
- package/lib/plugin/stepTimeout.js +7 -13
- package/lib/plugin/subtitles.js +10 -9
- package/lib/recorder.js +167 -126
- package/lib/rerun.js +94 -50
- package/lib/result.js +161 -0
- package/lib/secret.js +18 -17
- 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 -332
- package/lib/steps.js +54 -0
- package/lib/store.js +37 -5
- package/lib/template/heal.js +2 -11
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +354 -250
- package/lib/workerStorage.js +16 -16
- package/lib/workers.js +366 -282
- package/package.json +107 -95
- package/translations/de-DE.js +5 -4
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +23 -9
- package/translations/it-IT.js +5 -4
- package/translations/ja-JP.js +5 -4
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +5 -4
- package/translations/pt-BR.js +5 -4
- package/translations/ru-RU.js +5 -4
- package/translations/utils.js +18 -0
- package/translations/zh-CN.js +5 -4
- package/translations/zh-TW.js +5 -4
- package/typings/index.d.ts +177 -186
- package/typings/promiseBasedTypes.d.ts +3573 -5941
- package/typings/types.d.ts +4042 -6370
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/Nightmare.js +0 -1504
- package/lib/helper/Protractor.js +0 -1863
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1414
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -62
- package/lib/interfaces/bdd.js +0 -81
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -113
- 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 -127
- package/lib/plugin/selenoid.js +0 -384
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/plugin/tryTo.js +0 -115
- package/lib/plugin/wdio.js +0 -249
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
- package/lib/within.js +0 -70
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import event from '../event.js'
|
|
2
|
+
import output from '../output.js'
|
|
3
|
+
import Config from '../config.js'
|
|
4
|
+
import { isNotSet } from '../utils.js'
|
|
5
5
|
|
|
6
6
|
const hooks = ['Before', 'After', 'BeforeSuite', 'AfterSuite']
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
event.dispatcher.on(event.suite.before,
|
|
8
|
+
export default function () {
|
|
9
|
+
event.dispatcher.on(event.suite.before, suite => {
|
|
10
10
|
let retryConfig = Config.get('retry')
|
|
11
11
|
if (!retryConfig) return
|
|
12
12
|
|
|
@@ -28,8 +28,8 @@ module.exports = function () {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
hooks
|
|
31
|
-
.filter(
|
|
32
|
-
.forEach(
|
|
31
|
+
.filter(hook => !!config[hook])
|
|
32
|
+
.forEach(hook => {
|
|
33
33
|
if (isNotSet(suite.opts[`retry${hook}`])) suite.opts[`retry${hook}`] = config[hook]
|
|
34
34
|
})
|
|
35
35
|
|
|
@@ -41,7 +41,7 @@ module.exports = function () {
|
|
|
41
41
|
}
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
event.dispatcher.on(event.test.before,
|
|
44
|
+
event.dispatcher.on(event.test.before, test => {
|
|
45
45
|
let retryConfig = Config.get('retry')
|
|
46
46
|
if (!retryConfig) return
|
|
47
47
|
|
|
@@ -54,7 +54,7 @@ module.exports = function () {
|
|
|
54
54
|
retryConfig = [retryConfig]
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
retryConfig = retryConfig.filter(
|
|
57
|
+
retryConfig = retryConfig.filter(config => !!config.Scenario)
|
|
58
58
|
|
|
59
59
|
for (const config of retryConfig) {
|
|
60
60
|
if (config.grep) {
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import event from '../event.js'
|
|
2
|
+
import output from '../output.js'
|
|
3
|
+
import recorder from '../recorder.js'
|
|
4
|
+
import Config from '../config.js'
|
|
5
|
+
import store from '../store.js'
|
|
6
|
+
import debugModule from 'debug'
|
|
7
|
+
const debug = debugModule('codeceptjs:timeout')
|
|
8
|
+
import { TIMEOUT_ORDER, TimeoutError, TestTimeoutError, StepTimeoutError } from '../timeout.js'
|
|
9
|
+
import { BeforeSuiteHook, AfterSuiteHook } from '../mocha/hooks.js'
|
|
10
|
+
|
|
11
|
+
export default function () {
|
|
12
|
+
let timeout
|
|
13
|
+
let suiteTimeout = []
|
|
14
|
+
let currentTest
|
|
15
|
+
let currentTimeout
|
|
16
|
+
|
|
17
|
+
if (!store.timeouts) {
|
|
18
|
+
console.log('Timeouts were disabled')
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// disable timeout for BeforeSuite/AfterSuite hooks
|
|
23
|
+
// add separate configs to them?
|
|
24
|
+
event.dispatcher.on(event.hook.started, hook => {
|
|
25
|
+
if (hook instanceof BeforeSuiteHook) {
|
|
26
|
+
timeout = null
|
|
27
|
+
suiteTimeout = []
|
|
28
|
+
}
|
|
29
|
+
if (hook instanceof AfterSuiteHook) {
|
|
30
|
+
timeout = null
|
|
31
|
+
suiteTimeout = []
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
event.dispatcher.on(event.suite.before, suite => {
|
|
36
|
+
suiteTimeout = []
|
|
37
|
+
let timeoutConfig = Config.get('timeout')
|
|
38
|
+
|
|
39
|
+
if (timeoutConfig) {
|
|
40
|
+
debug('config:', timeoutConfig)
|
|
41
|
+
if (!Number.isNaN(+timeoutConfig)) {
|
|
42
|
+
checkForSeconds(timeoutConfig)
|
|
43
|
+
suiteTimeout.push(timeoutConfig)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!Array.isArray(timeoutConfig)) {
|
|
47
|
+
timeoutConfig = [timeoutConfig]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const config of timeoutConfig.filter(c => !!c.Feature)) {
|
|
51
|
+
if (config.grep) {
|
|
52
|
+
if (!suite.title.includes(config.grep)) continue
|
|
53
|
+
}
|
|
54
|
+
suiteTimeout.push(config.Feature)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (suite.totalTimeout) suiteTimeout.push(suite.totalTimeout)
|
|
59
|
+
output.log(`Timeouts: ${suiteTimeout}`)
|
|
60
|
+
|
|
61
|
+
if (suiteTimeout.length > 0) debug(suite.title, 'timeout', suiteTimeout)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
event.dispatcher.on(event.test.before, test => {
|
|
65
|
+
currentTest = test
|
|
66
|
+
let testTimeout = null
|
|
67
|
+
|
|
68
|
+
let timeoutConfig = Config.get('timeout')
|
|
69
|
+
|
|
70
|
+
if (typeof timeoutConfig === 'object' || Array.isArray(timeoutConfig)) {
|
|
71
|
+
if (!Array.isArray(timeoutConfig)) {
|
|
72
|
+
timeoutConfig = [timeoutConfig]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (const config of timeoutConfig.filter(c => !!c.Scenario)) {
|
|
76
|
+
console.log('Test Timeout', config, test.title.includes(config.grep))
|
|
77
|
+
if (config.grep) {
|
|
78
|
+
if (!test.title.includes(config.grep)) continue
|
|
79
|
+
}
|
|
80
|
+
testTimeout = config.Scenario
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
timeout = test.totalTimeout || testTimeout || suiteTimeout[suiteTimeout.length - 1]
|
|
85
|
+
if (!timeout) return
|
|
86
|
+
|
|
87
|
+
debug(test.title, 'timeout', {
|
|
88
|
+
'config from file': testTimeout,
|
|
89
|
+
'suite timeout': suiteTimeout,
|
|
90
|
+
'dynamic config': test.totalTimeout,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
currentTimeout = timeout
|
|
94
|
+
output.debug(`Test Timeout: ${timeout}s`)
|
|
95
|
+
timeout *= 1000
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
event.dispatcher.on(event.test.passed, test => {
|
|
99
|
+
currentTest = null
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
event.dispatcher.on(event.test.failed, test => {
|
|
103
|
+
currentTest = null
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
event.dispatcher.on(event.step.before, step => {
|
|
107
|
+
if (typeof timeout !== 'number') return
|
|
108
|
+
|
|
109
|
+
if (!store.timeouts) {
|
|
110
|
+
debug('step', step.toCode().trim(), 'timeout disabled')
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (timeout < 0) {
|
|
115
|
+
debug('Previous steps timed out, setting timeout to 0.01s')
|
|
116
|
+
step.setTimeout(0.01, TIMEOUT_ORDER.testOrSuite)
|
|
117
|
+
} else {
|
|
118
|
+
debug(`Setting timeout ${timeout}ms for step ${step.toCode().trim()}`)
|
|
119
|
+
step.setTimeout(timeout, TIMEOUT_ORDER.testOrSuite)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
event.dispatcher.on(event.step.after, step => {
|
|
124
|
+
if (typeof timeout !== 'number') return
|
|
125
|
+
if (!store.timeouts) return
|
|
126
|
+
|
|
127
|
+
recorder.catchWithoutStop(err => {
|
|
128
|
+
// we wrap timeout errors in a StepTimeoutError
|
|
129
|
+
// but only if global timeout is set
|
|
130
|
+
// should we wrap all timeout errors?
|
|
131
|
+
if (err instanceof TimeoutError) {
|
|
132
|
+
const testTimeoutExceeded = timeout && +Date.now() - step.startTime >= timeout
|
|
133
|
+
debug('Step failed due to global test or suite timeout')
|
|
134
|
+
if (testTimeoutExceeded) {
|
|
135
|
+
debug('Test failed due to global test or suite timeout')
|
|
136
|
+
throw new TestTimeoutError(currentTimeout)
|
|
137
|
+
}
|
|
138
|
+
throw new StepTimeoutError(currentTimeout, step)
|
|
139
|
+
}
|
|
140
|
+
throw err
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
event.dispatcher.on(event.step.finished, step => {
|
|
145
|
+
if (!store.timeouts) {
|
|
146
|
+
debug('step', step.toCode().trim(), 'timeout disabled')
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (typeof timeout === 'number') debug('Timeout', timeout)
|
|
151
|
+
|
|
152
|
+
debug(`step ${step.toCode().trim()}:${step.status} duration`, step.duration)
|
|
153
|
+
if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration
|
|
154
|
+
|
|
155
|
+
if (typeof timeout === 'number' && timeout <= 0 && recorder.isRunning()) {
|
|
156
|
+
debug(`step ${step.toCode().trim()} timed out`)
|
|
157
|
+
recorder.throw(new TestTimeoutError(currentTimeout))
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function checkForSeconds(timeout) {
|
|
163
|
+
if (timeout >= 1000) {
|
|
164
|
+
console.log(`Warning: Timeout was set to ${timeout}secs.\nGlobal timeout should be specified in seconds.`)
|
|
165
|
+
}
|
|
166
|
+
}
|
package/lib/listener/helpers.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const { error } = require('../output')
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import event from '../event.js'
|
|
3
|
+
import recorder from '../recorder.js'
|
|
4
|
+
import store from '../store.js'
|
|
5
|
+
import output from '../output.js'
|
|
7
6
|
/**
|
|
8
7
|
* Enable Helpers to listen to test events
|
|
9
8
|
*/
|
|
10
|
-
|
|
11
|
-
const helpers = container.helpers()
|
|
9
|
+
export default function () {
|
|
10
|
+
const helpers = global.container.helpers()
|
|
12
11
|
|
|
13
12
|
const runHelpersHook = (hook, param) => {
|
|
14
13
|
if (store.dryRun) return
|
|
15
|
-
Object.values(helpers).forEach(
|
|
14
|
+
Object.values(helpers).forEach(helper => {
|
|
16
15
|
if (helper[hook]) {
|
|
17
16
|
helper[hook](param)
|
|
18
17
|
}
|
|
@@ -21,59 +20,79 @@ module.exports = function () {
|
|
|
21
20
|
|
|
22
21
|
const runAsyncHelpersHook = (hook, param, force) => {
|
|
23
22
|
if (store.dryRun) return
|
|
24
|
-
Object.keys(helpers).forEach(
|
|
23
|
+
Object.keys(helpers).forEach(key => {
|
|
25
24
|
if (!helpers[key][hook]) return
|
|
26
25
|
recorder.add(`hook ${key}.${hook}()`, () => helpers[key][hook](param), force, false)
|
|
27
26
|
})
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
event.dispatcher.on(event.suite.before,
|
|
29
|
+
event.dispatcher.on(event.suite.before, suite => {
|
|
31
30
|
// if (suite.parent) return; // only for root suite
|
|
32
31
|
runAsyncHelpersHook('_beforeSuite', suite, true)
|
|
33
32
|
})
|
|
34
33
|
|
|
35
|
-
event.dispatcher.on(event.suite.after,
|
|
34
|
+
event.dispatcher.on(event.suite.after, suite => {
|
|
36
35
|
// if (suite.parent) return; // only for root suite
|
|
37
36
|
runAsyncHelpersHook('_afterSuite', suite, true)
|
|
38
37
|
})
|
|
39
38
|
|
|
40
|
-
event.dispatcher.on(event.test.started,
|
|
39
|
+
event.dispatcher.on(event.test.started, test => {
|
|
41
40
|
runHelpersHook('_test', test)
|
|
42
|
-
recorder.catch(
|
|
41
|
+
recorder.catch(e => output.error(e))
|
|
43
42
|
})
|
|
44
43
|
|
|
45
|
-
event.dispatcher.on(event.test.before,
|
|
44
|
+
event.dispatcher.on(event.test.before, test => {
|
|
46
45
|
// schedule config to revert changes
|
|
47
46
|
runAsyncHelpersHook('_before', test, true)
|
|
48
|
-
recorder.catchWithoutStop(
|
|
47
|
+
recorder.catchWithoutStop(e => output.error(e))
|
|
49
48
|
})
|
|
50
49
|
|
|
51
|
-
event.dispatcher.on(event.test.passed,
|
|
50
|
+
event.dispatcher.on(event.test.passed, test => {
|
|
52
51
|
runAsyncHelpersHook('_passed', test, true)
|
|
53
52
|
// should not fail test execution, so errors should be caught
|
|
54
|
-
recorder.catchWithoutStop(
|
|
53
|
+
recorder.catchWithoutStop(e => output.error(e))
|
|
55
54
|
})
|
|
56
55
|
|
|
57
|
-
event.dispatcher.on(event.test.failed,
|
|
56
|
+
event.dispatcher.on(event.test.failed, test => {
|
|
58
57
|
runAsyncHelpersHook('_failed', test, true)
|
|
59
58
|
// should not fail test execution, so errors should be caught
|
|
60
|
-
recorder.catchWithoutStop(
|
|
59
|
+
recorder.catchWithoutStop(e => output.error(e))
|
|
61
60
|
})
|
|
62
61
|
|
|
63
62
|
event.dispatcher.on(event.test.after, () => {
|
|
64
63
|
runAsyncHelpersHook('_after', {}, true)
|
|
65
|
-
recorder.catchWithoutStop(
|
|
64
|
+
recorder.catchWithoutStop(e => output.error(e))
|
|
66
65
|
})
|
|
67
66
|
|
|
68
|
-
event.dispatcher.on(event.step.before,
|
|
67
|
+
event.dispatcher.on(event.step.before, step => {
|
|
69
68
|
runAsyncHelpersHook('_beforeStep', step)
|
|
70
69
|
})
|
|
71
70
|
|
|
72
|
-
event.dispatcher.on(event.step.after,
|
|
71
|
+
event.dispatcher.on(event.step.after, step => {
|
|
73
72
|
runAsyncHelpersHook('_afterStep', step)
|
|
74
73
|
})
|
|
75
74
|
|
|
76
75
|
event.dispatcher.on(event.all.result, () => {
|
|
77
|
-
|
|
76
|
+
// Skip _finishTest for all helpers if any browser helper restarts to avoid double cleanup
|
|
77
|
+
const hasBrowserRestart = Object.values(helpers).some(helper => (helper.config && helper.config.restart) || (helper.options && helper.options.restart === 'context'))
|
|
78
|
+
|
|
79
|
+
Object.keys(helpers).forEach(key => {
|
|
80
|
+
const helper = helpers[key]
|
|
81
|
+
if (helper._finishTest && !hasBrowserRestart) {
|
|
82
|
+
recorder.add(`hook ${key}._finishTest()`, () => helper._finishTest(), true, false)
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
event.dispatcher.on(event.all.after, () => {
|
|
88
|
+
// Skip _cleanup for all helpers if any browser helper restarts to avoid double cleanup
|
|
89
|
+
const hasBrowserRestart = Object.values(helpers).some(helper => (helper.config && helper.config.restart) || (helper.options && helper.options.restart === 'context'))
|
|
90
|
+
|
|
91
|
+
Object.keys(helpers).forEach(key => {
|
|
92
|
+
const helper = helpers[key]
|
|
93
|
+
if (helper._cleanup && !hasBrowserRestart) {
|
|
94
|
+
recorder.add(`hook ${key}._cleanup()`, () => helper._cleanup(), true, false)
|
|
95
|
+
}
|
|
96
|
+
})
|
|
78
97
|
})
|
|
79
98
|
}
|
package/lib/listener/mocha.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
const container = require('../container')
|
|
1
|
+
import event from '../event.js'
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
export default function () {
|
|
5
4
|
let mocha
|
|
6
5
|
|
|
7
6
|
event.dispatcher.on(event.all.before, () => {
|
|
8
|
-
mocha = container.mocha()
|
|
7
|
+
mocha = global.container.mocha()
|
|
9
8
|
})
|
|
10
9
|
|
|
11
|
-
event.dispatcher.on(event.test.passed,
|
|
10
|
+
event.dispatcher.on(event.test.passed, test => {
|
|
12
11
|
mocha.Runner.emit('pass', test)
|
|
13
12
|
})
|
|
14
13
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import event from '../event.js'
|
|
2
|
+
|
|
3
|
+
export default function () {
|
|
4
|
+
event.dispatcher.on(event.hook.failed, err => {
|
|
5
|
+
global.container.result().addStats({ failedHooks: 1 })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
event.dispatcher.on(event.test.before, test => {
|
|
9
|
+
global.container.result().addTest(test)
|
|
10
|
+
})
|
|
11
|
+
}
|
package/lib/listener/steps.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import debugModule from 'debug'
|
|
2
|
+
const debug = debugModule('codeceptjs:steps')
|
|
3
|
+
import event from '../event.js'
|
|
4
|
+
import store from '../store.js'
|
|
5
|
+
import output from '../output.js'
|
|
6
|
+
import { BeforeHook, AfterHook, BeforeSuiteHook, AfterSuiteHook } from '../mocha/hooks.js'
|
|
5
7
|
|
|
6
8
|
let currentTest
|
|
7
9
|
let currentHook
|
|
@@ -9,40 +11,43 @@ let currentHook
|
|
|
9
11
|
/**
|
|
10
12
|
* Register steps inside tests
|
|
11
13
|
*/
|
|
12
|
-
|
|
13
|
-
event.dispatcher.on(event.test.before,
|
|
14
|
+
export default function () {
|
|
15
|
+
event.dispatcher.on(event.test.before, test => {
|
|
14
16
|
test.startedAt = +new Date()
|
|
15
|
-
test.artifacts = {}
|
|
16
17
|
})
|
|
17
18
|
|
|
18
|
-
event.dispatcher.on(event.test.started,
|
|
19
|
+
event.dispatcher.on(event.test.started, test => {
|
|
19
20
|
currentTest = test
|
|
20
21
|
currentTest.steps = []
|
|
21
22
|
if (!('retryNum' in currentTest)) currentTest.retryNum = 0
|
|
22
23
|
else currentTest.retryNum += 1
|
|
24
|
+
output.scenario.started(test)
|
|
23
25
|
})
|
|
24
26
|
|
|
25
|
-
event.dispatcher.on(event.test.after,
|
|
27
|
+
event.dispatcher.on(event.test.after, test => {
|
|
26
28
|
currentTest = null
|
|
27
29
|
})
|
|
28
30
|
|
|
29
|
-
event.dispatcher.on(event.test.finished,
|
|
31
|
+
event.dispatcher.on(event.test.finished, test => {})
|
|
30
32
|
|
|
31
|
-
event.dispatcher.on(event.hook.started,
|
|
32
|
-
currentHook =
|
|
33
|
+
event.dispatcher.on(event.hook.started, hook => {
|
|
34
|
+
currentHook = hook.ctx.test
|
|
33
35
|
currentHook.steps = []
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
output.hook.started(hook)
|
|
38
|
+
|
|
39
|
+
if (hook.ctx && hook.ctx.test) debug(`--- STARTED ${hook.ctx.test.title} ---`)
|
|
36
40
|
})
|
|
37
41
|
|
|
38
|
-
event.dispatcher.on(event.hook.passed,
|
|
42
|
+
event.dispatcher.on(event.hook.passed, hook => {
|
|
39
43
|
currentHook = null
|
|
40
|
-
|
|
44
|
+
output.hook.passed(hook)
|
|
45
|
+
if (hook.ctx && hook.ctx.test) debug(`--- ENDED ${hook.ctx.test.title} ---`)
|
|
41
46
|
})
|
|
42
47
|
|
|
43
48
|
event.dispatcher.on(event.test.failed, () => {
|
|
44
49
|
const cutSteps = function (current) {
|
|
45
|
-
const failureIndex = current.steps.findIndex(
|
|
50
|
+
const failureIndex = current.steps.findIndex(el => el.status === 'failed')
|
|
46
51
|
// To be sure that failed test will be failed in report
|
|
47
52
|
current.state = 'failed'
|
|
48
53
|
current.steps.length = failureIndex + 1
|
|
@@ -65,9 +70,8 @@ module.exports = function () {
|
|
|
65
70
|
currentTest.state = 'passed'
|
|
66
71
|
})
|
|
67
72
|
|
|
68
|
-
event.dispatcher.on(event.step.started,
|
|
69
|
-
|
|
70
|
-
step.test = currentTest
|
|
73
|
+
event.dispatcher.on(event.step.started, step => {
|
|
74
|
+
store.currentStep = step
|
|
71
75
|
if (currentHook && Array.isArray(currentHook.steps)) {
|
|
72
76
|
return currentHook.steps.push(step)
|
|
73
77
|
}
|
|
@@ -75,9 +79,8 @@ module.exports = function () {
|
|
|
75
79
|
currentTest.steps.push(step)
|
|
76
80
|
})
|
|
77
81
|
|
|
78
|
-
event.dispatcher.on(event.step.finished,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
debug(`Step '${step}' finished; Duration: ${step.duration || 0}ms`)
|
|
82
|
+
event.dispatcher.on(event.step.finished, step => {
|
|
83
|
+
store.currentStep = null
|
|
84
|
+
store.stepOptions = null
|
|
82
85
|
})
|
|
83
86
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import event from '../event.js'
|
|
2
|
+
import store from '../store.js'
|
|
3
|
+
|
|
4
|
+
export default function () {
|
|
5
|
+
event.dispatcher.on(event.suite.before, suite => {
|
|
6
|
+
store.currentSuite = suite
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
event.dispatcher.on(event.suite.after, () => {
|
|
10
|
+
store.currentSuite = null
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
event.dispatcher.on(event.test.before, test => {
|
|
14
|
+
store.currentTest = test
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
event.dispatcher.on(event.test.finished, () => {
|
|
18
|
+
store.currentTest = null
|
|
19
|
+
})
|
|
20
|
+
}
|