codeceptjs 4.0.0-beta.3 → 4.0.0-beta.5

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.
Files changed (155) hide show
  1. package/README.md +134 -119
  2. package/bin/codecept.js +12 -2
  3. package/bin/test-server.js +53 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/lib/actor.js +66 -102
  6. package/lib/ai.js +130 -121
  7. package/lib/assert/empty.js +3 -5
  8. package/lib/assert/equal.js +4 -7
  9. package/lib/assert/include.js +4 -6
  10. package/lib/assert/throws.js +2 -4
  11. package/lib/assert/truth.js +2 -2
  12. package/lib/codecept.js +141 -86
  13. package/lib/command/check.js +201 -0
  14. package/lib/command/configMigrate.js +2 -4
  15. package/lib/command/definitions.js +8 -26
  16. package/lib/command/dryRun.js +30 -35
  17. package/lib/command/generate.js +10 -14
  18. package/lib/command/gherkin/snippets.js +75 -73
  19. package/lib/command/gherkin/steps.js +1 -1
  20. package/lib/command/info.js +42 -8
  21. package/lib/command/init.js +13 -12
  22. package/lib/command/interactive.js +10 -2
  23. package/lib/command/list.js +1 -1
  24. package/lib/command/run-multiple/chunk.js +48 -45
  25. package/lib/command/run-multiple.js +12 -35
  26. package/lib/command/run-workers.js +21 -58
  27. package/lib/command/utils.js +5 -6
  28. package/lib/command/workers/runTests.js +263 -222
  29. package/lib/container.js +386 -238
  30. package/lib/data/context.js +10 -13
  31. package/lib/data/dataScenarioConfig.js +8 -8
  32. package/lib/data/dataTableArgument.js +6 -6
  33. package/lib/data/table.js +5 -11
  34. package/lib/effects.js +223 -0
  35. package/lib/element/WebElement.js +327 -0
  36. package/lib/els.js +158 -0
  37. package/lib/event.js +21 -17
  38. package/lib/heal.js +88 -80
  39. package/lib/helper/AI.js +2 -1
  40. package/lib/helper/ApiDataFactory.js +4 -7
  41. package/lib/helper/Appium.js +50 -57
  42. package/lib/helper/FileSystem.js +3 -3
  43. package/lib/helper/GraphQLDataFactory.js +4 -4
  44. package/lib/helper/JSONResponse.js +75 -37
  45. package/lib/helper/Mochawesome.js +31 -9
  46. package/lib/helper/Nightmare.js +37 -58
  47. package/lib/helper/Playwright.js +267 -272
  48. package/lib/helper/Protractor.js +56 -87
  49. package/lib/helper/Puppeteer.js +247 -264
  50. package/lib/helper/REST.js +29 -17
  51. package/lib/helper/TestCafe.js +22 -47
  52. package/lib/helper/WebDriver.js +157 -368
  53. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  54. package/lib/helper/extras/Popup.js +22 -22
  55. package/lib/helper/network/utils.js +1 -1
  56. package/lib/helper/testcafe/testcafe-utils.js +27 -28
  57. package/lib/listener/emptyRun.js +55 -0
  58. package/lib/listener/exit.js +7 -10
  59. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  60. package/lib/listener/globalTimeout.js +165 -0
  61. package/lib/listener/helpers.js +15 -15
  62. package/lib/listener/mocha.js +1 -1
  63. package/lib/listener/result.js +12 -0
  64. package/lib/listener/retryEnhancer.js +85 -0
  65. package/lib/listener/steps.js +32 -18
  66. package/lib/listener/store.js +20 -0
  67. package/lib/locator.js +1 -1
  68. package/lib/mocha/asyncWrapper.js +231 -0
  69. package/lib/{interfaces → mocha}/bdd.js +3 -3
  70. package/lib/mocha/cli.js +308 -0
  71. package/lib/mocha/factory.js +104 -0
  72. package/lib/{interfaces → mocha}/featureConfig.js +32 -12
  73. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  74. package/lib/mocha/hooks.js +112 -0
  75. package/lib/mocha/index.js +12 -0
  76. package/lib/mocha/inject.js +29 -0
  77. package/lib/{interfaces → mocha}/scenarioConfig.js +31 -7
  78. package/lib/mocha/suite.js +82 -0
  79. package/lib/mocha/test.js +181 -0
  80. package/lib/mocha/types.d.ts +42 -0
  81. package/lib/mocha/ui.js +232 -0
  82. package/lib/output.js +93 -65
  83. package/lib/pause.js +160 -138
  84. package/lib/plugin/analyze.js +396 -0
  85. package/lib/plugin/auth.js +435 -0
  86. package/lib/plugin/autoDelay.js +8 -8
  87. package/lib/plugin/autoLogin.js +3 -338
  88. package/lib/plugin/commentStep.js +6 -1
  89. package/lib/plugin/coverage.js +10 -22
  90. package/lib/plugin/customLocator.js +3 -3
  91. package/lib/plugin/customReporter.js +52 -0
  92. package/lib/plugin/eachElement.js +1 -1
  93. package/lib/plugin/fakerTransform.js +1 -1
  94. package/lib/plugin/heal.js +36 -9
  95. package/lib/plugin/htmlReporter.js +1947 -0
  96. package/lib/plugin/pageInfo.js +140 -0
  97. package/lib/plugin/retryFailedStep.js +17 -18
  98. package/lib/plugin/retryTo.js +2 -113
  99. package/lib/plugin/screenshotOnFail.js +17 -58
  100. package/lib/plugin/selenoid.js +15 -35
  101. package/lib/plugin/standardActingHelpers.js +4 -1
  102. package/lib/plugin/stepByStepReport.js +56 -17
  103. package/lib/plugin/stepTimeout.js +5 -12
  104. package/lib/plugin/subtitles.js +4 -4
  105. package/lib/plugin/tryTo.js +3 -102
  106. package/lib/plugin/wdio.js +8 -10
  107. package/lib/recorder.js +155 -124
  108. package/lib/rerun.js +43 -42
  109. package/lib/result.js +161 -0
  110. package/lib/secret.js +1 -2
  111. package/lib/step/base.js +239 -0
  112. package/lib/step/comment.js +10 -0
  113. package/lib/step/config.js +50 -0
  114. package/lib/step/func.js +46 -0
  115. package/lib/step/helper.js +50 -0
  116. package/lib/step/meta.js +99 -0
  117. package/lib/step/record.js +74 -0
  118. package/lib/step/retry.js +11 -0
  119. package/lib/step/section.js +55 -0
  120. package/lib/step.js +21 -332
  121. package/lib/steps.js +50 -0
  122. package/lib/store.js +37 -5
  123. package/lib/template/heal.js +2 -11
  124. package/lib/test-server.js +323 -0
  125. package/lib/timeout.js +66 -0
  126. package/lib/utils.js +351 -218
  127. package/lib/within.js +75 -55
  128. package/lib/workerStorage.js +2 -1
  129. package/lib/workers.js +386 -277
  130. package/package.json +81 -75
  131. package/translations/de-DE.js +5 -3
  132. package/translations/fr-FR.js +5 -4
  133. package/translations/index.js +1 -0
  134. package/translations/it-IT.js +4 -3
  135. package/translations/ja-JP.js +4 -3
  136. package/translations/nl-NL.js +76 -0
  137. package/translations/pl-PL.js +4 -3
  138. package/translations/pt-BR.js +4 -3
  139. package/translations/ru-RU.js +4 -3
  140. package/translations/utils.js +9 -0
  141. package/translations/zh-CN.js +4 -3
  142. package/translations/zh-TW.js +4 -3
  143. package/typings/index.d.ts +197 -187
  144. package/typings/promiseBasedTypes.d.ts +53 -903
  145. package/typings/types.d.ts +372 -1042
  146. package/lib/cli.js +0 -257
  147. package/lib/helper/ExpectHelper.js +0 -391
  148. package/lib/helper/MockServer.js +0 -221
  149. package/lib/helper/SoftExpectHelper.js +0 -381
  150. package/lib/listener/artifacts.js +0 -19
  151. package/lib/listener/timeout.js +0 -109
  152. package/lib/mochaFactory.js +0 -113
  153. package/lib/plugin/debugErrors.js +0 -67
  154. package/lib/scenario.js +0 -224
  155. package/lib/ui.js +0 -236
