codeceptjs 3.6.10 → 3.7.0-beta.10

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 (127) hide show
  1. package/README.md +89 -119
  2. package/bin/codecept.js +9 -2
  3. package/docs/webapi/clearCookie.mustache +1 -1
  4. package/lib/actor.js +66 -102
  5. package/lib/ai.js +130 -121
  6. package/lib/assert/empty.js +3 -5
  7. package/lib/assert/equal.js +4 -7
  8. package/lib/assert/include.js +4 -6
  9. package/lib/assert/throws.js +2 -4
  10. package/lib/assert/truth.js +2 -2
  11. package/lib/codecept.js +87 -83
  12. package/lib/command/check.js +186 -0
  13. package/lib/command/configMigrate.js +2 -4
  14. package/lib/command/definitions.js +8 -26
  15. package/lib/command/generate.js +10 -14
  16. package/lib/command/gherkin/snippets.js +10 -8
  17. package/lib/command/gherkin/steps.js +1 -1
  18. package/lib/command/info.js +1 -3
  19. package/lib/command/init.js +8 -12
  20. package/lib/command/interactive.js +2 -2
  21. package/lib/command/list.js +1 -1
  22. package/lib/command/run-multiple.js +12 -35
  23. package/lib/command/run-workers.js +5 -57
  24. package/lib/command/utils.js +5 -6
  25. package/lib/command/workers/runTests.js +68 -232
  26. package/lib/container.js +354 -237
  27. package/lib/data/context.js +10 -13
  28. package/lib/data/dataScenarioConfig.js +8 -8
  29. package/lib/data/dataTableArgument.js +6 -6
  30. package/lib/data/table.js +5 -11
  31. package/lib/effects.js +218 -0
  32. package/lib/els.js +158 -0
  33. package/lib/event.js +19 -17
  34. package/lib/heal.js +88 -80
  35. package/lib/helper/AI.js +2 -1
  36. package/lib/helper/ApiDataFactory.js +3 -6
  37. package/lib/helper/Appium.js +45 -51
  38. package/lib/helper/FileSystem.js +3 -3
  39. package/lib/helper/GraphQLDataFactory.js +3 -3
  40. package/lib/helper/JSONResponse.js +57 -37
  41. package/lib/helper/Nightmare.js +35 -53
  42. package/lib/helper/Playwright.js +211 -252
  43. package/lib/helper/Protractor.js +54 -77
  44. package/lib/helper/Puppeteer.js +139 -232
  45. package/lib/helper/REST.js +5 -17
  46. package/lib/helper/TestCafe.js +21 -44
  47. package/lib/helper/WebDriver.js +131 -169
  48. package/lib/helper/testcafe/testcafe-utils.js +26 -27
  49. package/lib/listener/emptyRun.js +55 -0
  50. package/lib/listener/exit.js +7 -10
  51. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  52. package/lib/listener/globalTimeout.js +165 -0
  53. package/lib/listener/helpers.js +15 -15
  54. package/lib/listener/mocha.js +1 -1
  55. package/lib/listener/result.js +12 -0
  56. package/lib/listener/steps.js +20 -18
  57. package/lib/listener/store.js +20 -0
  58. package/lib/mocha/asyncWrapper.js +216 -0
  59. package/lib/{interfaces → mocha}/bdd.js +3 -3
  60. package/lib/mocha/cli.js +308 -0
  61. package/lib/mocha/factory.js +104 -0
  62. package/lib/{interfaces → mocha}/featureConfig.js +24 -12
  63. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  64. package/lib/mocha/hooks.js +112 -0
  65. package/lib/mocha/index.js +12 -0
  66. package/lib/mocha/inject.js +29 -0
  67. package/lib/{interfaces → mocha}/scenarioConfig.js +21 -6
  68. package/lib/mocha/suite.js +81 -0
  69. package/lib/mocha/test.js +159 -0
  70. package/lib/mocha/types.d.ts +42 -0
  71. package/lib/mocha/ui.js +219 -0
  72. package/lib/output.js +82 -62
  73. package/lib/pause.js +155 -138
  74. package/lib/plugin/analyze.js +349 -0
  75. package/lib/plugin/autoDelay.js +6 -6
  76. package/lib/plugin/autoLogin.js +6 -7
  77. package/lib/plugin/commentStep.js +6 -1
  78. package/lib/plugin/coverage.js +10 -19
  79. package/lib/plugin/customLocator.js +3 -3
  80. package/lib/plugin/customReporter.js +52 -0
  81. package/lib/plugin/eachElement.js +1 -1
  82. package/lib/plugin/fakerTransform.js +1 -1
  83. package/lib/plugin/heal.js +36 -9
  84. package/lib/plugin/pageInfo.js +140 -0
  85. package/lib/plugin/retryFailedStep.js +4 -4
  86. package/lib/plugin/retryTo.js +18 -118
  87. package/lib/plugin/screenshotOnFail.js +17 -49
  88. package/lib/plugin/selenoid.js +15 -35
  89. package/lib/plugin/standardActingHelpers.js +4 -1
  90. package/lib/plugin/stepByStepReport.js +56 -17
  91. package/lib/plugin/stepTimeout.js +5 -12
  92. package/lib/plugin/subtitles.js +4 -4
  93. package/lib/plugin/tryTo.js +17 -107
  94. package/lib/plugin/wdio.js +8 -10
  95. package/lib/recorder.js +146 -125
  96. package/lib/rerun.js +43 -42
  97. package/lib/result.js +161 -0
  98. package/lib/secret.js +1 -1
  99. package/lib/step/base.js +228 -0
  100. package/lib/step/config.js +50 -0
  101. package/lib/step/func.js +46 -0
  102. package/lib/step/helper.js +50 -0
  103. package/lib/step/meta.js +99 -0
  104. package/lib/step/record.js +74 -0
  105. package/lib/step/retry.js +11 -0
  106. package/lib/step/section.js +55 -0
  107. package/lib/step.js +21 -332
  108. package/lib/steps.js +50 -0
  109. package/lib/store.js +10 -2
  110. package/lib/template/heal.js +2 -11
  111. package/lib/timeout.js +66 -0
  112. package/lib/utils.js +317 -216
  113. package/lib/within.js +73 -55
  114. package/lib/workers.js +259 -275
  115. package/package.json +56 -54
  116. package/typings/index.d.ts +175 -186
  117. package/typings/promiseBasedTypes.d.ts +164 -17
  118. package/typings/types.d.ts +284 -115
  119. package/lib/cli.js +0 -256
  120. package/lib/helper/ExpectHelper.js +0 -391
  121. package/lib/helper/SoftExpectHelper.js +0 -381
  122. package/lib/listener/artifacts.js +0 -19
  123. package/lib/listener/timeout.js +0 -109
  124. package/lib/mochaFactory.js +0 -113
  125. package/lib/plugin/debugErrors.js +0 -67
  126. package/lib/scenario.js +0 -224
  127. 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,47 @@ 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
