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
package/lib/recorder.js CHANGED
@@ -1,27 +1,27 @@
1
- const debug = require('debug')('codeceptjs:recorder');
2
- const promiseRetry = require('promise-retry');
3
- const chalk = require('chalk');
4
- const { printObjectProperties } = require('./utils');
5
- const { log } = require('./output');
6
-
7
- const MAX_TASKS = 100;
8
-
9
- let promise;
10
- let running = false;
11
- let errFn;
12
- let queueId = 0;
13
- let sessionId = null;
14
- let asyncErr = null;
15
- let ignoredErrs = [];
16
-
17
- let tasks = [];
18
- let oldPromises = [];
1
+ const debug = require('debug')('codeceptjs:recorder')
2
+ const promiseRetry = require('promise-retry')
3
+ const chalk = require('chalk')
4
+ const { printObjectProperties } = require('./utils')
5
+ const { log } = require('./output')
6
+ const { TimeoutError } = require('./timeout')
7
+ const MAX_TASKS = 100
8
+
9
+ let promise
10
+ let running = false
11
+ let errFn
12
+ let queueId = 0
13
+ let sessionId = null
14
+ let asyncErr = null
15
+ let ignoredErrs = []
16
+
17
+ let tasks = []
18
+ let oldPromises = []
19
19
 
20
20
  const defaultRetryOptions = {
21
21
  retries: 0,
22
22
  minTimeout: 150,
23
23
  maxTimeout: 10000,
24
- };
24
+ }
25
25
 
26
26
  /**
27
27
  * Singleton object to record all test steps as promises and run them in chain.
@@ -29,7 +29,6 @@ const defaultRetryOptions = {
29
29
  * @interface
30
30
  */