@@ -0,0 +1,85 @@
1
+ const event = require('../event')
2
+ const { enhanceMochaTest } = require('../mocha/test')
3
+
4
+ /**
5
+ * Enhance retried tests by copying CodeceptJS-specific properties from the original test
6
+ * This fixes the issue where Mocha's shallow clone during retries loses CodeceptJS properties
7
+ */
8
+ module.exports = function () {
9
+ event.dispatcher.on(event.test.before, test => {
10
+ // Check if this test is a retry (has a reference to the original test)
11
+ const originalTest = test.retriedTest && test.retriedTest()
12
+
13
+ if (originalTest) {
14
+ // This is a retried test - copy CodeceptJS-specific properties from the original
15
+ copyCodeceptJSProperties(originalTest, test)
16
+
17
+ // Ensure the test is enhanced with CodeceptJS functionality
18
+ enhanceMochaTest(test)
19
+ }
20
+ })
21
+ }
22
+
23
+ /**
24
+ * Copy CodeceptJS-specific properties from the original test to the retried test
25
+ * @param {CodeceptJS.Test} originalTest - The original test object
26
+ * @param {CodeceptJS.Test} retriedTest - The retried test object
27
+ */
28
+ function copyCodeceptJSProperties(originalTest, retriedTest) {
29
+ // Copy CodeceptJS-specific properties
30
+ if (originalTest.opts !== undefined) {
31
+ retriedTest.opts = originalTest.opts ? { ...originalTest.opts } : {}
32
+ }
33
+
34
+ if (originalTest.tags !== undefined) {
35
+ retriedTest.tags = originalTest.tags ? [...originalTest.tags] : []
36
+ }
37
+
38
+ if (originalTest.notes !== undefined) {
39
+ retriedTest.notes = originalTest.notes ? [...originalTest.notes] : []
40
+ }
41
+
42
+ if (originalTest.meta !== undefined) {
43
+ retriedTest.meta = originalTest.meta ? { ...originalTest.meta } : {}
44
+ }
45
+
46
+ if (originalTest.artifacts !== undefined) {
47
+ retriedTest.artifacts = originalTest.artifacts ? [...originalTest.artifacts] : []
48
+ }
49
+
50
+ if (originalTest.steps !== undefined) {
51
+ retriedTest.steps = originalTest.steps ? [...originalTest.steps] : []
52
+ }
53
+
54
+ if (originalTest.config !== undefined) {
55
+ retriedTest.config = originalTest.config ? { ...originalTest.config } : {}
56
+ }
57
+
58
+ if (originalTest.inject !== undefined) {
59
+ retriedTest.inject = originalTest.inject ? { ...originalTest.inject } : {}
60
+ }
61
+
62
+ // Copy methods that might be missing
63
+ if (originalTest.addNote && !retriedTest.addNote) {
64
+ retriedTest.addNote = function (type, note) {
65
+ this.notes = this.notes || []
66
+ this.notes.push({ type, text: note })
67
+ }
68
+ }
69
+
70
+ if (originalTest.applyOptions && !retriedTest.applyOptions) {
71
+ retriedTest.applyOptions = originalTest.applyOptions.bind(retriedTest)
72
+ }
73
+
74
+ if (originalTest.simplify && !retriedTest.simplify) {
75
+ retriedTest.simplify = originalTest.simplify.bind(retriedTest)
76
+ }
77
+
78
+ // Preserve the uid if it exists
79
+ if (originalTest.uid !== undefined) {
80
+ retriedTest.uid = originalTest.uid
81
+ }
82
+
83
+ // Mark as enhanced
84
+ retriedTest.codeceptjs = true
85
+ }
@@ -2,47 +2,55 @@ const debug = require('debug')('codeceptjs:steps')
2
2
  const event = require('../event')