+
189
196
  if (!retryOpts || !taskName || !retry) {
190
- const [promise, timer] = getTimeoutPromise(timeout, taskName);
191
- return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer));
197
+ const [promise, timer] = getTimeoutPromise(timeout, taskName)
198
+ return Promise.race([promise, Promise.resolve(res).then(fn)]).finally(() => clearTimeout(timer))
192
199
  }
193
200
 
194
- debug(`${currentQueue()} Running | ${taskName}`);
195
-
196
- const retryRules = this.retries.slice().reverse();
201
+ const retryRules = this.retries.slice().reverse()
197
202
  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
- });
203
+ if (number > 1) log(`${currentQueue()}Retrying... Attempt #${number}`)
204
+ const [promise, timer] = getTimeoutPromise(timeout, taskName)
205
+ return Promise.race([promise, Promise.resolve(res).then(fn)])
206
+ .finally(() => clearTimeout(timer))
207
+ .catch(err => {
208
+ if (ignoredErrs.includes(err)) return
209
+ for (const retryObj of retryRules) {
210
+ if (!retryObj.when) return retry(err)
211
+ if (retryObj.when && retryObj.when(err)) return retry(err)
212
+ }
213
+ throw err
214
+ })
215
+ })
216
+ }))
210
217
  },
211
218
 
212
219
  /**
@@ -215,15 +222,15 @@ module.exports = {
215
222
  * @inner
216
223
  */
217
224
  retry(opts) {
218
- if (!promise) return;
225
+ if (!promise) return
219
226
 
220
227
  if (opts === null) {
221
- opts = {};
228
+ opts = {}
222
229
  }
223
230
  if (Number.isInteger(opts)) {
224
- opts = { retries: opts };
231
+ opts = { retries: opts }
225
232
  }
226
- return this.add(() => this.retries.push(opts));
233
+ return this.add(() => this.retries.push(opts))
227
234
  },
228
235
 
229
236
  /**
@@ -232,20 +239,25 @@ module.exports = {
232
239
  * @inner
233
240
  */
234
241
  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
