codeceptjs 4.0.0-beta.1 → 4.0.0-beta.10.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.
Files changed (207) hide show
  1. package/README.md +133 -120
  2. package/bin/codecept.js +107 -96
  3. package/bin/test-server.js +64 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/docs/webapi/click.mustache +5 -1
  6. package/lib/actor.js +71 -103
  7. package/lib/ai.js +159 -188
  8. package/lib/assert/empty.js +22 -24
  9. package/lib/assert/equal.js +30 -37
  10. package/lib/assert/error.js +14 -14
  11. package/lib/assert/include.js +43 -48
  12. package/lib/assert/throws.js +11 -11
  13. package/lib/assert/truth.js +22 -22
  14. package/lib/assert.js +20 -18
  15. package/lib/codecept.js +238 -162
  16. package/lib/colorUtils.js +50 -52
  17. package/lib/command/check.js +206 -0
  18. package/lib/command/configMigrate.js +56 -51
  19. package/lib/command/definitions.js +96 -109
  20. package/lib/command/dryRun.js +77 -79
  21. package/lib/command/generate.js +234 -194
  22. package/lib/command/gherkin/init.js +42 -33
  23. package/lib/command/gherkin/snippets.js +76 -74
  24. package/lib/command/gherkin/steps.js +20 -17
  25. package/lib/command/info.js +74 -38
  26. package/lib/command/init.js +300 -290
  27. package/lib/command/interactive.js +41 -32
  28. package/lib/command/list.js +28 -27
  29. package/lib/command/run-multiple/chunk.js +51 -48
  30. package/lib/command/run-multiple/collection.js +5 -5
  31. package/lib/command/run-multiple/run.js +5 -1
  32. package/lib/command/run-multiple.js +97 -97
  33. package/lib/command/run-rerun.js +19 -25
  34. package/lib/command/run-workers.js +68 -92
  35. package/lib/command/run.js +39 -27
  36. package/lib/command/utils.js +80 -64
  37. package/lib/command/workers/runTests.js +388 -226
  38. package/lib/config.js +124 -50
  39. package/lib/container.js +751 -260
  40. package/lib/data/context.js +60 -61
  41. package/lib/data/dataScenarioConfig.js +47 -47
  42. package/lib/data/dataTableArgument.js +32 -32
  43. package/lib/data/table.js +22 -22
  44. package/lib/effects.js +307 -0
  45. package/lib/element/WebElement.js +327 -0
  46. package/lib/els.js +160 -0
  47. package/lib/event.js +173 -163
  48. package/lib/globals.js +141 -0
  49. package/lib/heal.js +89 -85
  50. package/lib/helper/AI.js +131 -41
  51. package/lib/helper/ApiDataFactory.js +107 -75
  52. package/lib/helper/Appium.js +542 -404
  53. package/lib/helper/FileSystem.js +100 -79
  54. package/lib/helper/GraphQL.js +44 -43
  55. package/lib/helper/GraphQLDataFactory.js +52 -52
  56. package/lib/helper/JSONResponse.js +126 -88
  57. package/lib/helper/Mochawesome.js +54 -29
  58. package/lib/helper/Playwright.js +2547 -1316
  59. package/lib/helper/Puppeteer.js +1578 -1181
  60. package/lib/helper/REST.js +209 -68
  61. package/lib/helper/WebDriver.js +1482 -1342
  62. package/lib/helper/errors/ConnectionRefused.js +6 -6
  63. package/lib/helper/errors/ElementAssertion.js +11 -16
  64. package/lib/helper/errors/ElementNotFound.js +5 -9
  65. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  66. package/lib/helper/extras/Console.js +11 -11
  67. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  68. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
  71. package/lib/helper/extras/Popup.js +22 -22
  72. package/lib/helper/extras/React.js +27 -28
  73. package/lib/helper/network/actions.js +36 -42
  74. package/lib/helper/network/utils.js +78 -84
  75. package/lib/helper/scripts/blurElement.js +5 -5
  76. package/lib/helper/scripts/focusElement.js +5 -5
  77. package/lib/helper/scripts/highlightElement.js +8 -8
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -3
  80. package/lib/history.js +23 -19
  81. package/lib/hooks.js +8 -8
  82. package/lib/html.js +94 -104
  83. package/lib/index.js +38 -27
  84. package/lib/listener/config.js +30 -23
  85. package/lib/listener/emptyRun.js +54 -0
  86. package/lib/listener/enhancedGlobalRetry.js +110 -0
  87. package/lib/listener/exit.js +16 -18
  88. package/lib/listener/globalRetry.js +70 -0
  89. package/lib/listener/globalTimeout.js +181 -0
  90. package/lib/listener/helpers.js +76 -51
  91. package/lib/listener/mocha.js +10 -11
  92. package/lib/listener/result.js +11 -0
  93. package/lib/listener/retryEnhancer.js +85 -0
  94. package/lib/listener/steps.js +71 -59
  95. package/lib/listener/store.js +20 -0
  96. package/lib/locator.js +214 -197
  97. package/lib/mocha/asyncWrapper.js +274 -0
  98. package/lib/mocha/bdd.js +167 -0
  99. package/lib/mocha/cli.js +341 -0
  100. package/lib/mocha/factory.js +163 -0
  101. package/lib/mocha/featureConfig.js +89 -0
  102. package/lib/mocha/gherkin.js +231 -0
  103. package/lib/mocha/hooks.js +121 -0
  104. package/lib/mocha/index.js +21 -0
  105. package/lib/mocha/inject.js +46 -0
  106. package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
  107. package/lib/mocha/suite.js +89 -0
  108. package/lib/mocha/test.js +184 -0
  109. package/lib/mocha/types.d.ts +42 -0
  110. package/lib/mocha/ui.js +242 -0
  111. package/lib/output.js +141 -71
  112. package/lib/parser.js +47 -44
  113. package/lib/pause.js +173 -145
  114. package/lib/plugin/analyze.js +403 -0
  115. package/lib/plugin/{autoLogin.js → auth.js} +178 -79
  116. package/lib/plugin/autoDelay.js +36 -40
  117. package/lib/plugin/coverage.js +131 -78
  118. package/lib/plugin/customLocator.js +22 -21
  119. package/lib/plugin/customReporter.js +53 -0
  120. package/lib/plugin/enhancedRetryFailedStep.js +99 -0
  121. package/lib/plugin/heal.js +101 -110
  122. package/lib/plugin/htmlReporter.js +3648 -0
  123. package/lib/plugin/pageInfo.js +140 -0
  124. package/lib/plugin/pauseOnFail.js +12 -11
  125. package/lib/plugin/retryFailedStep.js +82 -47
  126. package/lib/plugin/screenshotOnFail.js +111 -92
  127. package/lib/plugin/stepByStepReport.js +159 -101
  128. package/lib/plugin/stepTimeout.js +20 -25
  129. package/lib/plugin/subtitles.js +38 -38
  130. package/lib/recorder.js +193 -130
  131. package/lib/rerun.js +94 -49
  132. package/lib/result.js +238 -0
  133. package/lib/retryCoordinator.js +207 -0
  134. package/lib/secret.js +20 -18
  135. package/lib/session.js +95 -89
  136. package/lib/step/base.js +239 -0
  137. package/lib/step/comment.js +10 -0
  138. package/lib/step/config.js +50 -0
  139. package/lib/step/func.js +46 -0
  140. package/lib/step/helper.js +50 -0
  141. package/lib/step/meta.js +99 -0
  142. package/lib/step/record.js +74 -0
  143. package/lib/step/retry.js +11 -0
  144. package/lib/step/section.js +55 -0
  145. package/lib/step.js +18 -329
  146. package/lib/steps.js +54 -0
  147. package/lib/store.js +38 -7
  148. package/lib/template/heal.js +3 -12
  149. package/lib/template/prompts/generatePageObject.js +31 -0
  150. package/lib/template/prompts/healStep.js +13 -0
  151. package/lib/template/prompts/writeStep.js +9 -0
  152. package/lib/test-server.js +334 -0
  153. package/lib/timeout.js +60 -0
  154. package/lib/transform.js +8 -8
  155. package/lib/translation.js +34 -21
  156. package/lib/utils/mask_data.js +47 -0
  157. package/lib/utils.js +411 -228
  158. package/lib/workerStorage.js +37 -34
  159. package/lib/workers.js +532 -296
  160. package/package.json +115 -95
  161. package/translations/de-DE.js +5 -3
  162. package/translations/fr-FR.js +5 -4
  163. package/translations/index.js +22 -12
  164. package/translations/it-IT.js +4 -3
  165. package/translations/ja-JP.js +4 -3
  166. package/translations/nl-NL.js +76 -0
  167. package/translations/pl-PL.js +4 -3
  168. package/translations/pt-BR.js +4 -3
  169. package/translations/ru-RU.js +4 -3
  170. package/translations/utils.js +10 -0
  171. package/translations/zh-CN.js +4 -3
  172. package/translations/zh-TW.js +4 -3
  173. package/typings/index.d.ts +546 -185
  174. package/typings/promiseBasedTypes.d.ts +150 -879
  175. package/typings/types.d.ts +547 -996
  176. package/lib/cli.js +0 -249
  177. package/lib/dirname.js +0 -5
  178. package/lib/helper/Expect.js +0 -425
  179. package/lib/helper/ExpectHelper.js +0 -399
  180. package/lib/helper/MockServer.js +0 -223
  181. package/lib/helper/Nightmare.js +0 -1411
  182. package/lib/helper/Protractor.js +0 -1835
  183. package/lib/helper/SoftExpectHelper.js +0 -381
  184. package/lib/helper/TestCafe.js +0 -1410
  185. package/lib/helper/clientscripts/nightmare.js +0 -213
  186. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  187. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  188. package/lib/interfaces/bdd.js +0 -98
  189. package/lib/interfaces/featureConfig.js +0 -69
  190. package/lib/interfaces/gherkin.js +0 -195
  191. package/lib/listener/artifacts.js +0 -19
  192. package/lib/listener/retry.js +0 -68
  193. package/lib/listener/timeout.js +0 -109
  194. package/lib/mochaFactory.js +0 -110
  195. package/lib/plugin/allure.js +0 -15
  196. package/lib/plugin/commentStep.js +0 -136
  197. package/lib/plugin/debugErrors.js +0 -67
  198. package/lib/plugin/eachElement.js +0 -127
  199. package/lib/plugin/fakerTransform.js +0 -49
  200. package/lib/plugin/retryTo.js +0 -121
  201. package/lib/plugin/selenoid.js +0 -371
  202. package/lib/plugin/standardActingHelpers.js +0 -9
  203. package/lib/plugin/tryTo.js +0 -105
  204. package/lib/plugin/wdio.js +0 -246
  205. package/lib/scenario.js +0 -222
  206. package/lib/ui.js +0 -238
  207. package/lib/within.js +0 -70
