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.
Files changed (188) hide show
  1. package/README.md +89 -119
  2. package/bin/codecept.js +53 -54
  3. package/docs/webapi/clearCookie.mustache +1 -1
  4. package/lib/actor.js +70 -102
  5. package/lib/ai.js +131 -121
  6. package/lib/assert/empty.js +11 -12
  7. package/lib/assert/equal.js +16 -21
  8. package/lib/assert/error.js +2 -2
  9. package/lib/assert/include.js +11 -15
  10. package/lib/assert/throws.js +3 -5
  11. package/lib/assert/truth.js +10 -7
  12. package/lib/assert.js +18 -18
  13. package/lib/codecept.js +112 -101
  14. package/lib/colorUtils.js +48 -50
  15. package/lib/command/check.js +206 -0
  16. package/lib/command/configMigrate.js +13 -14
  17. package/lib/command/definitions.js +24 -36
  18. package/lib/command/dryRun.js +16 -16
  19. package/lib/command/generate.js +38 -39
  20. package/lib/command/gherkin/init.js +36 -38
  21. package/lib/command/gherkin/snippets.js +76 -74
  22. package/lib/command/gherkin/steps.js +21 -18
  23. package/lib/command/info.js +49 -15
  24. package/lib/command/init.js +41 -37
  25. package/lib/command/interactive.js +22 -13
  26. package/lib/command/list.js +11 -10
  27. package/lib/command/run-multiple/chunk.js +50 -47
  28. package/lib/command/run-multiple/collection.js +5 -5
  29. package/lib/command/run-multiple/run.js +3 -3
  30. package/lib/command/run-multiple.js +27 -47
  31. package/lib/command/run-rerun.js +6 -7
  32. package/lib/command/run-workers.js +15 -66
  33. package/lib/command/run.js +8 -8
  34. package/lib/command/utils.js +22 -21
  35. package/lib/command/workers/runTests.js +131 -241
  36. package/lib/config.js +111 -49
  37. package/lib/container.js +589 -244
  38. package/lib/data/context.js +16 -18
  39. package/lib/data/dataScenarioConfig.js +9 -9
  40. package/lib/data/dataTableArgument.js +7 -7
  41. package/lib/data/table.js +6 -12
  42. package/lib/effects.js +307 -0
  43. package/lib/els.js +160 -0
  44. package/lib/event.js +24 -19
  45. package/lib/globals.js +141 -0
  46. package/lib/heal.js +89 -81
  47. package/lib/helper/AI.js +3 -2
  48. package/lib/helper/ApiDataFactory.js +19 -19
  49. package/lib/helper/Appium.js +47 -51
  50. package/lib/helper/FileSystem.js +35 -15
  51. package/lib/helper/GraphQL.js +1 -1
  52. package/lib/helper/GraphQLDataFactory.js +4 -4
  53. package/lib/helper/JSONResponse.js +72 -45
  54. package/lib/helper/Mochawesome.js +14 -11
  55. package/lib/helper/Playwright.js +832 -434
  56. package/lib/helper/Puppeteer.js +393 -292
  57. package/lib/helper/REST.js +32 -27
  58. package/lib/helper/WebDriver.js +320 -219
  59. package/lib/helper/errors/ConnectionRefused.js +6 -6
  60. package/lib/helper/errors/ElementAssertion.js +11 -16
  61. package/lib/helper/errors/ElementNotFound.js +5 -9
  62. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  63. package/lib/helper/extras/Console.js +11 -11
  64. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  65. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  66. package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
  67. package/lib/helper/extras/Popup.js +22 -22
  68. package/lib/helper/extras/React.js +29 -30
  69. package/lib/helper/network/actions.js +33 -48
  70. package/lib/helper/network/utils.js +76 -83
  71. package/lib/helper/scripts/blurElement.js +6 -6
  72. package/lib/helper/scripts/focusElement.js +6 -6
  73. package/lib/helper/scripts/highlightElement.js +9 -9
  74. package/lib/helper/scripts/isElementClickable.js +34 -34
  75. package/lib/helper.js +2 -1
  76. package/lib/history.js +23 -20
  77. package/lib/hooks.js +10 -10
  78. package/lib/html.js +90 -100
  79. package/lib/index.js +48 -21
  80. package/lib/listener/config.js +8 -9
  81. package/lib/listener/emptyRun.js +54 -0
  82. package/lib/listener/exit.js +10 -12
  83. package/lib/listener/{retry.js → globalRetry.js} +10 -10
  84. package/lib/listener/globalTimeout.js +166 -0
  85. package/lib/listener/helpers.js +43 -24
  86. package/lib/listener/mocha.js +4 -5
  87. package/lib/listener/result.js +11 -0
  88. package/lib/listener/steps.js +26 -23
  89. package/lib/listener/store.js +20 -0
  90. package/lib/locator.js +213 -192
  91. package/lib/mocha/asyncWrapper.js +264 -0
  92. package/lib/mocha/bdd.js +167 -0
  93. package/lib/mocha/cli.js +341 -0
  94. package/lib/mocha/factory.js +160 -0
  95. package/lib/{interfaces → mocha}/featureConfig.js +33 -13
  96. package/lib/{interfaces → mocha}/gherkin.js +75 -45
  97. package/lib/mocha/hooks.js +121 -0
  98. package/lib/mocha/index.js +21 -0
  99. package/lib/mocha/inject.js +46 -0
  100. package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
  101. package/lib/mocha/suite.js +89 -0
  102. package/lib/mocha/test.js +178 -0
  103. package/lib/mocha/types.d.ts +42 -0
  104. package/lib/mocha/ui.js +229 -0
  105. package/lib/output.js +86 -64
  106. package/lib/parser.js +44 -44
  107. package/lib/pause.js +160 -139
  108. package/lib/plugin/analyze.js +403 -0
  109. package/lib/plugin/{autoLogin.js → auth.js} +137 -43
  110. package/lib/plugin/autoDelay.js +19 -15
  111. package/lib/plugin/coverage.js +22 -27
  112. package/lib/plugin/customLocator.js +5 -5
  113. package/lib/plugin/customReporter.js +53 -0
  114. package/lib/plugin/heal.js +49 -17
  115. package/lib/plugin/pageInfo.js +140 -0
  116. package/lib/plugin/pauseOnFail.js +4 -3
  117. package/lib/plugin/retryFailedStep.js +60 -19
  118. package/lib/plugin/screenshotOnFail.js +80 -83
  119. package/lib/plugin/stepByStepReport.js +70 -31
  120. package/lib/plugin/stepTimeout.js +7 -13
  121. package/lib/plugin/subtitles.js +10 -9
  122. package/lib/recorder.js +167 -126
  123. package/lib/rerun.js +94 -50
  124. package/lib/result.js +161 -0
  125. package/lib/secret.js +18 -17
  126. package/lib/session.js +95 -89
  127. package/lib/step/base.js +239 -0
  128. package/lib/step/comment.js +10 -0
  129. package/lib/step/config.js +50 -0
  130. package/lib/step/func.js +46 -0
  131. package/lib/step/helper.js +50 -0
  132. package/lib/step/meta.js +99 -0
  133. package/lib/step/record.js +74 -0
  134. package/lib/step/retry.js +11 -0
  135. package/lib/step/section.js +55 -0
  136. package/lib/step.js +18 -332
  137. package/lib/steps.js +54 -0
  138. package/lib/store.js +37 -5
  139. package/lib/template/heal.js +2 -11
  140. package/lib/timeout.js +60 -0
  141. package/lib/transform.js +8 -8
  142. package/lib/translation.js +32 -18
  143. package/lib/utils.js +354 -250
  144. package/lib/workerStorage.js +16 -16
  145. package/lib/workers.js +366 -282
  146. package/package.json +107 -95
  147. package/translations/de-DE.js +5 -4
  148. package/translations/fr-FR.js +5 -4
  149. package/translations/index.js +23 -9
  150. package/translations/it-IT.js +5 -4
  151. package/translations/ja-JP.js +5 -4
  152. package/translations/nl-NL.js +76 -0
  153. package/translations/pl-PL.js +5 -4
  154. package/translations/pt-BR.js +5 -4
  155. package/translations/ru-RU.js +5 -4
  156. package/translations/utils.js +18 -0
  157. package/translations/zh-CN.js +5 -4
  158. package/translations/zh-TW.js +5 -4
  159. package/typings/index.d.ts +177 -186
  160. package/typings/promiseBasedTypes.d.ts +3573 -5941
  161. package/typings/types.d.ts +4042 -6370
  162. package/lib/cli.js +0 -256
  163. package/lib/helper/ExpectHelper.js +0 -391
  164. package/lib/helper/Nightmare.js +0 -1504
  165. package/lib/helper/Protractor.js +0 -1863
  166. package/lib/helper/SoftExpectHelper.js +0 -381
  167. package/lib/helper/TestCafe.js +0 -1414
  168. package/lib/helper/clientscripts/nightmare.js +0 -213
  169. package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
  170. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  171. package/lib/helper/testcafe/testcafe-utils.js +0 -62
  172. package/lib/interfaces/bdd.js +0 -81
  173. package/lib/listener/artifacts.js +0 -19
  174. package/lib/listener/timeout.js +0 -109
  175. package/lib/mochaFactory.js +0 -113
  176. package/lib/plugin/allure.js +0 -15
  177. package/lib/plugin/commentStep.js +0 -136
  178. package/lib/plugin/debugErrors.js +0 -67
  179. package/lib/plugin/eachElement.js +0 -127
  180. package/lib/plugin/fakerTransform.js +0 -49
  181. package/lib/plugin/retryTo.js +0 -127
  182. package/lib/plugin/selenoid.js +0 -384
  183. package/lib/plugin/standardActingHelpers.js +0 -3
  184. package/lib/plugin/tryTo.js +0 -115
  185. package/lib/plugin/wdio.js +0 -249
  186. package/lib/scenario.js +0 -224
  187. package/lib/ui.js +0 -236
  188. package/lib/within.js +0 -70