31
31
  module.exports = {
32
-
33
32
  /**
34
33
  * @type {Array<Object<string, *>>}
35
34
  * @inner
@@ -43,11 +42,11 @@ module.exports = {
43
42
  * @inner
44
43
  */
45
44
  start() {
46
- debug('Starting recording promises');
47
- running = true;
48
- asyncErr = null;
49
- errFn = null;
50
- this.reset();
45
+ debug('Starting recording promises')
46
+ running = true
47
+ asyncErr = null
48
+ errFn = null
49
+ this.reset()
51
50
  },
52
51
 
53
52
  /**
@@ -55,7 +54,7 @@ module.exports = {
55
54
  * @inner
56
55
  */
57
56
  isRunning() {
58
- return running;
57
+ return running
59
58
  },
60
59
 
61
60
  /**
@@ -64,7 +63,7 @@ module.exports = {
64
63
  */
65
64
  startUnlessRunning() {
66
65
  if (!this.isRunning()) {
67
- this.start();
66
+ this.start()
68
67
  }
69
68
  },
70
69
 
@@ -76,7 +75,7 @@ module.exports = {
76
75
  * @inner
77
76
  */
78
77
  errHandler(fn) {
79
- errFn = fn;
78
+ errFn = fn
80
79
  },
81
80
 
82
81
  /**
@@ -87,16 +86,16 @@ module.exports = {
87
86
  * @inner
88
87
  */
89
88
  reset() {
90
- if (promise && running) this.catch();
91
- queueId++;
92
- sessionId = null;
93
- asyncErr = null;
94
- log(`${currentQueue()} Starting recording promises`);
95
- promise = Promise.resolve();
96
- oldPromises = [];
97
- tasks = [];
98
- ignoredErrs = [];
99
- this.session.running = false;
89
+ if (promise && running) this.catch()
90
+ queueId++
91
+ sessionId = null
92
+ asyncErr = null
93
+ log(`${currentQueue()} Starting recording promises`)
94
+ promise = Promise.resolve()
95
+ oldPromises = []
96
+ tasks = []
97
+ ignoredErrs = []
98
+ this.session.running = false
100
99
  // reset this retries makes the retryFailedStep plugin won't work if there is Before/BeforeSuit block due to retries is undefined on Scenario
101
100
  // this.retries = [];
102
101
  },
@@ -123,12 +122,16 @@ module.exports = {
123
122
  * @inner
124
123
  */
125
124
  start(name) {
126
- debug(`${currentQueue()}Starting <${name}> session`);
127
- tasks.push('--->');
128
- oldPromises.push(promise);
129
- this.running = true;
130
- sessionId = name;
131
- promise = Promise.resolve();
125
+ if (sessionId) {
126
+ debug(`${currentQueue()}Session already started as ${sessionId}`)
127
+ this.restore(sessionId)
128
+ }
129
+ debug(`${currentQueue()}Starting <${name}> session`)
130
+ tasks.push('--->')
131
+ oldPromises.push(promise)
132
+ this.running = true
133
+ sessionId = name
134
+ promise = Promise.resolve()
132
135
  },
133
136
 
134
137
  /**
@@ -136,12 +139,12 @@ module.exports = {
136
139
  * @inner
137
140
  */
138
141
  restore(name) {
139
- tasks.push('<---');
140
- debug(`${currentQueue()}Finalize <${name}> session`);
141
- this.running = false;
142
- sessionId = null;
143
- this.catch(errFn);
144
- promise = promise.then(() => oldPromises.pop());
142
+ tasks.push('<---')
143
+ debug(`${currentQueue()}Finalize <${name}> session`)
144
+ this.running = false
145
+ sessionId = null
146
+ this.catch(errFn)
147
+ promise = promise.then(() => oldPromises.pop())
145
148
  },
146
149
 
147
150
  /**
@@ -149,9 +152,8 @@ module.exports = {
149
152
  * @inner
150
153
  */
151
154
  catch(fn) {
152
- promise = promise.catch(fn);
155
+ promise = promise.catch(fn)
153
156
  },
154
-
155
157
  },
156
158
 
157
159
  /**
@@ -171,42 +173,48 @@ module.exports = {
171
173
  */
172
174
  add(taskName, fn = undefined, force = false, retry = undefined, timeout = undefined) {
173
175
  if (typeof taskName === 'function') {
174
- fn = taskName;
175
- taskName = fn.toString();
176
- if (retry === undefined) retry = false;
176
+ fn = taskName
177
+ taskName = fn.toString()
178
+ if (retry === undefined) retry = false
177
179
  }
178
- if (retry === undefined) retry = true;
180
+ if (retry === undefined) retry = true
179
181
  if (!running && !force) {
180
- return;
182
+ return Promise.resolve()
181
183
  }
182
- tasks.push(taskName);
183
- debug(chalk.gray(`${currentQueue()} Queued | ${taskName}`));
184
+ tasks.push(taskName)
185
+ debug(chalk.gray(`${currentQueue()} Queued | ${taskName}`))
184
186
 
185
- return promise = Promise.resolve(promise).then((res) => {
187
+ return (promise = Promise.resolve(promise).then(res => {
186
188
  // prefer options for non-conditional retries
187
- const retryOpts = this.retries.sort((r1, r2) => r1.when && !r2.when).slice(-1).pop();
189
+ const retryOpts = this.retries
190
+ .sort((r1, r2) => r1.when && !r2.when)
191
+ .slice(-1)
192
+ .pop()
188
193
  // no retries or unnamed tasks
194
+ debug(`${currentQueue()} Running | ${taskName} | Timeout: ${timeout || 'None'}`)
195
+ if (retryOpts) debug(`${currentQueue()} Retry opts`, JSON.stringify(retryOpts))
196
+
189
197
  if (!retryOpts || !taskName || !retry) {
190
- const [promise, timer] = getTimeoutPromise(timeout, taskName);
191
- return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer));
198
+ const [promise, timer] = getTimeoutPromise(timeout, taskName)
199
+ return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer))
192
200
  }
193
201
 
194
- debug(`${currentQueue()} Running | ${taskName}`);
195
-
196
- const retryRules = this.retries.slice().reverse();
202
+ const retryRules = this.retries.slice().reverse()
197
203
  return promiseRetry(Object.assign(defaultRetryOptions, retryOpts), (retry, number) => {
198
- if (number > 1) log(`${currentQueue()}Retrying... Attempt #${number}`);
199
- const [promise, timer] = getTimeoutPromise(timeout, taskName);
200
- return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer)).catch((err) => {
201
- if (ignoredErrs.includes(err)) return;
202
- for (const retryObj of retryRules) {
203
- if (!retryObj.when) return retry(err);
204
- if (retryObj.when && retryObj.when(err)) return retry(err);
205
- }
206
- throw err;
207
- });
208
- });
209
- });
204
+ if (number > 1) log(`${currentQueue()}Retrying... Attempt #${number}`)
205
+ const [promise, timer] = getTimeoutPromise(timeout, taskName)
206
+ return Promise.race([promise, Promise.resolve(res).then(fn)])
207
+ .finally(() => clearTimeout(timer))
208
+ .catch(err => {
209
+ if (ignoredErrs.includes(err)) return
210
+ for (const retryObj of retryRules) {
211
+ if (!retryObj.when) return retry(err)
212
+ if (retryObj.when && retryObj.when(err)) return retry(err)
213
+ }
214
+ throw err
215
+ })
216
+ })
217
+ }))
210
218
  },