242
+ const fnDescription = customErrFn
243
+ ?.toString()
244
+ ?.replace(/\s{2,}/g, ' ')
245
+ .replace(/\n/g, ' ')
246
+ ?.slice(0, 50)
247
+ debug(chalk.gray(`${currentQueue()} Queued | catch with error handler ${fnDescription || ''}`))
248
+ return (promise = promise.catch(err => {
249
+ log(`${currentQueue()}Error | ${err} ${fnDescription}...`)
250
+ if (!(err instanceof Error)) {
251
+ // strange things may happen
252
+ err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`) // we should be prepared for them
241
253
  }
242
254
  if (customErrFn) {
243
- customErrFn(err);
255
+ customErrFn(err)
244
256
  } else if (errFn) {
245
- errFn(err);
257
+ errFn(err)
246
258
  }
247
- this.stop();
248
- });
259
+ this.stop()
260
+ }))
249
261
  },
250
262
 
251
263
  /**
@@ -254,17 +266,22 @@ module.exports = {
254
266
  * @inner
255
267
  */
256
268
  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
269
+ const fnDescription = customErrFn
270
+ ?.toString()
271
+ ?.replace(/\s{2,}/g, ' ')
272
+ .replace(/\n/g, ' ')
273
+ ?.slice(0, 50)
274
+ return (promise = promise.catch(err => {
275
+ if (ignoredErrs.includes(err)) return // already caught
276
+ log(`${currentQueue()} Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`)
277
+ if (!(err instanceof Error)) {
278
+ // strange things may happen
279
+ err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`) // we should be prepared for them
263
280
  }
264
281
  if (customErrFn) {
265
- return customErrFn(err);
282
+ return customErrFn(err)
266
283
  }
267
- });
284
+ }))
268
285
  },
269
286
 
270
287
  /**
@@ -276,15 +293,15 @@ module.exports = {
276
293
  */
277
294
 
278
295
  throw(err) {
279
- if (ignoredErrs.includes(err)) return promise; // already caught
296
+ if (ignoredErrs.includes(err)) return promise // already caught
280
297
  return this.add(`throw error: ${err.message}`, () => {
281
- if (ignoredErrs.includes(err)) return; // already caught
282
- throw err;
283
- });
298
+ if (ignoredErrs.includes(err)) return // already caught
299
+ throw err
300
+ })
284
301
  },
285
302
 
286
303
  ignoreErr(err) {
287
- ignoredErrs.push(err);
304
+ ignoredErrs.push(err)
288
305
  },
289
306
 
290
307
  /**
@@ -293,7 +310,7 @@ module.exports = {
293
310
  */
294
311
  saveFirstAsyncError(err) {
295
312
  if (asyncErr === null) {
296
- asyncErr = err;
313
+ asyncErr = err
297
314
  }
298
315
  },
299
316
 
@@ -302,7 +319,7 @@ module.exports = {
302
319
  * @inner
303
320
  */
304
321
  getAsyncErr() {
305
- return asyncErr;
322
+ return asyncErr
306
323
  },
307
324
 
308
325
  /**
@@ -310,7 +327,7 @@ module.exports = {
310
327
  * @inner
311
328
  */
312
329
  cleanAsyncErr() {
313
- asyncErr = null;
330
+ asyncErr = null
314
331
  },
315
332
 
316
333
  /**
@@ -319,9 +336,9 @@ module.exports = {
319
336
  * @inner
320
337
  */
321
338
  stop() {
322
- debug(this.toString());
323
- log(`${currentQueue()} Stopping recording promises`);
324
- running = false;
339
+ debug(this.toString())
340
+ log(`${currentQueue()} Stopping recording promises`)
341
+ running = false
325
342
  },
326
343
 
327
344
  /**
@@ -332,7 +349,7 @@ module.exports = {
332
349
  * @inner
333
350
  */
334
351
  promise() {
335
- return promise;
352
+ return promise
336
353
  },
337
354
 
338
355
  /**
@@ -341,7 +358,7 @@ module.exports = {
341
358
  * @inner
342
359
  */
343
360
  scheduled() {
344
- return tasks.slice(-MAX_TASKS).join('\n');
361
+ return tasks.slice(-MAX_TASKS).join('\n')
345
362
  },
346
363
 
347
364
  /**
@@ -350,7 +367,7 @@ module.exports = {
350
367
  * @inner
351
368
  */
352
369
  getQueueId() {
353
- return queueId;
370
+ return queueId
354
371
  },
355
372
 
356
373
  /**
@@ -359,21 +376,25 @@ module.exports = {
359
376
  * @inner
360
377
  */
361
378
  toString() {
362
- return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`;
379
+ return `Queue: ${currentQueue()}\n\nTasks: ${this.scheduled()}`
363
380
  },
364
-
365
- };
381
+ }
366
382
 
367
383
  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];
384
+ let timer
385
+ if (timeoutMs) debug(`Timing out in ${timeoutMs}ms`)
386
+ return [
387
+ new Promise((done, reject) => {
388
+ timer = setTimeout(() => {
389
+ reject(new TimeoutError(`Action ${taskName} was interrupted on timeout ${timeoutMs}ms`))
390
+ }, timeoutMs || 2e9)
391
+ }),
392
+ timer,
393
+ ]
373
394
  }
374
395
 
375
396
  function currentQueue() {
376
- let session = '';
377
- if (sessionId) session = `<${sessionId}> `;
378
- return `[${queueId}] ${session}`;
397
+ let session = ''
398
+ if (sessionId) session = `<${sessionId}> `
399
+ return `[${queueId}] ${session}`
379
400
  }
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