package/lib/step.js CHANGED
@@ -1,337 +1,23 @@
1
- // TODO: place MetaStep in other file, disable rule
2
-
3
- const store = require('./store');
4
- const Secret = require('./secret');
5
- const event = require('./event');
6
-
7
- const STACK_LINE = 4;
8
-
1
+ // refactored step class, moved to helper
9
2
  /**
10
- * Each command in test executed through `I.` object is wrapped in Step.
11
- * Step allows logging executed commands and triggers hook before and after step execution.
12
- * @param {CodeceptJS.Helper} helper
13
- * @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.
14
5
  */
15
- class Step {
16
- static get TIMEOUT_ORDER() {
17
- return {
18
- /**
19
- * timeouts set with order below zero only override timeouts of higher order if their value is smaller
20
- */
21
- testOrSuite: -5,
22
- /**
23
- * 0-9 - designated for override of timeouts set from code, 5 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=true
24
- */
25
- stepTimeoutHard: 5,
26
- /**
27
- * 10-19 - designated for timeouts set from code, 15 is order of I.setTimeout(t) operation
28
- */
29
- codeLimitTime: 15,
30
- /**
31
- * 20-29 - designated for timeout settings which could be overriden in tests code, 25 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=false
32
- */
33
- stepTimeoutSoft: 25,
34
- };
35
- }
36
-
37
- constructor(helper, name) {
38
- /** @member {string} */
39
- this.actor = 'I'; // I = actor
40
- /** @member {CodeceptJS.Helper} */
41
- this.helper = helper; // corresponding helper
42
- /** @member {string} */
43
- this.name = name; // name of a step console
44
- /** @member {string} */
45
- this.helperMethod = name; // helper method
46
- /** @member {string} */
47
- this.status = 'pending';
48
- /**
49
- * @member {string} suffix
50
- * @memberof CodeceptJS.Step#
51
- */
52
- /** @member {string} */
53
- this.prefix = this.suffix = '';
54
- /** @member {string} */
55
- this.comment = '';
56
- /** @member {Array<*>} */
57
- this.args = [];
58
- /** @member {MetaStep} */
59
- this.metaStep = undefined;
60
- /** @member {string} */
61
- this.stack = '';
62
-
63
- const timeouts = new Map();
64
- /**
65
- * @method
66
- * @returns {number|undefined}
67
- */
68
- this.getTimeout = function () {
69
- let totalTimeout;
70
- // iterate over all timeouts starting from highest values of order
71
- new Map([...timeouts.entries()].sort().reverse()).forEach((timeout, order) => {
72
- if (timeout !== undefined && (
73
- // when orders >= 0 - timeout value overrides those set with higher order elements
74
- order >= 0
75
-
76
- // when `order < 0 && totalTimeout === undefined` - timeout is used when nothing is set by elements with higher order
77
- || totalTimeout === undefined
78
-
79
- // when `order < 0` - timeout overrides higher values of timeout or 'no timeout' (totalTimeout === 0) set by elements with higher order
80
- || timeout > 0 && (timeout < totalTimeout || totalTimeout === 0)
81
- )) {
82
- totalTimeout = timeout;
83
- }
84
- });
85
- return totalTimeout;
86
- };
87
- /**
88
- * @method
89
- * @param {number} timeout - timeout in milliseconds or 0 if no timeout
90
- * @param {number} order - order defines the priority of timeout, timeouts set with lower order override those set with higher order.
91
- * When order below 0 value of timeout only override if new value is lower
92
- */
93
- this.setTimeout = function (timeout, order) {
94
- timeouts.set(order, timeout);
95
- };
96
-
97
- this.setTrace();
98
- }
99
-
100
- /** @function */
101
- setTrace() {
102
- Error.captureStackTrace(this);
103
- }
104
-
105
- /** @param {Array<*>} args */
106
- setArguments(args) {
107
- this.args = args;
108
- }
109
-
110
- /**
111
- * @param {...any} args
112
- * @return {*}
113
- */
114
- run() {
115
- this.args = Array.prototype.slice.call(arguments);
116
- if (store.dryRun) {
117
- this.setStatus('success');
118
- return Promise.resolve(new Proxy({}, dryRunResolver()));
119
- }
120
- let result;
121
- try {
122
- if (this.helperMethod !== 'say') {
123
- result = this.helper[this.helperMethod].apply(this.helper, this.args);
124
- }
125
- this.setStatus('success');
126
- } catch (err) {
127
- this.setStatus('failed');
128
- throw err;
129
- }
130
- return result;
131
- }
132
-
133
- /** @param {string} status */
134
- setStatus(status) {
135
- this.status = status;
136
- if (this.metaStep) {
137
- this.metaStep.setStatus(status);
138
- }
139
- }
140
-
141
- /** @return {string} */
142
- humanize() {
143
- return humanizeString(this.name);
144
- }
145
-
146
- /** @return {string} */
147
- humanizeArgs() {
148
- return this.args.map((arg) => {
149
- if (!arg) {
150
- return '';
151
- }
152
- if (typeof arg === 'string') {
153
- return `"${arg}"`;
154
- }
155
- if (Array.isArray(arg)) {
156
- try {
157
- const res = JSON.stringify(arg);
158
- return res;
159
- } catch (err) {
160
- return `[${arg.toString()}]`;
161
- }
162
- } else if (typeof arg === 'function') {
163
- return arg.toString();
164
- } else if (typeof arg === 'undefined') {
165
- return `${arg}`;
166
- } else if (arg instanceof Secret) {
167
- return arg.getMasked();
168
- } else if (arg.toString && arg.toString() !== '[object Object]') {
169
- return arg.toString();
170
- } else if (typeof arg === 'object') {
171
- const returnedArg = {};
172
- for (const [key, value] of Object.entries(arg)) {
173
- returnedArg[key] = value;
174
- if (value instanceof Secret) returnedArg[key] = value.getMasked();
175
- }
176
- return JSON.stringify(returnedArg);
177
- }
178
- return arg;
179
- }).join(', ');
180
- }
181
-
182
- /** @return {string} */
183
- line() {
184
- const lines = this.stack.split('\n');
185
- if (lines[STACK_LINE]) {
186
- return lines[STACK_LINE].trim().replace(global.codecept_dir || '', '.').trim();
187
- }
188
- return '';
189
- }
190
-
191
- /** @return {string} */
192
- toString() {
193
- return `${this.prefix}${this.actor} ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
194
- }
195
-
196
- /** @return {string} */
197
- toCode() {
198
- return `${this.prefix}${this.actor}.${this.name}(${this.humanizeArgs()})${this.suffix}`;
199
- }
200
-
201
- isMetaStep() {
202
- return this.constructor.name === 'MetaStep';
203
- }
204
-
205
- /** @return {boolean} */
206
- hasBDDAncestor() {
207
- let hasBDD = false;
208
- let processingStep;
209
- processingStep = this;
210
-
211
- while (processingStep.metaStep) {
212
- if (processingStep.metaStep.actor.match(/^(Given|When|Then|And)/)) {
213
- hasBDD = true;
214
- break;
215
- } else {
216
- processingStep = processingStep.metaStep;
217
- }
218
- }
219
- return hasBDD;
220
- }
221
- }
222
-
223
- /** @extends Step */
224
- class MetaStep extends Step {
225
- constructor(obj, method) {
226
- super(null, method);
227
- this.actor = obj;
228
- }
6
+ import BaseStep from './step/base.js'
7
+ import StepConfig from './step/config.js'
8
+ import Step from './step/helper.js'
229
9
 
230
- /** @return {boolean} */
231
- isBDD() {
232
- if (this.actor && this.actor.match && this.actor.match(/^(Given|When|Then|And)/)) {
233
- return true;
234
- }
235
- return false;
236
- }
237
-
238
- isWithin() {
239
- if (this.actor && this.actor.match && this.actor.match(/^(Within)/)) {
240
- return true;
241
- }
242
- return false;
243
- }
244
-
245
- toString() {
246
- const actorText = this.actor;
247
-
248
- if (this.isBDD() || this.isWithin()) {
249
- return `${this.prefix}${actorText} ${this.name} "${this.humanizeArgs()}${this.suffix}"`;
250
- }
251
-
252
- if (actorText === 'I') {
253
- return `${this.prefix}${actorText} ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
254
- }
255
-
256
- return `On ${this.prefix}${actorText}: ${this.humanize()} ${this.humanizeArgs()}${this.suffix}`;
257
- }
258
-
259
- humanize() {
260
- return humanizeString(this.name);
261
- }
262
-
263
- setTrace() {
264
- }
265
-
266
- setContext(context) {
267
- this.context = context;
268
- }
269
-
270
- /** @return {*} */
271
- run(fn) {
272
- this.status = 'queued';
273
- this.setArguments(Array.from(arguments).slice(1));
274
- let result;
275
-
276
- const registerStep = (step) => {
277
- this.metaStep = null;
278
- step.metaStep = this;
279
- };
280
- event.dispatcher.prependListener(event.step.before, registerStep);
281
- // Handle async and sync methods.
282
- if (fn.constructor.name === 'AsyncFunction') {
283
- result = fn.apply(this.context, this.args).then((result) => {
284
- return result;
285
- }).catch((error) => {
286
- this.setStatus('failed');
287
- throw error;
288
- }).finally(() => {
289
- this.endTime = Date.now();
290
- event.dispatcher.removeListener(event.step.before, registerStep);
291
- });
292
- } else {
293
- try {
294
- this.startTime = Date.now();
295
- result = fn.apply(this.context, this.args);
296
- } catch (error) {
297
- this.setStatus('failed');
298
- throw error;
299
- } finally {
300
- this.endTime = Date.now();
301
- event.dispatcher.removeListener(event.step.before, registerStep);
302
- }
303
- }
304
-
305
- return result;
306
- }
307
- }
308
-
309
- Step.TIMEOUTS = {};
310
-
311
- /** @type {Class<MetaStep>} */
312
- Step.MetaStep = MetaStep;
313
-
314
- module.exports = Step;
315
-
316
- function dryRunResolver() {
317
- return {
318
- get(target, prop) {
319
- if (prop === 'toString') return () => '<VALUE>';
320
- return new Proxy({}, dryRunResolver());
321
- },
322
- };
323
- }
324
-
325
- function humanizeString(string) {
326
- // split strings by words, then make them all lowercase
327
- const _result = string.replace(/([a-z](?=[A-Z]))/g, '$1 ')
328
- .split(' ')
329
- .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'
330
16
 
331
- _result[0] = _result[0] === 'i' ? capitalizeFLetter(_result[0]) : _result[0];
332
- return _result.join(' ').trim();
333
- }
17
+ /**
18
+ * Step used to execute a single function
19
+ */
20
+ import FuncStep from './step/func.js'
334
21
 