211
219
 
212
220
  /**
@@ -215,15 +223,15 @@ module.exports = {
215
223
  * @inner
216
224
  */
217
225
  retry(opts) {
218
- if (!promise) return;
226
+ if (!promise) return
219
227
 
220
228
  if (opts === null) {
221
- opts = {};
229
+ opts = {}
222
230
  }
223
231
  if (Number.isInteger(opts)) {
224
- opts = { retries: opts };
232
+ opts = { retries: opts }
225
233
  }
226
- return this.add(() => this.retries.push(opts));
234
+ return this.add(() => this.retries.push(opts))
227
235
  },
228
236
 
229
237
  /**
@@ -232,20 +240,25 @@ module.exports = {
232
240
  * @inner
233
241
  */
234
242
  catch(customErrFn) {
235
- const fnDescription = customErrFn?.toString()?.replace(/\s{2,}/g, ' ').replace(/\n/g, ' ')?.slice(0, 50);
236
- debug(chalk.gray(`${currentQueue()} Queued | catch with error handler ${fnDescription || ''}`));
237
- return promise = promise.catch((err) => {
238
- log(`${currentQueue()}Error | ${err} ${fnDescription}...`);
239
- if (!(err instanceof Error)) { // strange things may happen
240
- err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`); // we should be prepared for them
243
+ const fnDescription = customErrFn
244
+ ?.toString()
245
+ ?.replace(/\s{2,}/g, ' ')
246
+ .replace(/\n/g, ' ')
247
+ ?.slice(0, 50)
248
+ debug(chalk.gray(`${currentQueue()} Queued | catch with error handler ${fnDescription || ''}`))
249
+ return (promise = promise.catch(err => {
250
+ log(`${currentQueue()}Error | ${err} ${fnDescription}...`)
251
+ if (!(err instanceof Error)) {
252
+ // strange things may happen
253
+ err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`) // we should be prepared for them
241
254
  }
242
255
  if (customErrFn) {
243
- customErrFn(err);
256
+ customErrFn(err)
244
257
  } else if (errFn) {
245
- errFn(err);
258
+ errFn(err)
246
259
  }
247
- this.stop();
248
- });
260
+ this.stop()
261
+ }))
249
262
  },
250
263
 
251
264
  /**
@@ -254,17 +267,22 @@ module.exports = {
254
267
  * @inner
255
268
  */
256
269
  catchWithoutStop(customErrFn) {
257
- const fnDescription = customErrFn?.toString()?.replace(/\s{2,}/g, ' ').replace(/\n/g, ' ')?.slice(0, 50);
258
- return promise = promise.catch((err) => {
259
- if (ignoredErrs.includes(err)) return; // already caught
260
- log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`);
261
- if (!(err instanceof Error)) { // strange things may happen
262
- err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`); // we should be prepared for them
270
+ const fnDescription = customErrFn
271
+ ?.toString()
272
+ ?.replace(/\s{2,}/g, ' ')
273
+ .replace(/\n/g, ' ')
274
+ ?.slice(0, 50)
275
+ return (promise = promise.catch(err => {
276
+ if (ignoredErrs.includes(err)) return // already caught
277
+ log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`)
278
+ if (!(err instanceof Error)) {
279
+ // strange things may happen
280
+ err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`) // we should be prepared for them
263
281
  }
264
282
  if (customErrFn) {
265
- return customErrFn(err);
283
+ return customErrFn(err)
266
284
  }
267
- });
285
+ }))
268
286
  },
269
287
 
270
288
  /**
@@ -276,15 +294,15 @@ module.exports = {
276
294
  */
277
295
 
278
296
  throw(err) {
279
- if (ignoredErrs.includes(err)) return promise; // already caught
297
+ if (ignoredErrs.includes(err)) return promise // already caught
280
298
  return this.add(`throw error: ${err.message}`, () => {
281
- if (ignoredErrs.includes(err)) return; // already caught
282
- throw err;
283
- });
299
+ if (ignoredErrs.includes(err)) return // already caught
300
+ throw err
301
+ })
284
302
  },
285
303
 
286
304
  ignoreErr(err) {
287
- ignoredErrs.push(err);
305
+ ignoredErrs.push(err)
288
306
  },