@@ -0,0 +1,99 @@
1
+ import Step from './base.js'
2
+ import event from '../event.js'
3
+ import { humanizeString } from '../utils.js'
4
+
5
+ class MetaStep extends Step {
6
+ constructor(actor, method) {
7
+ if (!method) method = ''
8
+ super(method)
9
+
10
+ /** @member {boolean} collsapsed hide children steps from output */
11
+ this.collapsed = false
12
+
13
+ this.actor = actor
14
+ }
15
+
16
+ /** @return {boolean} */
17
+ isBDD() {
18
+ if (this.actor && this.actor.match && this.actor.match(/^(Given|When|Then|And|But)/)) {
19
+ return true
20
+ }
21
+ return false
22
+ }
23
+
24
+ toCliStyled() {
25
+ return this.toString()
26
+ }
27
+
28
+ toString() {
29
+ const actorText = this.actor
30
+
31
+ if (this.isBDD()) {
32
+ return `${this.prefix}${actorText} ${this.name} "${this.humanizeArgs()}${this.suffix}"`
33
+ }
34
+
35
+ if (actorText === 'I') {
36
+ return `${this.prefix}${actorText} ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`
37
+ }
38
+
39
+ if (!this.actor) {
40
+ return `${this.name} ${this.humanizeArgs()}${this.suffix}`.trim()
41
+ }
42
+
43
+ return `On ${this.prefix}${actorText}: ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`.trim()
44
+ }
45
+
46
+ humanize() {
47
+ return humanizeString(this.name)
48
+ }
49
+
50
+ setTrace() {}
51
+
52
+ setContext(context) {
53
+ this.context = context
54
+ }
55
+
56
+ /** @return {*} */
57
+ run(fn) {
58
+ this.status = 'queued'
59
+ this.setArguments(Array.from(arguments).slice(1))
60
+ let result
61
+
62
+ const registerStep = step => {
63
+ this.setMetaStep(null)
64
+ step.setMetaStep(this)
65
+ }
66
+ event.dispatcher.prependListener(event.step.before, registerStep)
67
+ // Handle async and sync methods.
68
+ if (fn.constructor.name === 'AsyncFunction') {
69
+ result = fn
70
+ .apply(this.context, this.args)
71
+ .then(result => {
72
+ return result
73
+ })
74
+ .catch(error => {
75
+ this.setStatus('failed')
76
+ throw error
77
+ })
78
+ .finally(() => {
79
+ this.endTime = Date.now()
80
+ event.dispatcher.removeListener(event.step.before, registerStep)
81
+ })
82
+ } else {
83
+ try {
84
+ this.startTime = Date.now()
85
+ result = fn.apply(this.context, this.args)
86
+ } catch (error) {
87
+ this.setStatus('failed')
88
+ throw error
89
+ } finally {
90
+ this.endTime = Date.now()
91
+ event.dispatcher.removeListener(event.step.before, registerStep)
92
+ }
93
+ }
94
+
95
+ return result
96
+ }
97
+ }
98
+
99
+ export default MetaStep
@@ -0,0 +1,74 @@
1
+ import event from '../event.js'
2
+ import recorder from '../recorder.js'
3
+ import StepConfig from './config.js'
4
+ import output from '../output.js'
5
+ import store from '../store.js'
6
+ import { TIMEOUT_ORDER } from '../timeout.js'
7
+ import retryStep from './retry.js'
8
+ function recordStep(step, args) {
9
+ step.status = 'queued'
10
+
11
+ // apply step configuration
12
+ const lastArg = args[args.length - 1]
13
+ if (lastArg instanceof StepConfig) {
14
+ const stepConfig = args.pop()
15
+ const { opts, timeout, retry } = stepConfig.getConfig()
16
+
17
+ if (opts) {
18
+ output.debug(`Step ${step.name}: options applied ${JSON.stringify(opts)}`)
19
+ store.stepOptions = opts
20
+ step.opts = opts
21
+ }
22
+ if (timeout) {
23
+ output.debug(`Step ${step.name} timeout ${timeout}s`)
24
+ step.setTimeout(timeout * 1000, TIMEOUT_ORDER.codeLimitTime)
25
+ }
26
+ if (retry) retryStep(retry)
27
+ }
28
+
29
+ step.setArguments(args)
30
+ // run async before step hooks
31
+ event.emit(event.step.before, step)
32
+
33
+ const task = `${step.name}: ${step.humanizeArgs()}`
34
+ let val
35
+
36
+ // run step inside promise
37
+ recorder.add(
38
+ task,
39
+ () => {
40
+ if (!step.startTime) {
41
+ // step can be retries
42
+ event.emit(event.step.started, step)
43
+ step.startTime = +Date.now()
44
+ }
45
+ return (val = step.run(...args))
46
+ },
47
+ false,
48
+ undefined,
49
+ step.timeout,
50
+ )
51
+
52
+ event.emit(event.step.after, step)
53
+
54
+ recorder.add('step passed', () => {
55
+ step.endTime = +Date.now()
56
+ event.emit(event.step.passed, step, val)
57
+ event.emit(event.step.finished, step)
58
+ })
59
+
60
+ recorder.catch(err => {
61
+ step.status = 'failed'
62
+ step.endTime = +Date.now()
63
+ event.emit(event.step.failed, step, err)
64
+ event.emit(event.step.finished, step)
65
+ throw err
66
+ })
67
+
68
+ recorder.add('return result', () => val)
69
+ // run async after step hooks
70
+
71
+ return recorder.promise()
72
+ }
73
+
74
+ export default recordStep
@@ -0,0 +1,11 @@
1
+ import recorder from '../recorder.js'
2
+ import event from '../event.js'
3
+
4
+ function retryStep(opts) {
5
+ if (opts === undefined) opts = 1
6
+ recorder.retry(opts)
7
+ // remove retry once the step passed
8
+ recorder.add(() => event.dispatcher.once(event.step.finished, () => recorder.retries.pop()))
9
+ }
10
+
11
+ export default retryStep
@@ -0,0 +1,55 @@
1
+ import MetaStep from './meta.js'
2
+ import event from '../event.js'
3
+
4
+ let currentSection
5
+
6
+ class Section {
7
+ constructor(name = '') {
8
+ this.name = name
9
+
10
+ this.metaStep = new MetaStep(null, name)
11
+
12
+ this.attachMetaStep = step => {
13
+ if (currentSection !== this) return
14
+ if (!step) return
15
+ const metaStep = getRootMetaStep(step)
16
+
17
+ if (metaStep !== this.metaStep) {
18
+ metaStep.metaStep = this.metaStep
19
+ }
20
+ }
21
+ }
22
+
23
+ hidden() {
24
+ this.metaStep.collapsed = true
25
+ return this
26
+ }
27
+
28
+ start() {
29
+ if (currentSection) currentSection.end()
30
+ currentSection = this
31
+ event.dispatcher.prependListener(event.step.before, this.attachMetaStep)
32
+ event.dispatcher.once(event.test.finished, () => this.end())
33
+ return this
34
+ }
35
+
36
+ end() {
37
+ currentSection = null
38
+ event.dispatcher.off(event.step.started, this.attachMetaStep)
39
+ return this
40
+ }
41
+
42
+ /**
43
+ * @returns {Section}
44
+ */
45
+ static current() {
46
+ return currentSection
47
+ }
48
+ }
49
+
50
+ function getRootMetaStep(step) {
51
+ if (step.metaStep) return getRootMetaStep(step.metaStep)
52
+ return step
53
+ }
54
+
55
+ export default Section
package/lib/step.js CHANGED
@@ -1,334 +1,23 @@
1
- // TODO: place MetaStep in other file, disable rule
2
- /* eslint-disable max-classes-per-file */
3
- import { store } from './store.js';
4
-
5
- import Secret from './secret.js';
6
- import * as event from './event.js';
7
-
8
- const STACK_LINE = 4;
9
-
1
+ // refactored step class, moved to helper
10
2
  /**
11
- * Each command in test executed through `I.` object is wrapped in Step.
12
- * Step allows logging executed commands and triggers hook before and after step execution.
13
- * @param {CodeceptJS.Helper} helper
14
- * @param {string} name
3
+ * Step is wrapper around a helper method.
4
+ * It is used to create a new step that is a combination of other steps.
15
5
  */