335
- function capitalizeFLetter(string) {
336
- return (string[0].toUpperCase() + string.slice(1));
337
- }
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
@@ -3,12 +3,44 @@
3
3
  * @namespace
4
4
  */
5
5
  const store = {
6
- /** @type {boolean} */
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
- module.exports = store;
46
+ export default store
@@ -6,17 +6,8 @@ heal.addRecipe('ai', {
6
6
  html: ({ I }) => I.grabHTMLFrom('body'),
7
7
  },
8
8
  suggest: true,
9
- steps: [
10
- 'click',
11
- 'fillField',
12
- 'appendField',
13
- 'selectOption',
14
- 'attachFile',
15
- 'checkOption',
16
- 'uncheckOption',
17
- 'doubleClick',
18
- ],
19
- fn: async (args) => {
9
+ steps: ['click', 'fillField', 'appendField', 'selectOption', 'attachFile', 'checkOption', 'uncheckOption', 'doubleClick'],
10
+ fn: async args => {
20
11
  return ai.healFailedStep(args)
21
12
  },
22
13
  })
package/lib/timeout.js ADDED
@@ -0,0 +1,60 @@
1
+ const TIMEOUT_ORDER = {
2
+ /**
3
+ * timeouts set with order below zero only override timeouts of higher order if their value is smaller
4
+ */
5
+ testOrSuite: -5,
6
+ /**
7
+ * 0-9 - designated for override of timeouts set from code, 5 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=true
8
+ */
9
+ stepTimeoutHard: 5,
10
+ /**
11
+ * 10-19 - designated for timeouts set from code, 15 is order of I.setTimeout(t) operation
12
+ */
13
+ codeLimitTime: 15,
14
+ /**
15
+ * 20-29 - designated for timeout settings which could be overriden in tests code, 25 is used by stepTimeout plugin when stepTimeout.config.overrideStepLimits=false
16
+ */
17
+ stepTimeoutSoft: 25,
18
+ }
19
+
20
+ function getCurrentTimeout(timeouts) {
21
+ let totalTimeout
22
+ // iterate over all timeouts starting from highest values of order
23
+ new Map([...timeouts.entries()].sort().reverse()).forEach((timeout, order) => {
24
+ if (
25
+ timeout !== undefined &&
26
+ // when orders >= 0 - timeout value overrides those set with higher order elements
27
+ (order >= 0 ||
28
+ // when `order < 0 && totalTimeout === undefined` - timeout is used when nothing is set by elements with higher order
29
+ totalTimeout === undefined ||
30
+ // when `order < 0` - timeout overrides higher values of timeout or 'no timeout' (totalTimeout === 0) set by elements with higher order
31
+ (timeout > 0 && (timeout < totalTimeout || totalTimeout === 0)))
32
+ ) {
33
+ totalTimeout = timeout
34
+ }
35
+ })
36
+ return totalTimeout
37
+ }
38
+
39
+ class TimeoutError extends Error {
40
+ constructor(message) {
41
+ super(message)
42
+ this.name = 'TimeoutError'
43
+ }
44
+ }
45
+
46
+ class TestTimeoutError extends TimeoutError {
47
+ constructor(timeout) {
48
+ super(`Timeout ${timeout}s exceeded (with Before hook)`)
49
+ this.name = 'TestTimeoutError'
50
+ }
51
+ }
52
+
53
+ class StepTimeoutError extends TimeoutError {
54
+ constructor(timeout, step) {
55
+ super(`Step ${step.toCode().trim()} timed out after ${timeout}s`)
56
+ this.name = 'StepTimeoutError'
57
+ }
58
+ }
59
+
60
+ export { TIMEOUT_ORDER, getCurrentTimeout, TimeoutError, TestTimeoutError, StepTimeoutError }
package/lib/transform.js CHANGED
@@ -1,26 +1,26 @@
1
1
  const transformers = {
2
2
  'gherkin.examples': [],
3
- };
3
+ }
4
4
 
