codeceptjs 3.6.4-beta.2 → 3.6.5-beta.1
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/bin/codecept.js +84 -63
- package/lib/ai.js +47 -1
- package/lib/assert/empty.js +19 -19
- package/lib/assert/equal.js +32 -30
- package/lib/assert/error.js +14 -14
- package/lib/assert/include.js +42 -42
- package/lib/assert/throws.js +13 -11
- package/lib/assert/truth.js +17 -18
- package/lib/command/configMigrate.js +57 -52
- package/lib/command/definitions.js +88 -88
- package/lib/command/dryRun.js +65 -63
- package/lib/command/generate.js +191 -181
- package/lib/command/info.js +39 -37
- package/lib/command/init.js +289 -286
- package/lib/command/interactive.js +32 -32
- package/lib/command/list.js +26 -26
- package/lib/command/run-multiple.js +113 -93
- package/lib/command/run-rerun.js +22 -22
- package/lib/command/run-workers.js +63 -63
- package/lib/command/run.js +24 -26
- package/lib/command/utils.js +64 -63
- package/lib/data/context.js +60 -60
- package/lib/data/dataScenarioConfig.js +47 -47
- package/lib/data/dataTableArgument.js +29 -29
- package/lib/data/table.js +26 -20
- package/lib/helper/AI.js +114 -35
- package/lib/helper/ApiDataFactory.js +72 -69
- package/lib/helper/Appium.js +409 -379
- package/lib/helper/ExpectHelper.js +214 -248
- package/lib/helper/FileSystem.js +77 -78
- package/lib/helper/GraphQL.js +44 -43
- package/lib/helper/GraphQLDataFactory.js +49 -50
- package/lib/helper/JSONResponse.js +64 -62
- package/lib/helper/Mochawesome.js +28 -28
- package/lib/helper/MockServer.js +12 -12
- package/lib/helper/Nightmare.js +664 -572
- package/lib/helper/Playwright.js +1320 -1211
- package/lib/helper/Protractor.js +663 -629
- package/lib/helper/Puppeteer.js +1232 -1124
- package/lib/helper/REST.js +115 -69
- package/lib/helper/TestCafe.js +490 -491
- package/lib/helper/WebDriver.js +1294 -1156
- package/lib/history.js +16 -3
- package/lib/interfaces/bdd.js +38 -51
- package/lib/interfaces/featureConfig.js +19 -19
- package/lib/interfaces/gherkin.js +122 -111
- package/lib/interfaces/scenarioConfig.js +29 -29
- package/lib/listener/artifacts.js +9 -9
- package/lib/listener/config.js +24 -23
- package/lib/listener/exit.js +12 -12
- package/lib/listener/helpers.js +42 -42
- package/lib/listener/mocha.js +11 -11
- package/lib/listener/retry.js +32 -30
- package/lib/listener/steps.js +50 -51
- package/lib/listener/timeout.js +53 -53
- package/lib/pause.js +17 -3
- package/lib/plugin/allure.js +14 -14
- package/lib/plugin/autoDelay.js +29 -36
- package/lib/plugin/autoLogin.js +70 -66
- package/lib/plugin/commentStep.js +18 -18
- package/lib/plugin/coverage.js +92 -77
- package/lib/plugin/customLocator.js +20 -19
- package/lib/plugin/debugErrors.js +24 -24
- package/lib/plugin/eachElement.js +37 -37
- package/lib/plugin/fakerTransform.js +6 -6
- package/lib/plugin/heal.js +66 -63
- package/lib/plugin/pauseOnFail.js +10 -10
- package/lib/plugin/retryFailedStep.js +31 -38
- package/lib/plugin/retryTo.js +28 -28
- package/lib/plugin/screenshotOnFail.js +107 -86
- package/lib/plugin/selenoid.js +131 -117
- package/lib/plugin/standardActingHelpers.js +2 -8
- package/lib/plugin/stepByStepReport.js +102 -92
- package/lib/plugin/stepTimeout.js +23 -22
- package/lib/plugin/subtitles.js +34 -34
- package/lib/plugin/tryTo.js +39 -29
- package/lib/plugin/wdio.js +77 -72
- package/lib/template/heal.js +11 -14
- package/package.json +5 -3
- package/translations/de-DE.js +1 -1
- package/translations/fr-FR.js +1 -1
- package/translations/index.js +9 -9
- package/translations/it-IT.js +1 -1
- package/translations/ja-JP.js +1 -1
- package/translations/pl-PL.js +1 -1
- package/translations/pt-BR.js +1 -1
- package/translations/ru-RU.js +1 -1
- package/translations/zh-CN.js +1 -1
- package/translations/zh-TW.js +1 -1
- package/typings/index.d.ts +42 -19
- package/typings/promiseBasedTypes.d.ts +280 -1
- package/typings/types.d.ts +76 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** @class */
|
|
2
2
|
class ScenarioConfig {
|
|
3
3
|
constructor(test) {
|
|
4
|
-
this.test = test
|
|
4
|
+
this.test = test
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -12,8 +12,8 @@ class ScenarioConfig {
|
|
|
12
12
|
* @returns {this}
|
|
13
13
|
*/
|
|
14
14
|
throws(err) {
|
|
15
|
-
this.test.throws = err
|
|
16
|
-
return this
|
|
15
|
+
this.test.throws = err
|
|
16
|
+
return this
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -24,8 +24,8 @@ class ScenarioConfig {
|
|
|
24
24
|
* @returns {this}
|
|
25
25
|
*/
|
|
26
26
|
fails() {
|
|
27
|
-
this.test.throws = new Error()
|
|
28
|
-
return this
|
|
27
|
+
this.test.throws = new Error()
|
|
28
|
+
return this
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -35,9 +35,9 @@ class ScenarioConfig {
|
|
|
35
35
|
* @returns {this}
|
|
36
36
|
*/
|
|
37
37
|
retry(retries) {
|
|
38
|
-
if (process.env.SCENARIO_ONLY) retries = -retries
|
|
39
|
-
this.test.retries(retries)
|
|
40
|
-
return this
|
|
38
|
+
if (process.env.SCENARIO_ONLY) retries = -retries
|
|
39
|
+
this.test.retries(retries)
|
|
40
|
+
return this
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -46,12 +46,12 @@ class ScenarioConfig {
|
|
|
46
46
|
* @returns {this}
|
|
47
47
|
*/
|
|
48
48
|
timeout(timeout) {
|
|
49
|
-
console.log(`Scenario('${this.test.title}', () => {}).timeout(${timeout}) is deprecated!`)
|
|
50
|
-
console.log(`Please use Scenario('${this.test.title}', { timeout: ${timeout / 1000} }, () => {}) instead`)
|
|
51
|
-
console.log('Timeout should be set in seconds')
|
|
49
|
+
console.log(`Scenario('${this.test.title}', () => {}).timeout(${timeout}) is deprecated!`)
|
|
50
|
+
console.log(`Please use Scenario('${this.test.title}', { timeout: ${timeout / 1000} }, () => {}) instead`)
|
|
51
|
+
console.log('Timeout should be set in seconds')
|
|
52
52
|
|
|
53
|
-
this.test.timeout(timeout)
|
|
54
|
-
return this
|
|
53
|
+
this.test.timeout(timeout)
|
|
54
|
+
return this
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -60,8 +60,8 @@ class ScenarioConfig {
|
|
|
60
60
|
* @returns {this}
|
|
61
61
|
*/
|
|
62
62
|
inject(obj) {
|
|
63
|
-
this.test.inject = obj
|
|
64
|
-
return this
|
|
63
|
+
this.test.inject = obj
|
|
64
|
+
return this
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
@@ -73,17 +73,17 @@ class ScenarioConfig {
|
|
|
73
73
|
*/
|
|
74
74
|
async config(helper, obj) {
|
|
75
75
|
if (!obj) {
|
|
76
|
-
obj = helper
|
|
77
|
-
helper = 0
|
|
76
|
+
obj = helper
|
|
77
|
+
helper = 0
|
|
78
78
|
}
|
|
79
79
|
if (typeof obj === 'function') {
|
|
80
|
-
obj = await obj(this.test)
|
|
80
|
+
obj = await obj(this.test)
|
|
81
81
|
}
|
|
82
82
|
if (!this.test.config) {
|
|
83
|
-
this.test.config = {}
|
|
83
|
+
this.test.config = {}
|
|
84
84
|
}
|
|
85
|
-
this.test.config[helper] = obj
|
|
86
|
-
return this
|
|
85
|
+
this.test.config[helper] = obj
|
|
86
|
+
return this
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -92,10 +92,10 @@ class ScenarioConfig {
|
|
|
92
92
|
* @returns {this}
|
|
93
93
|
*/
|
|
94
94
|
tag(tagName) {
|
|
95
|
-
if (tagName[0] !== '@') tagName = `@${tagName}
|
|
96
|
-
this.test.tags.push(tagName)
|
|
97
|
-
this.test.title = `${this.test.title.trim()} ${tagName}
|
|
98
|
-
return this
|
|
95
|
+
if (tagName[0] !== '@') tagName = `@${tagName}`
|
|
96
|
+
this.test.tags.push(tagName)
|
|
97
|
+
this.test.title = `${this.test.title.trim()} ${tagName}`
|
|
98
|
+
return this
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -105,10 +105,10 @@ class ScenarioConfig {
|
|
|
105
105
|
*/
|
|
106
106
|
injectDependencies(dependencies) {
|
|
107
107
|
Object.keys(dependencies).forEach((key) => {
|
|
108
|
-
this.test.inject[key] = dependencies[key]
|
|
109
|
-
})
|
|
110
|
-
return this
|
|
108
|
+
this.test.inject[key] = dependencies[key]
|
|
109
|
+
})
|
|
110
|
+
return this
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
module.exports = ScenarioConfig
|
|
114
|
+
module.exports = ScenarioConfig
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const recorder = require('../recorder')
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const recorder = require('../recorder')
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create and clean up empty artifacts
|
|
6
6
|
*/
|
|
7
7
|
module.exports = function () {
|
|
8
8
|
event.dispatcher.on(event.test.before, (test) => {
|
|
9
|
-
test.artifacts = {}
|
|
10
|
-
})
|
|
9
|
+
test.artifacts = {}
|
|
10
|
+
})
|
|
11
11
|
|
|
12
12
|
event.dispatcher.on(event.test.after, (test) => {
|
|
13
13
|
recorder.add('clean up empty artifacts', () => {
|
|
14
|
-
for (const key in
|
|
15
|
-
if (!test.artifacts[key]) delete test.artifacts[key]
|
|
14
|
+
for (const key in test.artifacts || {}) {
|
|
15
|
+
if (!test.artifacts[key]) delete test.artifacts[key]
|
|
16
16
|
}
|
|
17
|
-
})
|
|
18
|
-
})
|
|
19
|
-
}
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
}
|
package/lib/listener/config.js
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const container = require('../container')
|
|
3
|
-
const recorder = require('../recorder')
|
|
4
|
-
const { deepMerge, deepClone, ucfirst } = require('../utils')
|
|
5
|
-
const { debug } = require('../output')
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const container = require('../container')
|
|
3
|
+
const recorder = require('../recorder')
|
|
4
|
+
const { deepMerge, deepClone, ucfirst } = require('../utils')
|
|
5
|
+
const { debug } = require('../output')
|
|
6
6
|
/**
|
|
7
7
|
* Enable Helpers to listen to test events
|
|
8
8
|
*/
|
|
9
9
|
module.exports = function () {
|
|
10
|
-
const helpers = container.helpers()
|
|
10
|
+
const helpers = container.helpers()
|
|
11
11
|
|
|
12
|
-
enableDynamicConfigFor('suite')
|
|
13
|
-
enableDynamicConfigFor('test')
|
|
12
|
+
enableDynamicConfigFor('suite')
|
|
13
|
+
enableDynamicConfigFor('test')
|
|
14
14
|
|
|
15
15
|
function enableDynamicConfigFor(type) {
|
|
16
16
|
event.dispatcher.on(event[type].before, (context = {}) => {
|
|
17
17
|
function updateHelperConfig(helper, config) {
|
|
18
|
-
const oldConfig = { ...helper.options }
|
|
18
|
+
const oldConfig = { ...helper.options }
|
|
19
19
|
try {
|
|
20
|
-
helper._setConfig(deepMerge(deepClone(oldConfig), config))
|
|
21
|
-
debug(`[${ucfirst(type)} Config] ${helper.constructor.name} ${JSON.stringify(config)}`)
|
|
20
|
+
helper._setConfig(deepMerge(deepClone(oldConfig), config))
|
|
21
|
+
debug(`[${ucfirst(type)} Config] ${helper.constructor.name} ${JSON.stringify(config)}`)
|
|
22
22
|
} catch (err) {
|
|
23
|
-
recorder.throw(err)
|
|
24
|
-
return
|
|
23
|
+
recorder.throw(err)
|
|
24
|
+
return
|
|
25
25
|
}
|
|
26
26
|
event.dispatcher.once(event[type].after, () => {
|
|
27
|
-
helper._setConfig(oldConfig)
|
|
28
|
-
debug(`[${ucfirst(type)} Config] Reverted for ${helper.constructor.name}`)
|
|
29
|
-
})
|
|
27
|
+
helper._setConfig(oldConfig)
|
|
28
|
+
debug(`[${ucfirst(type)} Config] Reverted for ${helper.constructor.name}`)
|
|
29
|
+
})
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
// change config
|
|
33
33
|
if (context.config) {
|
|
34
34
|
for (let name in context.config) {
|
|
35
|
-
const config = context.config[name]
|
|
36
|
-
if (name === '0') {
|
|
37
|
-
|
|
35
|
+
const config = context.config[name]
|
|
36
|
+
if (name === '0') {
|
|
37
|
+
// first helper
|
|
38
|
+
name = Object.keys(helpers)[0]
|
|
38
39
|
}
|
|
39
|
-
const helper = helpers[name]
|
|
40
|
-
updateHelperConfig(helper, config)
|
|
40
|
+
const helper = helpers[name]
|
|
41
|
+
updateHelperConfig(helper, config)
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
})
|
|
44
|
+
})
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|
package/lib/listener/exit.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
const event = require('../event')
|
|
1
|
+
const event = require('../event')
|
|
2
2
|
|
|
3
3
|
module.exports = function () {
|
|
4
|
-
let failedTests = []
|
|
4
|
+
let failedTests = []
|
|
5
5
|
|
|
6
6
|
event.dispatcher.on(event.test.failed, (testOrSuite) => {
|
|
7
7
|
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
|
|
8
8
|
// is a suite and not a test
|
|
9
|
-
const id = testOrSuite.uid || (testOrSuite.ctx && testOrSuite.ctx.test.uid) || 'empty'
|
|
10
|
-
failedTests.push(id)
|
|
11
|
-
})
|
|
9
|
+
const id = testOrSuite.uid || (testOrSuite.ctx && testOrSuite.ctx.test.uid) || 'empty'
|
|
10
|
+
failedTests.push(id)
|
|
11
|
+
})
|
|
12
12
|
|
|
13
13
|
// if test was successful after retries
|
|
14
14
|
event.dispatcher.on(event.test.passed, (testOrSuite) => {
|
|
15
15
|
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
|
|
16
16
|
// is a suite and not a test
|
|
17
|
-
const id = testOrSuite.uid || (testOrSuite.ctx && testOrSuite.ctx.test.uid) || 'empty'
|
|
18
|
-
failedTests = failedTests.filter(failed => id !== failed)
|
|
19
|
-
})
|
|
17
|
+
const id = testOrSuite.uid || (testOrSuite.ctx && testOrSuite.ctx.test.uid) || 'empty'
|
|
18
|
+
failedTests = failedTests.filter((failed) => id !== failed)
|
|
19
|
+
})
|
|
20
20
|
|
|
21
21
|
process.on('beforeExit', (code) => {
|
|
22
22
|
if (failedTests.length) {
|
|
23
|
-
code = 1
|
|
23
|
+
code = 1
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
if (code) {
|
|
27
|
-
process.exit(code)
|
|
27
|
+
process.exit(code)
|
|
28
28
|
}
|
|
29
|
-
})
|
|
30
|
-
}
|
|
29
|
+
})
|
|
30
|
+
}
|
package/lib/listener/helpers.js
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const event = require('../event')
|
|
3
|
-
const container = require('../container')
|
|
4
|
-
const recorder = require('../recorder')
|
|
5
|
-
const store = require('../store')
|
|
6
|
-
const { error } = require('../output')
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const event = require('../event')
|
|
3
|
+
const container = require('../container')
|
|
4
|
+
const recorder = require('../recorder')
|
|
5
|
+
const store = require('../store')
|
|
6
|
+
const { error } = require('../output')
|
|
7
7
|
/**
|
|
8
8
|
* Enable Helpers to listen to test events
|
|
9
9
|
*/
|
|
10
10
|
module.exports = function () {
|
|
11
|
-
const helpers = container.helpers()
|
|
11
|
+
const helpers = container.helpers()
|
|
12
12
|
|
|
13
13
|
const runHelpersHook = (hook, param) => {
|
|
14
|
-
if (store.dryRun) return
|
|
14
|
+
if (store.dryRun) return
|
|
15
15
|
Object.values(helpers).forEach((helper) => {
|
|
16
16
|
if (helper[hook]) {
|
|
17
|
-
helper[hook](param)
|
|
17
|
+
helper[hook](param)
|
|
18
18
|
}
|
|
19
|
-
})
|
|
20
|
-
}
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
21
|
|
|
22
22
|
const runAsyncHelpersHook = (hook, param, force) => {
|
|
23
|
-
if (store.dryRun) return
|
|
23
|
+
if (store.dryRun) return
|
|
24
24
|
Object.keys(helpers).forEach((key) => {
|
|
25
|
-
if (!helpers[key][hook]) return
|
|
26
|
-
recorder.add(`hook ${key}.${hook}()`, () => helpers[key][hook](param), force, false)
|
|
27
|
-
})
|
|
28
|
-
}
|
|
25
|
+
if (!helpers[key][hook]) return
|
|
26
|
+
recorder.add(`hook ${key}.${hook}()`, () => helpers[key][hook](param), force, false)
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
event.dispatcher.on(event.suite.before, (suite) => {
|
|
31
31
|
// if (suite.parent) return; // only for root suite
|
|
32
|
-
runAsyncHelpersHook('_beforeSuite', suite, true)
|
|
33
|
-
})
|
|
32
|
+
runAsyncHelpersHook('_beforeSuite', suite, true)
|
|
33
|
+
})
|
|
34
34
|
|
|
35
35
|
event.dispatcher.on(event.suite.after, (suite) => {
|
|
36
36
|
// if (suite.parent) return; // only for root suite
|
|
37
|
-
runAsyncHelpersHook('_afterSuite', suite, true)
|
|
38
|
-
})
|
|
37
|
+
runAsyncHelpersHook('_afterSuite', suite, true)
|
|
38
|
+
})
|
|
39
39
|
|
|
40
40
|
event.dispatcher.on(event.test.started, (test) => {
|
|
41
|
-
runHelpersHook('_test', test)
|
|
42
|
-
recorder.catch(e => error(e))
|
|
43
|
-
})
|
|
41
|
+
runHelpersHook('_test', test)
|
|
42
|
+
recorder.catch((e) => error(e))
|
|
43
|
+
})
|
|
44
44
|
|
|
45
45
|
event.dispatcher.on(event.test.before, (test) => {
|
|
46
46
|
// schedule config to revert changes
|
|
47
|
-
runAsyncHelpersHook('_before', test, true)
|
|
48
|
-
recorder.catchWithoutStop(e => error(e))
|
|
49
|
-
})
|
|
47
|
+
runAsyncHelpersHook('_before', test, true)
|
|
48
|
+
recorder.catchWithoutStop((e) => error(e))
|
|
49
|
+
})
|
|
50
50
|
|
|
51
51
|
event.dispatcher.on(event.test.passed, (test) => {
|
|
52
|
-
runAsyncHelpersHook('_passed', test, true)
|
|
52
|
+
runAsyncHelpersHook('_passed', test, true)
|
|
53
53
|
// should not fail test execution, so errors should be caught
|
|
54
|
-
recorder.catchWithoutStop(e => error(e))
|
|
55
|
-
})
|
|
54
|
+
recorder.catchWithoutStop((e) => error(e))
|
|
55
|
+
})
|
|
56
56
|
|
|
57
57
|
event.dispatcher.on(event.test.failed, (test) => {
|
|
58
|
-
runAsyncHelpersHook('_failed', test, true)
|
|
58
|
+
runAsyncHelpersHook('_failed', test, true)
|
|
59
59
|
// should not fail test execution, so errors should be caught
|
|
60
|
-
recorder.catchWithoutStop(e => error(e))
|
|
61
|
-
})
|
|
60
|
+
recorder.catchWithoutStop((e) => error(e))
|
|
61
|
+
})
|
|
62
62
|
|
|
63
63
|
event.dispatcher.on(event.test.after, () => {
|
|
64
|
-
runAsyncHelpersHook('_after', {}, true)
|
|
65
|
-
recorder.catchWithoutStop(e => error(e))
|
|
66
|
-
})
|
|
64
|
+
runAsyncHelpersHook('_after', {}, true)
|
|
65
|
+
recorder.catchWithoutStop((e) => error(e))
|
|
66
|
+
})
|
|
67
67
|
|
|
68
68
|
event.dispatcher.on(event.step.before, (step) => {
|
|
69
|
-
runAsyncHelpersHook('_beforeStep', step)
|
|
70
|
-
})
|
|
69
|
+
runAsyncHelpersHook('_beforeStep', step)
|
|
70
|
+
})
|
|
71
71
|
|
|
72
72
|
event.dispatcher.on(event.step.after, (step) => {
|
|
73
|
-
runAsyncHelpersHook('_afterStep', step)
|
|
74
|
-
})
|
|
73
|
+
runAsyncHelpersHook('_afterStep', step)
|
|
74
|
+
})
|
|
75
75
|
|
|
76
76
|
event.dispatcher.on(event.all.result, () => {
|
|
77
|
-
runAsyncHelpersHook('_finishTest', {}, true)
|
|
78
|
-
})
|
|
79
|
-
}
|
|
77
|
+
runAsyncHelpersHook('_finishTest', {}, true)
|
|
78
|
+
})
|
|
79
|
+
}
|
package/lib/listener/mocha.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const container = require('../container')
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const container = require('../container')
|
|
3
3
|
|
|
4
4
|
module.exports = function () {
|
|
5
|
-
let mocha
|
|
5
|
+
let mocha
|
|
6
6
|
|
|
7
7
|
event.dispatcher.on(event.all.before, () => {
|
|
8
|
-
mocha = container.mocha()
|
|
9
|
-
})
|
|
8
|
+
mocha = container.mocha()
|
|
9
|
+
})
|
|
10
10
|
|
|
11
11
|
event.dispatcher.on(event.test.passed, (test) => {
|
|
12
|
-
mocha.Runner.emit('pass', test)
|
|
13
|
-
})
|
|
12
|
+
mocha.Runner.emit('pass', test)
|
|
13
|
+
})
|
|
14
14
|
|
|
15
15
|
event.dispatcher.on(event.test.failed, (test, err) => {
|
|
16
|
-
test.state = 'failed'
|
|
17
|
-
mocha.Runner.emit('fail', test, err)
|
|
18
|
-
})
|
|
19
|
-
}
|
|
16
|
+
test.state = 'failed'
|
|
17
|
+
mocha.Runner.emit('fail', test, err)
|
|
18
|
+
})
|
|
19
|
+
}
|
package/lib/listener/retry.js
CHANGED
|
@@ -1,68 +1,70 @@
|
|
|
1
|
-
const event = require('../event')
|
|
2
|
-
const output = require('../output')
|
|
3
|
-
const Config = require('../config')
|
|
4
|
-
const { isNotSet } = require('../utils')
|
|
1
|
+
const event = require('../event')
|
|
2
|
+
const output = require('../output')
|
|
3
|
+
const Config = require('../config')
|
|
4
|
+
const { isNotSet } = require('../utils')
|
|
5
5
|
|
|
6
|
-
const hooks = ['Before', 'After', 'BeforeSuite', 'AfterSuite']
|
|
6
|
+
const hooks = ['Before', 'After', 'BeforeSuite', 'AfterSuite']
|
|
7
7
|
|
|
8
8
|
module.exports = function () {
|
|
9
9
|
event.dispatcher.on(event.suite.before, (suite) => {
|
|
10
|
-
let retryConfig = Config.get('retry')
|
|
11
|
-
if (!retryConfig) return
|
|
10
|
+
let retryConfig = Config.get('retry')
|
|
11
|
+
if (!retryConfig) return
|
|
12
12
|
|
|
13
13
|
if (Number.isInteger(+retryConfig)) {
|
|
14
14
|
// is number
|
|
15
|
-
const retryNum = +retryConfig
|
|
16
|
-
output.log(`Retries: ${retryNum}`)
|
|
17
|
-
suite.retries(retryNum)
|
|
18
|
-
return
|
|
15
|
+
const retryNum = +retryConfig
|
|
16
|
+
output.log(`Retries: ${retryNum}`)
|
|
17
|
+
suite.retries(retryNum)
|
|
18
|
+
return
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (!Array.isArray(retryConfig)) {
|
|
22
|
-
retryConfig = [retryConfig]
|
|
22
|
+
retryConfig = [retryConfig]
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
for (const config of retryConfig) {
|
|
26
26
|
if (config.grep) {
|
|
27
|
-
if (!suite.title.includes(config.grep)) continue
|
|
27
|
+
if (!suite.title.includes(config.grep)) continue
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
hooks
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
hooks
|
|
31
|
+
.filter((hook) => !!config[hook])
|
|
32
|
+
.forEach((hook) => {
|
|
33
|
+
if (isNotSet(suite.opts[`retry${hook}`])) suite.opts[`retry${hook}`] = config[hook]
|
|
34
|
+
})
|
|
33
35
|
|
|
34
36
|
if (config.Feature) {
|
|
35
|
-
if (isNotSet(suite.retries())) suite.retries(config.Feature)
|
|
37
|
+
if (isNotSet(suite.retries())) suite.retries(config.Feature)
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
output.log(`Retries: ${JSON.stringify(config)}`)
|
|
40
|
+
output.log(`Retries: ${JSON.stringify(config)}`)
|
|
39
41
|
}
|
|
40
|
-
})
|
|
42
|
+
})
|
|
41
43
|
|
|
42
44
|
event.dispatcher.on(event.test.before, (test) => {
|
|
43
|
-
let retryConfig = Config.get('retry')
|
|
44
|
-
if (!retryConfig) return
|
|
45
|
+
let retryConfig = Config.get('retry')
|
|
46
|
+
if (!retryConfig) return
|
|
45
47
|
|
|
46
48
|
if (Number.isInteger(+retryConfig)) {
|
|
47
|
-
if (test.retries() === -1) test.retries(retryConfig)
|
|
48
|
-
return
|
|
49
|
+
if (test.retries() === -1) test.retries(retryConfig)
|
|
50
|
+
return
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
if (!Array.isArray(retryConfig)) {
|
|
52
|
-
retryConfig = [retryConfig]
|
|
54
|
+
retryConfig = [retryConfig]
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
retryConfig = retryConfig.filter(config => !!config.Scenario)
|
|
57
|
+
retryConfig = retryConfig.filter((config) => !!config.Scenario)
|
|
56
58
|
|
|
57
59
|
for (const config of retryConfig) {
|
|
58
60
|
if (config.grep) {
|
|
59
|
-
if (!test.fullTitle().includes(config.grep)) continue
|
|
61
|
+
if (!test.fullTitle().includes(config.grep)) continue
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
if (config.Scenario) {
|
|
63
|
-
if (test.retries() === -1) test.retries(config.Scenario)
|
|
64
|
-
output.log(`Retries: ${config.Scenario}`)
|
|
65
|
+
if (test.retries() === -1) test.retries(config.Scenario)
|
|
66
|
+
output.log(`Retries: ${config.Scenario}`)
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
+
})
|
|
70
|
+
}
|
package/lib/listener/steps.js
CHANGED
|
@@ -1,84 +1,83 @@
|
|
|
1
|
-
const debug = require('debug')('codeceptjs:steps')
|
|
2
|
-
const event = require('../event')
|
|
3
|
-
const store = require('../store')
|
|
4
|
-
const output = require('../output')
|
|
1
|
+
const debug = require('debug')('codeceptjs:steps')
|
|
2
|
+
const event = require('../event')
|
|
3
|
+
const store = require('../store')
|
|
4
|
+
const output = require('../output')
|
|
5
5
|
|
|
6
|
-
let currentTest
|
|
7
|
-
let currentHook
|
|
6
|
+
let currentTest
|
|
7
|
+
let currentHook
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Register steps inside tests
|
|
11
11
|
*/
|
|
12
12
|
module.exports = function () {
|
|
13
13
|
event.dispatcher.on(event.test.before, (test) => {
|
|
14
|
-
test.startedAt = +new Date()
|
|
15
|
-
test.artifacts = {}
|
|
16
|
-
})
|
|
14
|
+
test.startedAt = +new Date()
|
|
15
|
+
test.artifacts = {}
|
|
16
|
+
})
|
|
17
17
|
|
|
18
18
|
event.dispatcher.on(event.test.started, (test) => {
|
|
19
|
-
currentTest = test
|
|
20
|
-
currentTest.steps = []
|
|
21
|
-
if (!('retryNum' in currentTest)) currentTest.retryNum = 0
|
|
22
|
-
else currentTest.retryNum += 1
|
|
23
|
-
})
|
|
19
|
+
currentTest = test
|
|
20
|
+
currentTest.steps = []
|
|
21
|
+
if (!('retryNum' in currentTest)) currentTest.retryNum = 0
|
|
22
|
+
else currentTest.retryNum += 1
|
|
23
|
+
})
|
|
24
24
|
|
|
25
25
|
event.dispatcher.on(event.test.after, (test) => {
|
|
26
|
-
currentTest = null
|
|
27
|
-
})
|
|
26
|
+
currentTest = null
|
|
27
|
+
})
|
|
28
28
|
|
|
29
|
-
event.dispatcher.on(event.test.finished, (test) => {
|
|
30
|
-
});
|
|
29
|
+
event.dispatcher.on(event.test.finished, (test) => {})
|
|
31
30
|
|
|
32
31
|
event.dispatcher.on(event.hook.started, (suite) => {
|
|
33
|
-
currentHook = suite.ctx.test
|
|
34
|
-
currentHook.steps = []
|
|
32
|
+
currentHook = suite.ctx.test
|
|
33
|
+
currentHook.steps = []
|
|
35
34
|
|
|
36
|
-
if (suite.ctx && suite.ctx.test) output.log(`--- STARTED ${suite.ctx.test.title} ---`)
|
|
37
|
-
})
|
|
35
|
+
if (suite.ctx && suite.ctx.test) output.log(`--- STARTED ${suite.ctx.test.title} ---`)
|
|
36
|
+
})
|
|
38
37
|
|
|
39
38
|
event.dispatcher.on(event.hook.passed, (suite) => {
|
|
40
|
-
currentHook = null
|
|
41
|
-
if (suite.ctx && suite.ctx.test) output.log(`--- ENDED ${suite.ctx.test.title} ---`)
|
|
42
|
-
})
|
|
39
|
+
currentHook = null
|
|
40
|
+
if (suite.ctx && suite.ctx.test) output.log(`--- ENDED ${suite.ctx.test.title} ---`)
|
|
41
|
+
})
|
|
43
42
|
|
|
44
43
|
event.dispatcher.on(event.test.failed, () => {
|
|
45
44
|
const cutSteps = function (current) {
|
|
46
|
-
const failureIndex = current.steps.findIndex(el => el.status === 'failed')
|
|
45
|
+
const failureIndex = current.steps.findIndex((el) => el.status === 'failed')
|
|
47
46
|
// To be sure that failed test will be failed in report
|
|
48
|
-
current.state = 'failed'
|
|
49
|
-
current.steps.length = failureIndex + 1
|
|
50
|
-
return current
|
|
51
|
-
}
|
|
47
|
+
current.state = 'failed'
|
|
48
|
+
current.steps.length = failureIndex + 1
|
|
49
|
+
return current
|
|
50
|
+
}
|
|
52
51
|
if (currentHook && Array.isArray(currentHook.steps) && currentHook.steps.length) {
|
|
53
|
-
currentHook = cutSteps(currentHook)
|
|
54
|
-
return currentHook = null
|
|
52
|
+
currentHook = cutSteps(currentHook)
|
|
53
|
+
return (currentHook = null)
|
|
55
54
|
}
|
|
56
|
-
if (!currentTest) return
|
|
55
|
+
if (!currentTest) return
|
|
57
56
|
// last step is failing step
|
|
58
|
-
if (!currentTest.steps.length) return
|
|
59
|
-
return currentTest = cutSteps(currentTest)
|
|
60
|
-
})
|
|
57
|
+
if (!currentTest.steps.length) return
|
|
58
|
+
return (currentTest = cutSteps(currentTest))
|
|
59
|
+
})
|
|
61
60
|
|
|
62
61
|
event.dispatcher.on(event.test.passed, () => {
|
|
63
|
-
if (!currentTest) return
|
|
62
|
+
if (!currentTest) return
|
|
64
63
|
// To be sure that passed test will be passed in report
|
|
65
|
-
delete currentTest.err
|
|
66
|
-
currentTest.state = 'passed'
|
|
67
|
-
})
|
|
64
|
+
delete currentTest.err
|
|
65
|
+
currentTest.state = 'passed'
|
|
66
|
+
})
|
|
68
67
|
|
|
69
68
|
event.dispatcher.on(event.step.started, (step) => {
|
|
70
|
-
step.startedAt = +new Date()
|
|
71
|
-
step.test = currentTest
|
|
69
|
+
step.startedAt = +new Date()
|
|
70
|
+
step.test = currentTest
|
|
72
71
|
if (currentHook && Array.isArray(currentHook.steps)) {
|
|
73
|
-
return currentHook.steps.push(step)
|
|
72
|
+
return currentHook.steps.push(step)
|
|
74
73
|
}
|
|
75
|
-
if (!currentTest || !currentTest.steps) return
|
|
76
|
-
currentTest.steps.push(step)
|
|
77
|
-
})
|
|
74
|
+
if (!currentTest || !currentTest.steps) return
|
|
75
|
+
currentTest.steps.push(step)
|
|
76
|
+
})
|
|
78
77
|
|
|
79
78
|
event.dispatcher.on(event.step.finished, (step) => {
|
|
80
|
-
step.finishedAt = +new Date()
|
|
81
|
-
if (step.startedAt) step.duration = step.finishedAt - step.startedAt
|
|
82
|
-
debug(`Step '${step}' finished; Duration: ${step.duration || 0}ms`)
|
|
83
|
-
})
|
|
84
|
-
}
|
|
79
|
+
step.finishedAt = +new Date()
|
|
80
|
+
if (step.startedAt) step.duration = step.finishedAt - step.startedAt
|
|
81
|
+
debug(`Step '${step}' finished; Duration: ${step.duration || 0}ms`)
|
|
82
|
+
})
|
|
83
|
+
}
|