16
- export class Step {
17
- static get TIMEOUT_ORDER() {
18
- return {
19
- /**
20
- * timeouts set with order below zero only override timeouts of higher order if their value is smaller
21
- */
22
- testOrSuite: -5,
23
- /**
24
- * 0-9 - designated for override of timeouts set from code, 5 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=true
25
- */
26
- stepTimeoutHard: 5,
27
- /**
28
- * 10-19 - designated for timeouts set from code, 15 is order of I.setTimeout(t) operation
29
- */
30
- codeLimitTime: 15,
31
- /**
32
- * 20-29 - designated for timeout settings which could be overriden in tests code, 25 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=false
33
- */
34
- stepTimeoutSoft: 25,
35
- };
36
- }
37
-
38
- constructor(helper, name) {
39
- /** @member {string} */
40
- this.actor = 'I'; // I = actor
41
- /** @member {CodeceptJS.Helper} */
42
- this.helper = helper; // corresponding helper
43
- /** @member {string} */
44
- this.name = name; // name of a step console
45
- /** @member {string} */
46
- this.helperMethod = name; // helper method
47
- /** @member {string} */
48
- this.status = 'pending';
49
- /**
50
- * @member {string} suffix
51
- * @memberof CodeceptJS.Step#
52
- */
53
- /** @member {string} */
54
- this.prefix = this.suffix = '';
55
- /** @member {string} */
56
- this.comment = '';
57
- /** @member {Array<*>} */
58
- this.args = [];
59
- /** @member {MetaStep} */
60
- this.metaStep = undefined;
61
- /** @member {string} */
62
- this.stack = '';
63
-
64
- const timeouts = new Map();
65
- /**
66
- * @method
67
- * @returns {number|undefined}
68
- */
69
- this.getTimeout = function () {
70
- let totalTimeout;
71
- // iterate over all timeouts starting from highest values of order
72
- new Map([...timeouts.entries()].sort().reverse()).forEach((timeout, order) => {
73
- if (timeout !== undefined && (
74
- // when orders >= 0 - timeout value overrides those set with higher order elements
75
- (// when `order < 0` - timeout overrides higher values of timeout or 'no timeout' (totalTimeout === 0) set by elements with higher order
76
- (order >= 0
77
-
78
- // when `order < 0 && totalTimeout === undefined` - timeout is used when nothing is set by elements with higher order
79
- || totalTimeout === undefined || timeout > 0 && (timeout < totalTimeout || totalTimeout === 0)))
80
- )) {
81
- totalTimeout = timeout;
82
- }
83
- });
84
- return totalTimeout;
85
- };
86
- /**
87
- * @method
88
- * @param {number} timeout - timeout in milliseconds or 0 if no timeout
89
- * @param {number} order - order defines the priority of timeout, timeouts set with lower order override those set with higher order.
90
- * When order below 0 value of timeout only override if new value is lower
91
- */
92
- this.setTimeout = function (timeout, order) {
93
- timeouts.set(order, timeout);
94
- };
95
-
96
- this.setTrace();
97
- }
98
-
99
- /** @function */
100
- setTrace() {
101
- Error.captureStackTrace(this);
102
- }
103
-
104
- /** @param {Array<*>} args */
105
- setArguments(args) {
106
- this.args = args;
107
- }
108
-
109
- /**
110
- * @param {...any} args
111
- * @return {*}
112
- */
113
- run() {
114
- this.args = Array.prototype.slice.call(arguments);
115
- if (store.dryRun) {
116
- this.setStatus('success');
117
- return Promise.resolve(new Proxy({}, dryRunResolver()));
118
- }
119
- let result;
120
- try {
121
- if (this.helperMethod !== 'say') {
122
- result = this.helper[this.helperMethod].apply(this.helper, this.args);
123
- }
124
- this.setStatus('success');
125
- } catch (err) {
126
- this.setStatus('failed');
127
- throw err;
128
- }
129
- return result;
130
- }
131
-
132
- /** @param {string} status */
133
- setStatus(status) {
134
- this.status = status;
135
- if (this.metaStep) {
136
- this.metaStep.setStatus(status);
137
- }
138
- }
139
-
140
- /** @return {string} */
141
- humanize() {
142
- return humanizeString(this.name);
143
- }
144
-
145
- /** @return {string} */
146
- humanizeArgs() {
147
- return this.args.map((arg) => {
148
- if (!arg) {
149
- return '';
150
- }
151
- if (typeof arg === 'string') {
152
- return `"${arg}"`;
153
- }
154
- if (Array.isArray(arg)) {
155
- try {
156
- const res = JSON.stringify(arg);
157
- return res;
158
- } catch (err) {
159
- return `[${arg.toString()}]`;
160
- }
161
- } else if (typeof arg === 'function') {
162
- return arg.toString();
163
- } else if (typeof arg === 'undefined') {
164
- return `${arg}`;
165
- } else if (arg instanceof Secret) {
166
- return arg.getMasked();
167
- } else if (arg.toString && arg.toString() !== '[object Object]') {
168
- return arg.toString();
169
- } else if (typeof arg === 'object') {
170
- const returnedArg = {};
171
- for (const [key, value] of Object.entries(arg)) {
172
- returnedArg[key] = value;
173
- if (value instanceof Secret) returnedArg[key] = value.getMasked();
174
- }
175
- return JSON.stringify(returnedArg);
176
- }
177
- return arg;
178
- }).join(', ');
179
- }
180
-
181
- /** @return {string} */
182
- line() {
183
- const lines = this.stack.split('\n');
184
- if (lines[STACK_LINE]) {
185
- return lines[STACK_LINE].trim().replace(global.codecept_dir || '', '.').trim();
186
- }
187
- return '';
188
- }
189
-
190
- /** @return {string} */
191
- toString() {
192
- return `${this.prefix}${this.actor} ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
193
- }
194
-
195
- /** @return {string} */
196
- toCode() {
197
- return `${this.prefix}${this.actor}.${this.name}(${this.humanizeArgs()})${this.suffix}`;
198
- }
199
-
200
- isMetaStep() {
201
- return this.constructor.name === 'MetaStep';
202
- }
203
-
204
- /** @return {boolean} */
205
- hasBDDAncestor() {
206
- let hasBDD = false;
207
- let processingStep;
208
- processingStep = this;
209
-
210
- while (processingStep.metaStep) {
211
- if (processingStep.metaStep.actor.match(/^(Given|When|Then|And)/)) {
212
- hasBDD = true;
213
- break;
214
- } else {
215
- processingStep = processingStep.metaStep;
216
- }
217
- }
218
- return hasBDD;
219
- }
220
- }
221
-
222
- /** @extends Step */
223
- export class MetaStep extends Step {
224
- constructor(obj, method) {
225
- super(null, method);
226
- this.actor = obj;
227
- }
6
+ import BaseStep from './step/base.js'
7
+ import StepConfig from './step/config.js'
8
+ import Step from './step/helper.js'
228
9
 
229
- /** @return {boolean} */
230
- isBDD() {
231
- if (this.actor && this.actor.match && this.actor.match(/^(Given|When|Then|And)/)) {
232
- return true;
233
- }
234
- return false;
235
- }
236
-
237
- isWithin() {
238
- if (this.actor && this.actor.match && this.actor.match(/^(Within)/)) {
239
- return true;
240
- }
241
- return false;
242
- }
243
-
244
- toString() {
245
- const actorText = this.actor;
246
-
247
- if (this.isBDD() || this.isWithin()) {
248
- return `${this.prefix}${actorText} ${this.name} "${this.humanizeArgs()}${this.suffix}"`;
249
- }
250
-
251
- if (actorText === 'I') {
252
- return `${this.prefix}${actorText} ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
253
- }
254
-
255
- return `On ${this.prefix}${actorText}: ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
256
- }
257
-
258
- humanize() {
259
- return humanizeString(this.name);
260
- }
261
-
262
- setTrace() {
263
- }
264
-
265
- setContext(context) {
266
- this.context = context;
267
- }
268
-
269
- /** @return {*} */
270
- run(fn) {
271
- this.status = 'queued';
272
- this.setArguments(Array.from(arguments).slice(1));
273
- let result;
274
-
275
- const registerStep = (step) => {
276
- this.metaStep = null;
277
- step.metaStep = this;
278
- };
279
- event.dispatcher.prependListener(event.step.before, registerStep);
280
- // Handle async and sync methods.
281
- if (fn.constructor.name === 'AsyncFunction') {
282
- result = fn.apply(this.context, this.args).then((result) => {
283
- return result;
284
- }).catch((error) => {
285
- this.setStatus('failed');
286
- throw error;
287
- }).finally(() => {
288
- this.endTime = Date.now();
289
- event.dispatcher.removeListener(event.step.before, registerStep);
290
- });
291
- } else {
292
- try {
293
- this.startTime = Date.now();
294
- result = fn.apply(this.context, this.args);
295
- } catch (error) {
296
- this.setStatus('failed');
297
- throw error;
298
- } finally {
299
- this.endTime = Date.now();
300
- event.dispatcher.removeListener(event.step.before, registerStep);
301
- }
302
- }
303
-
304
- return result;
305
- }
306
- }
307
-
308
- Step.TIMEOUTS = {};
309
-
310
- /** @type {Class<MetaStep>} */
311
- Step.MetaStep = MetaStep;
312
-
313
- function dryRunResolver() {
314
- return {
315
- get(target, prop) {
316
- if (prop === 'toString') return () => '<VALUE>';
317
- return new Proxy({}, dryRunResolver());
318
- },
319
- };
320
- }
321
-
322
- function humanizeString(string) {
323
- // split strings by words, then make them all lowercase
324
- const _result = string.replace(/([a-z](?=[A-Z]))/g, '$1 ')
325
- .split(' ')
326
- .map(word => word.toLowerCase());
10
+ /**
11
+ * MetaStep is a step that is used to wrap other steps.
12
+ * It is used to create a new step that is a combination of other steps.
13
+ * It is used to create a new step that is a combination of other steps.
14
+ */
15
+ import MetaStep from './step/meta.js'
327
16
 
328
- _result[0] = _result[0] === 'i' ? capitalizeFLetter(_result[0]) : _result[0];
329
- return _result.join(' ').trim();
330
- }
17
+ /**
18
+ * Step used to execute a single function
19
+ */
20
+ import FuncStep from './step/func.js'
331
21
 
332
- function capitalizeFLetter(string) {
333
- return (string[0].toUpperCase() + string.slice(1));
334
- }
22
+ export default Step
23
+ export { MetaStep, BaseStep, StepConfig, FuncStep }
package/lib/steps.js ADDED
@@ -0,0 +1,54 @@
1
+ import StepConfig from './step/config.js'
2
+ import SectionClass from './step/section.js'
3
+ function stepOpts(opts = {}) {
4
+ return new StepConfig(opts)
5
+ }
6
+
7
+ function stepTimeout(timeout) {
8
+ return new StepConfig().timeout(timeout)
9
+ }
10
+
11
+ function stepRetry(retry) {
12
+ return new StepConfig().retry(retry)
13
+ }
14
+
15
+ function section(name) {
16
+ if (!name) return endSection()
17
+ return new SectionClass(name).start()
18
+ }
19
+
20
+ function endSection() {
21
+ return SectionClass.current().end()
22
+ }
23
+
24
+ // Section function to be added here
25
+
26
+ const step = {
27
+ // steps.opts syntax
28
+ opts: stepOpts,
29
+ timeout: stepTimeout,
30
+ retry: stepRetry,
31
+
32
+ // one-function syntax
33
+ stepTimeout,
34
+ stepRetry,
35
+ stepOpts,
36
+
37
+ // sections
38
+ section,
39
+ endSection,
40
+
41
+ Section: section,
42
+ EndSection: endSection,
43
+
44
+ // shortcuts
45
+ Given: () => section('Given'),
46
+ When: () => section('When'),
47
+ Then: () => section('Then'),
48
+ }
49
+
50
+ export default step
51
+
52
+ // Named exports for ESM compatibility
53
+ export const Section = step.Section
54
+ export const EndSection = step.EndSection
package/lib/store.js CHANGED
@@ -2,14 +2,45 @@
2
2
  * global values for current session
3
3
  * @namespace
4
4
  */
5
- export const store = {
6
- /** @type {boolean} */
5
+ const store = {
6
+ /**
7
+ * If we are in --debug mode
8
+ * @type {boolean}
9
+ */
7
10
  debugMode: false,
8
- /** @type {boolean} */
11
+
12
+ /**
13
+ * Is timeouts enabled
14
+ * @type {boolean}
15
+ */
9
16
  timeouts: true,
10
- /** @type {boolean} */
17
+
18
+ /**
19
+ * If auto-retries are enabled by retryFailedStep plugin
20
+ * tryTo effect disables them
21
+ * @type {boolean}
22
+ */
23
+ autoRetries: false,
24
+
25
+ /**
26
+ * Tests are executed via dry-run
27
+ * @type {boolean}
28
+ */
11
29
  dryRun: false,
12
- };
30
+ /**
31
+ * If we are in pause mode
32
+ * @type {boolean}
33
+ */
34
+ onPause: false,
35
+
36
+ // current object states
37
+
38
+ /** @type {CodeceptJS.Test | null} */
39
+ currentTest: null,
40
+ /** @type {CodeceptJS.Step | null} */
41
+ currentStep: null,
42
+ /** @type {CodeceptJS.Suite | null} */
43
+ currentSuite: null,
44
+ }
13
45
 
14
- /** @type {boolean} */
15
- export const timeouts = true;
46
+ export default store