289
307
 
290
308
  /**
@@ -293,7 +311,7 @@ module.exports = {
293
311
  */
294
312
  saveFirstAsyncError(err) {
295
313
  if (asyncErr === null) {
296
- asyncErr = err;
314
+ asyncErr = err
297
315
  }
298
316
  },
299
317
 
@@ -302,7 +320,7 @@ module.exports = {
302
320
  * @inner
303
321
  */
304
322
  getAsyncErr() {
305
- return asyncErr;
323
+ return asyncErr
306
324
  },
307
325
 
308
326
  /**
@@ -310,7 +328,7 @@ module.exports = {
310
328
  * @inner
311
329
  */
312
330
  cleanAsyncErr() {
313
- asyncErr = null;
331
+ asyncErr = null
314
332
  },
315
333
 
316
334
  /**
@@ -319,9 +337,9 @@ module.exports = {
319
337
  * @inner
320
338
  */
321
339
  stop() {
322
- debug(this.toString());
323
- log(`${currentQueue()} Stopping recording promises`);
324
- running = false;
340
+ debug(this.toString())
341
+ log(`${currentQueue()} Stopping recording promises`)
342
+ running = false
325
343
  },
326
344
 
327
345
  /**
@@ -332,7 +350,7 @@ module.exports = {
332
350
  * @inner
333
351
  */
334
352
  promise() {
335
- return promise;
353
+ return promise
336
354
  },
337
355
 
338
356
  /**
@@ -341,7 +359,7 @@ module.exports = {
341
359
  * @inner
342
360
  */
343
361
  scheduled() {
344
- return tasks.slice(-MAX_TASKS).join('\n');
362
+ return tasks.slice(-MAX_TASKS).join('\n')
345
363
  },
346
364
 
347
365
  /**
@@ -350,7 +368,7 @@ module.exports = {
350
368
  * @inner
351
369
  */
352
370
  getQueueId() {
353
- return queueId;
371
+ return queueId
354
372
  },
355
373
 
356
374
  /**
@@ -359,21 +377,34 @@ module.exports = {
359
377
  * @inner
360
378
  */
361
379
  toString() {
362
- return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`;
380
+ return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`
363
381
  },
364
382
 
365
- };
383
+ /**
384
+ * Get current session ID
385
+ * @return {string|null}
386
+ * @inner
387
+ */
388
+ getCurrentSessionId() {
389
+ return sessionId
390
+ },
391
+ }
366
392
 
367
393
  function getTimeoutPromise(timeoutMs, taskName) {
368
- let timer;
369
- if (timeoutMs) debug(`Timing out in ${timeoutMs}ms`);
370
- return [new Promise((done, reject) => {
371
- timer = setTimeout(() => { reject(new Error(`Action ${taskName} was interrupted on step timeout ${timeoutMs}ms`)); }, timeoutMs || 2e9);
372
- }), timer];
394
+ let timer
395
+ if (timeoutMs) debug(`Timing out in ${timeoutMs}ms`)
396
+ return [
397
+ new Promise((done, reject) => {
398
+ timer = setTimeout(() => {
399
+ reject(new TimeoutError(`Action ${taskName} was interrupted on timeout ${timeoutMs}ms`))
400
+ }, timeoutMs || 2e9)
401
+ }),
402
+ timer,
403
+ ]
373
404
  }
374
405
 
375
406
  function currentQueue() {
376
- let session = '';
377
- if (sessionId) session = `<${sessionId}> `;
378
- return `[${queueId}] ${session}`;
407
+ let session = ''
408
+ if (sessionId) session = `<${sessionId}> `
409
+ return `[${queueId}] ${session}`
379
410
  }
package/lib/rerun.js CHANGED
@@ -1,81 +1,82 @@
1
- const fsPath = require('path');
2
- const container = require('./container');
3
- const event = require('./event');
4
- const BaseCodecept = require('./codecept');
5
- const output = require('./output');
1
+ const fsPath = require('path')
2
+ const container = require('./container')
3
+ const event = require('./event')
4
+ const BaseCodecept = require('./codecept')
5
+ const output = require('./output')
6
6
 