3
3
  const store = require('../store')
4
4
  const output = require('../output')
5
+ const { BeforeHook, AfterHook, BeforeSuiteHook, AfterSuiteHook } = require('../mocha/hooks')
6
+ const recorder = require('../recorder')
5
7
 
6
8
  let currentTest
7
9
  let currentHook
8
10
 
11
+ // Session names that should not contribute steps to the main test trace
12
+ const EXCLUDED_SESSIONS = ['tryTo', 'hopeThat']
13
+
9
14
  /**
10
15
  * Register steps inside tests
11
16
  */
12
17
  module.exports = function () {
13
- event.dispatcher.on(event.test.before, (test) => {
18
+ event.dispatcher.on(event.test.before, test => {
14
19
  test.startedAt = +new Date()
15
- test.artifacts = {}
16
20
  })
17
21
 
18
- event.dispatcher.on(event.test.started, (test) => {
22
+ event.dispatcher.on(event.test.started, test => {
19
23
  currentTest = test
20
24
  currentTest.steps = []
21
25
  if (!('retryNum' in currentTest)) currentTest.retryNum = 0
22
26
  else currentTest.retryNum += 1
27
+ output.scenario.started(test)
23
28
  })
24
29
 
25
- event.dispatcher.on(event.test.after, (test) => {
30
+ event.dispatcher.on(event.test.after, test => {
26
31
  currentTest = null
27
32
  })
28
33
 
29
- event.dispatcher.on(event.test.finished, (test) => {})
34
+ event.dispatcher.on(event.test.finished, test => {})
30
35
 
31
- event.dispatcher.on(event.hook.started, (suite) => {
32
- currentHook = suite.ctx.test
36
+ event.dispatcher.on(event.hook.started, hook => {
37
+ currentHook = hook.ctx.test
33
38
  currentHook.steps = []
34
39
 
35
- if (suite.ctx && suite.ctx.test) output.log(`--- STARTED ${suite.ctx.test.title} ---`)
40
+ output.hook.started(hook)
41
+
42
+ if (hook.ctx && hook.ctx.test) debug(`--- STARTED ${hook.ctx.test.title} ---`)
36
43
  })
37
44
 
38
- event.dispatcher.on(event.hook.passed, (suite) => {
45
+ event.dispatcher.on(event.hook.passed, hook => {
39
46
  currentHook = null
40
- if (suite.ctx && suite.ctx.test) output.log(`--- ENDED ${suite.ctx.test.title} ---`)
47
+ output.hook.passed(hook)
48
+ if (hook.ctx && hook.ctx.test) debug(`--- ENDED ${hook.ctx.test.title} ---`)
41
49
  })
42
50
 
43
51
  event.dispatcher.on(event.test.failed, () => {
44
52
  const cutSteps = function (current) {
45
- const failureIndex = current.steps.findIndex((el) => el.status === 'failed')
53
+ const failureIndex = current.steps.findIndex(el => el.status === 'failed')
46
54
  // To be sure that failed test will be failed in report
47
55
  current.state = 'failed'
48
56
  current.steps.length = failureIndex + 1
@@ -65,19 +73,25 @@ module.exports = function () {
65
73
  currentTest.state = 'passed'
66
74
  })
67
75
 
68
- event.dispatcher.on(event.step.started, (step) => {
69
- step.startedAt = +new Date()
70
- step.test = currentTest
76
+ event.dispatcher.on(event.step.started, step => {
77
+ store.currentStep = step
71
78
  if (currentHook && Array.isArray(currentHook.steps)) {
72
79
  return currentHook.steps.push(step)
73
80
  }
74
81
  if (!currentTest || !currentTest.steps) return
82
+
83
+ // Check if we're in a session that should be excluded from main test steps
84
+ const currentSessionId = recorder.getCurrentSessionId()
85
+ if (currentSessionId && EXCLUDED_SESSIONS.includes(currentSessionId)) {
86
+ // Skip adding this step to the main test steps
87
+ return
88
+ }
89
+
75
90
  currentTest.steps.push(step)
76
91
  })
77
92
 
78
- event.dispatcher.on(event.step.finished, (step) => {
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`)
93
+ event.dispatcher.on(event.step.finished, step => {
94
+ store.currentStep = null
95
+ store.stepOptions = null
82
96
  })
83
97
  }
@@ -0,0 +1,20 @@
1
+ const event = require('../event')
2
+ const store = require('../store')
3
+
4
+ module.exports = 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
+ }
package/lib/locator.js CHANGED
@@ -389,7 +389,7 @@ class Locator {
389
389
  }
390
390
 
391
391
  /**
392
- * @param {CodeceptJS.LocatorOrString} locator
392
+ * @param {CodeceptJS.LocatorOrString} [locator]
393
393
  * @returns {Locator}
394
394
  */
395
395
  Locator.build = (locator) => {
@@ -0,0 +1,231 @@
1
+ const promiseRetry = require('promise-retry')
2
+ const event = require('../event')
3
+ const recorder = require('../recorder')
4
+ const assertThrown = require('../assert/throws')
5
+ const { ucfirst, isAsyncFunction } = require('../utils')
6
+ const { getInjectedArguments } = require('./inject')
7
+ const { fireHook } = require('./hooks')
8
+
9
+ const injectHook = function (inject, suite) {
10
+ try {
11
+ inject()
12
+ } catch (err) {
13
+ recorder.throw(err)
14
+ }
15
+ recorder.catch(err => {
16
+ suiteTestFailedHookError(suite, err)
17
+ throw err
18
+ })
19
+ return recorder.promise()
20
+ }
21
+
22
+ function suiteTestFailedHookError(suite, err, hookName) {
23
+ suite.eachTest(test => {
24
+ test.err = err
25
+ if (hookName) hookName = ucfirst(hookName)
26
+ event.emit(event.test.failed, test, err, hookName)
27
+ })
28
+ }
29
+
30
+ function makeDoneCallableOnce(done) {
31
+ let called = false
32
+ return function (err) {
33
+ if (called) {
34
+ return
35
+ }
36
+ called = true
37
+ return done(err)
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Wraps test function, injects support objects from container,
43
+ * starts promise chain with recorder, performs before/after hooks
44
+ * through event system.
45
+ */
46
+ module.exports.test = test => {
47
+ const testFn = test.fn
48
+ if (!testFn) {
49
+ return test
50
+ }
51
+
52
+ test.timeout(0)
53
+ test.async = true
54
+
55
+ test.fn = function (done) {
56
+ const doneFn = makeDoneCallableOnce(done)
57
+ recorder.errHandler(err => {
58
+ recorder.session.start('teardown')
59
+ recorder.cleanAsyncErr()
60
+ if (test.throws) {
61
+ // check that test should actually fail
62
+ try {
63
+ assertThrown(err, test.throws)
64
+ event.emit(event.test.passed, test)
65
+ event.emit(event.test.finished, test)
66
+ recorder.add(doneFn)
67
+ return
68
+ } catch (newErr) {
69
+ err = newErr
70
+ }
71
+ }
72
+ test.err = err
73
+ event.emit(event.test.failed, test, err)
74
+ event.emit(event.test.finished, test)
75
+ recorder.add(() => doneFn(err))
76
+ })
77
+
78
+ if (isAsyncFunction(testFn)) {
79
+ event.emit(event.test.started, test)
80
+ testFn
81
+ .call(test, getInjectedArguments(testFn, test))
82
+ .then(() => {
83
+ recorder.add('fire test.passed', () => {
84
+ event.emit(event.test.passed, test)
85
+ event.emit(event.test.finished, test)
86
+ })
87
+ recorder.add('finish test', doneFn)
88
+ })
89
+ .catch(err => {
90
+ recorder.throw(err)
91
+ })
92
+ .finally(() => {
93
+ recorder.catch()
94
+ })
95
+ return
96
+ }
97
+
98
+ try {
99
+ event.emit(event.test.started, test)
100
+ testFn.call(test, getInjectedArguments(testFn, test))
101
+ } catch (err) {
102
+ recorder.throw(err)
103
+ } finally {
104
+ recorder.add('fire test.passed', () => {
105
+ event.emit(event.test.passed, test)
106
+ event.emit(event.test.finished, test)
107
+ })
108
+ recorder.add('finish test', doneFn)
109
+ recorder.catch()
110
+ }
111
+ }
112
+ return test
113
+ }
114
+
115
+ /**
116
+ * Injects arguments to function from controller
117
+ */
118
+ module.exports.injected = function (fn, suite, hookName) {
119
+ return function (done) {
120
+ const doneFn = makeDoneCallableOnce(done)
121
+ const errHandler = err => {
122
+ recorder.session.start('teardown')
123
+ recorder.cleanAsyncErr()
124
+ if (['before', 'beforeSuite'].includes(hookName)) {
125
+ suiteTestFailedHookError(suite, err, hookName)
126
+ }
127
+ if (hookName === 'after') {
128
+ suiteTestFailedHookError(suite, err, hookName)
129
+ suite.eachTest(test => {
130
+ event.emit(event.test.after, test)
131
+ })
132
+ }
133
+ if (hookName === 'afterSuite') {
134
+ suiteTestFailedHookError(suite, err, hookName)
135
+ event.emit(event.suite.after, suite)
136
+ }
137
+ recorder.add(() => doneFn(err))
138
+ }
139
+
140
+ recorder.errHandler(err => {
141
+ errHandler(err)
142
+ })
143
+
144
+ if (!fn) throw new Error('fn is not defined')
145
+
146
+ fireHook(event.hook.started, suite)
147
+
148
+ this.test.body = fn.toString()
149
+
150
+ if (!recorder.isRunning()) {
151
+ recorder.errHandler(err => {
152
+ errHandler(err)
153
+ })
154
+ }
155
+
156
+ const opts = suite.opts || {}
157
+ const retries = opts[`retry${ucfirst(hookName)}`] || 0
158
+
159
+ const currentTest = hookName === 'before' || hookName === 'after' ? suite?.ctx?.currentTest : null
160
+
161
+ promiseRetry(
162
+ async (retry, number) => {
163
+ try {
164
+ recorder.startUnlessRunning()
165
+ await fn.call(this, { ...getInjectedArguments(fn), suite, test: currentTest })
166
+ await recorder.promise().catch(err => retry(err))
167
+ } catch (err) {
168
+ retry(err)
169
+ } finally {
170
+ if (number < retries) {
171
+ recorder.stop()
172
+ recorder.start()
173
+ }
174
+ }
175
+ },
176
+ { retries },
177
+ )
178
+ .then(() => {
179
+ recorder.add('fire hook.passed', () => fireHook(event.hook.passed, suite))
180
+ recorder.add('fire hook.finished', () => fireHook(event.hook.finished, suite))
181
+ recorder.add(`finish ${hookName} hook`, doneFn)
182
+ recorder.catch()
183
+ })
184
+ .catch(e => {
185
+ recorder.throw(e)
186
+ recorder.catch(e => {
187
+ const err = recorder.getAsyncErr() === null ? e : recorder.getAsyncErr()
188
+ errHandler(err)
189
+ })
190
+ recorder.add('fire hook.failed', () => fireHook(event.hook.failed, suite, e))
191
+ recorder.add('fire hook.finished', () => fireHook(event.hook.finished, suite))
192
+ })
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Starts promise chain, so helpers could enqueue their hooks
198
+ */
199
+ module.exports.setup = function (suite) {
200
+ const { enhanceMochaTest } = require('./test')
201
+ return injectHook(() => {
202
+ recorder.startUnlessRunning()
203
+ event.emit(event.test.before, enhanceMochaTest(suite?.ctx?.currentTest))
204
+ }, suite)
205
+ }
206
+
207
+ module.exports.teardown = function (suite) {
208
+ const { enhanceMochaTest } = require('./test')
209
+ return injectHook(() => {
210
+ recorder.startUnlessRunning()
211
+ event.emit(event.test.after, enhanceMochaTest(suite?.ctx?.currentTest))
212
+ }, suite)
213
+ }
214
+
215
+ module.exports.suiteSetup = function (suite) {
216
+ const { enhanceMochaSuite } = require('./suite')
217
+ return injectHook(() => {
218
+ recorder.startUnlessRunning()
219
+ event.emit(event.suite.before, enhanceMochaSuite(suite))
220
+ }, suite)
221
+ }
222
+
223
+ module.exports.suiteTeardown = function (suite) {
224
+ const { enhanceMochaSuite } = require('./suite')
225
+ return injectHook(() => {
226
+ recorder.startUnlessRunning()
227
+ event.emit(event.suite.after, enhanceMochaSuite(suite))
228
+ }, suite)
229
+ }
230
+
231
+ module.exports.getInjectedArguments = getInjectedArguments
@@ -27,7 +27,7 @@ const addStep = (step, fn) => {
27
27
 
28
28
  const parameterTypeRegistry = new ParameterTypeRegistry()
29
29
 
30
- const matchStep = (step) => {
30
+ const matchStep = step => {
31
31
  for (const stepName in steps) {
32
32
  if (stepName.indexOf('/') === 0) {
33
33
  const regExpArr = stepName.match(/^\/(.*?)\/([gimy]*)$/) || []
@@ -43,7 +43,7 @@ const matchStep = (step) => {
43
43
  const res = expression.match(step)
44
44
  if (res) {
45
45
  const fn = steps[stepName]
46
- fn.params = res.map((arg) => arg.getValue())
46
+ fn.params = res.map(arg => arg.getValue())
47
47
  return fn
48
48
  }
49
49
  }
@@ -58,7 +58,7 @@ const getSteps = () => {
58
58
  return steps
59
59
  }
60
60
 
61
- const defineParameterType = (options) => {
61
+ const defineParameterType = options => {
62
62
  const parameterType = buildParameterType(options)
63
63
  parameterTypeRegistry.defineParameterType(parameterType)
64
64
  }