5
5
  function transform(target, value) {
6
6
  if (target in transformers) {
7
7
  for (const transform of transformers[target]) {
8
- value = transform(value);
8
+ value = transform(value)
9
9
  }
10
10
  }
11
- return value;
11
+ return value
12
12
  }
13
13
 
14
14
  transform.addTransformer = function (target, transformer) {
15
15
  if (target in transformers) {
16
- transformers[target].push(transformer);
16
+ transformers[target].push(transformer)
17
17
  }
18
- };
18
+ }
19
19
 
20
20
  transform.addTransformerBeforeAll = function (target, transformer) {
21
21
  if (target in transformers) {
22
- transformers[target].unshift(transformer);
22
+ transformers[target].unshift(transformer)
23
23
  }
24
- };
24
+ }
25
25
 
26
- module.exports = transform;
26
+ export default transform
@@ -1,55 +1,69 @@
1
- const merge = require('lodash.merge');
2
- const path = require('path');
1
+ import merge from 'lodash.merge'
2
+ import path from 'path'
3
+ import { createRequire } from 'module'
3
4
 
4
5
  const defaultVocabulary = {
5
6
  I: 'I',
6
7
  actions: {},
7
- };
8
+ }
8
9
 
9
10
  class Translation {
10
11
  constructor(vocabulary, loaded) {
11
- this.vocabulary = vocabulary;
12
- this.loaded = loaded !== false;
12
+ this.vocabulary = vocabulary
13
+ this.loaded = loaded !== false
13
14
  }
14
15
 
15
16
  loadVocabulary(vocabularyFile) {
16
- if (!vocabularyFile) return;
17
- const filePath = path.join(global.codecept_dir, vocabularyFile);
17
+ if (!vocabularyFile) return
18
+ const filePath = path.join(global.codecept_dir, vocabularyFile)
18
19
 
19
20
  try {
20
- const vocabulary = require(filePath);
21
- this.vocabulary = merge(this.vocabulary, vocabulary);
21
+ const require = createRequire(import.meta.url)
22
+ const vocabulary = require(filePath)
23
+ this.vocabulary = merge(this.vocabulary, vocabulary)
22
24
  } catch (err) {
23
- throw new Error(`Can't load vocabulary from ${filePath}; ${err}`);
25
+ throw new Error(`Can't load vocabulary from ${filePath}; ${err}`)
24
26
  }
25
27
  }
26
28
 
27
29
  value(val) {
28
- return this.vocabulary[val];
30
+ return this.vocabulary[val]
29
31
  }
30
32
 
31
33
  actionAliasFor(actualActionName) {
32
34
  if (this.vocabulary.actions && this.vocabulary.actions[actualActionName]) {
33
- return this.vocabulary.actions[actualActionName];
35
+ return this.vocabulary.actions[actualActionName]
34
36
  }
35
- return actualActionName;
37
+ return actualActionName
36
38
  }
37
39
 
38
40
  get I() {
39
- return this.vocabulary.I;
41
+ return this.vocabulary.I
42
+ }
43
+
44
+ static async getLangs() {
45
+ const translations = await import('../translations/index.js')
46
+ return translations.default
40
47
  }
41
48
 
42
49
  static get langs() {
43
- return require('../translations');
50
+ // Synchronous fallback - may be empty initially
51
+ if (!this._cachedLangs) {
52
+ this.getLangs().then(langs => {
53
+ this._cachedLangs = langs
54
+ })
55
+ return {}
56
+ }
57
+ return this._cachedLangs
44
58
  }
45
59
 
46
60
  static createDefault() {
47
- return new Translation(defaultVocabulary, true);
61
+ return new Translation(defaultVocabulary, true)
48
62
  }
49
63
 
50
64
  static createEmpty() {
51
- return new Translation(defaultVocabulary, false);
65
+ return new Translation(defaultVocabulary, false)
52
66
  }
53
67
  }
54
68
 
55
- module.exports = Translation;
69
+ export default Translation