7
7
  class CodeceptRerunner extends BaseCodecept {
8
8
  runOnce(test) {
9
9
  return new Promise((resolve, reject) => {
10
10
  // @ts-ignore
11
- container.createMocha();
12
- const mocha = container.mocha();
13
- this.testFiles.forEach((file) => {
14
- delete require.cache[file];
15
- });
16
- mocha.files = this.testFiles;
11
+ container.createMocha()
12
+ const mocha = container.mocha()
13
+ this.testFiles.forEach(file => {
14
+ delete require.cache[file]
15
+ })
16
+ mocha.files = this.testFiles
17
17
  if (test) {
18
18
  if (!fsPath.isAbsolute(test)) {
19
- test = fsPath.join(global.codecept_dir, test);
19
+ test = fsPath.join(global.codecept_dir, test)
20
20
  }
21
- mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test);
21
+ mocha.files = mocha.files.filter(t => fsPath.basename(t, '.js') === test || t === test)
22
22
  }
23
23
  try {
24
- mocha.run((failures) => {
24
+ mocha.run(failures => {
25
25
  if (failures === 0) {
26
- resolve();
26
+ resolve()
27
27
  } else {
28
- reject(new Error(`${failures} tests fail`));
28
+ reject(new Error(`${failures} tests fail`))
29
29
  }
30
- });
30
+ })
31
31
  } catch (e) {
32
- reject(e);
32
+ reject(e)
33
33
  }
34
- });
34
+ })
35
35
  }
36
36
 
37
37
  async runTests(test) {
38
- const configRerun = this.config.rerun || {};
39
- const minSuccess = configRerun.minSuccess || 1;
40
- const maxReruns = configRerun.maxReruns || 1;
38
+ const configRerun = this.config.rerun || {}
39
+ const minSuccess = configRerun.minSuccess || 1
40
+ const maxReruns = configRerun.maxReruns || 1
41
41
  if (minSuccess > maxReruns) {
42
- process.exitCode = 1;
43
- throw new Error(`run-rerun Configuration Error: minSuccess must be less than maxReruns. Current values: minSuccess=${minSuccess} maxReruns=${maxReruns}`);
42
+ process.exitCode = 1
43
+ throw new Error(`run-rerun Configuration Error: minSuccess must be less than maxReruns. Current values: minSuccess=${minSuccess} maxReruns=${maxReruns}`)
44
44
  }
45
45
  if (maxReruns === 1) {
46
- await this.runOnce(test);
47
- return;
46
+ await this.runOnce(test)
47
+ return
48
48
  }
49
- let successCounter = 0;
50
- let rerunsCounter = 0;
49
+ let successCounter = 0
50
+ let rerunsCounter = 0
51
51
  while (rerunsCounter < maxReruns && successCounter < minSuccess) {
52
- rerunsCounter++;
52
+ container.result().reset() // reset result
53
+ rerunsCounter++
53
54
  try {
54
- await this.runOnce(test);
55
- successCounter++;
56
- output.success(`\nProcess run ${rerunsCounter} of max ${maxReruns}, success runs ${successCounter}/${minSuccess}\n`);
55
+ await this.runOnce(test)
56
+ successCounter++
57
+ output.success(`\nProcess run ${rerunsCounter} of max ${maxReruns}, success runs ${successCounter}/${minSuccess}\n`)
57
58
  } catch (e) {
58
- output.error(`\nFail run ${rerunsCounter} of max ${maxReruns}, success runs ${successCounter}/${minSuccess} \n`);
59
- console.error(e);
59
+ output.error(`\nFail run ${rerunsCounter} of max ${maxReruns}, success runs ${successCounter}/${minSuccess} \n`)
60
+ console.error(e)
60
61
  }
61
62
  }
62
63
  if (successCounter < minSuccess) {
63
- throw new Error(`Flaky tests detected! ${successCounter} success runs achieved instead of ${minSuccess} success runs expected`);
64
+ throw new Error(`Flaky tests detected! ${successCounter} success runs achieved instead of ${minSuccess} success runs expected`)
64
65
  }
65
66
  }
66
67
 
67
68
  async run(test) {
68
- event.emit(event.all.before, this);
69
+ event.emit(event.all.before, this)
69
70
  try {
70
- await this.runTests(test);
71
+ await this.runTests(test)
71
72
  } catch (e) {
72
- output.error(e.stack);
73
- throw e;
73
+ output.error(e.stack)
74
+ throw e
74
75
  } finally {
75
- event.emit(event.all.result, this);
76
- event.emit(event.all.after, this);
76
+ event.emit(event.all.result, this)
77
+ event.emit(event.all.after, this)
77
78
  }
78
79
  }
79
80
  }
80
81
 
81
- module.exports = CodeceptRerunner;
82
+ module.exports = CodeceptRerunner