codeceptjs 4.0.7 → 4.0.8

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.
package/lib/codecept.js CHANGED
@@ -289,8 +289,11 @@ class Codecept {
289
289
  // Ignore if gherkin module not available
290
290
  }
291
291
 
292
- // Sort test files alphabetically for consistent execution order
293
- this.testFiles.sort()
292
+ // Sort test files alphabetically for consistent execution order,
293
+ // but skip sorting when --shuffle is active so the randomised order is preserved.
294
+ if (!this.opts.shuffle) {
295
+ this.testFiles.sort()
296
+ }
294
297
 
295
298
  return new Promise((resolve, reject) => {
296
299
  const mocha = container.mocha()
package/lib/effects.js CHANGED
@@ -50,8 +50,10 @@ function within(context, fn) {
50
50
  return recorder.promise().then(() => res)
51
51
  })
52
52
  .catch(e => {
53
+ finishHelpers()
53
54
  finalize()
54
55
  recorder.throw(e)
56
+ return recorder.promise()
55
57
  })
56
58
  }
57
59
 
@@ -203,7 +205,7 @@ async function retryTo(callback, maxTries, pollInterval = 200) {
203
205
  const sessionName = 'retryTo'
204
206
 
205
207
  return new Promise((done, reject) => {
206
- let tries = 1
208
+ let tries = 0
207
209
 
208
210
  function handleRetryException(err) {
209
211
  recorder.throw(err)
@@ -216,7 +218,7 @@ async function retryTo(callback, maxTries, pollInterval = 200) {
216
218
  try {
217
219
  await callback(tries)
218
220
  } catch (err) {
219
- handleRetryException(err)
221
+ recorder.throw(err)
220
222
  }
221
223
 
222
224
  // Call done if no errors
@@ -228,7 +230,7 @@ async function retryTo(callback, maxTries, pollInterval = 200) {
228
230
  // Catch errors and retry
229
231
  recorder.session.catch(err => {
230
232
  recorder.session.restore(`${sessionName} ${tries}`)
231
- if (tries <= maxTries) {
233
+ if (tries < maxTries) {
232
234
  output.debug(`Error ${err}... Retrying`)
233
235
  recorder.add(`${sessionName} ${tries}`, () => setTimeout(tryBlock, pollInterval))
234
236
  } else {
@@ -197,11 +197,15 @@ export function setup(suite) {
197
197
  return function (done) {
198
198
  const doneFn = makeDoneCallableOnce(done)
199
199
  recorder.startUnlessRunning()
200
- import('./test.js').then(testModule => {
201
- const { enhanceMochaTest } = testModule.default || testModule
202
- event.emit(event.test.before, enhanceMochaTest(suite?.ctx?.currentTest ?? suite?.currentTest))
203
- recorder.add(() => doneFn())
204
- })
200
+ import('./test.js')
201
+ .then(testModule => {
202
+ const { enhanceMochaTest } = testModule.default || testModule
203
+ event.emit(event.test.before, enhanceMochaTest(suite?.ctx?.currentTest ?? suite?.currentTest))
204
+ recorder.add(() => doneFn())
205
+ })
206
+ .catch(err => {
207
+ doneFn(err)
208
+ })
205
209
  }
206
210
  }
207
211
 
@@ -209,11 +213,15 @@ export function teardown(suite) {
209
213
  return function (done) {
210
214
  const doneFn = makeDoneCallableOnce(done)
211
215
  recorder.startUnlessRunning()
212
- import('./test.js').then(testModule => {
213
- const { enhanceMochaTest } = testModule.default || testModule
214
- event.emit(event.test.after, enhanceMochaTest(suite?.ctx?.currentTest ?? suite?.currentTest))
215
- recorder.add(() => doneFn())
216
- })
216
+ import('./test.js')
217
+ .then(testModule => {
218
+ const { enhanceMochaTest } = testModule.default || testModule
219
+ event.emit(event.test.after, enhanceMochaTest(suite?.ctx?.currentTest ?? suite?.currentTest))
220
+ recorder.add(() => doneFn())
221
+ })
222
+ .catch(err => {
223
+ doneFn(err)
224
+ })
217
225
  }
218
226
  }
219
227
 
package/lib/pause.js CHANGED
@@ -19,6 +19,35 @@ let finish
19
19
  let next
20
20
  let registeredVariables = {}
21
21
  let externalHandler = null
22
+ let pauseSessionOpen = false
23
+
24
+ function onStepAfter() {
25
+ recorder.add('Start next pause session', () => {
26
+ // test already finished, nothing to pause
27
+ if (!store.currentTest) return
28
+ if (!next) return
29
+ return pauseSession()
30
+ })
31
+ }
32
+
33
+ function onTestFinished() {
34
+ if (typeof finish === 'function') finish()
35
+ if (pauseSessionOpen) {
36
+ recorder.session.restore('pause')
37
+ pauseSessionOpen = false
38
+ }
39
+ if (rl) rl.close()
40
+ if (!externalHandler) history.save()
41
+ event.dispatcher.removeListener(event.step.after, onStepAfter)
42
+ event.dispatcher.removeListener(event.test.finished, onTestFinished)
43
+ }
44
+
45
+ function registerPauseListeners() {
46
+ event.dispatcher.removeListener(event.step.after, onStepAfter)
47
+ event.dispatcher.removeListener(event.test.finished, onTestFinished)
48
+ event.dispatcher.on(event.step.after, onStepAfter)
49
+ event.dispatcher.on(event.test.finished, onTestFinished)
50
+ }
22
51
 
23
52
  /**
24
53
  * Pauses test execution and starts interactive shell
@@ -28,22 +57,7 @@ const pause = function (passedObject = {}) {
28
57
  if (store.dryRun) return
29
58
 
30
59
  next = false
31
- // add listener to all next steps to provide next() functionality
32
- event.dispatcher.on(event.step.after, () => {
33
- recorder.add('Start next pause session', () => {
34
- // test already finished, nothing to pause
35
- if (!store.currentTest) return
36
- if (!next) return
37
- return pauseSession()
38
- })
39
- })
40
-
41
- event.dispatcher.on(event.test.finished, () => {
42
- if (typeof finish === 'function') finish()
43
- recorder.session.restore('pause')
44
- if (rl) rl.close()
45
- if (!externalHandler) history.save()
46
- })
60
+ registerPauseListeners()
47
61
 
48
62
  recorder.add('Start new session', () => pauseSession(passedObject))
49
63
  }
@@ -51,12 +65,14 @@ const pause = function (passedObject = {}) {
51
65
  function pauseSession(passedObject = {}) {
52
66
  registeredVariables = passedObject
53
67
  recorder.session.start('pause')
68
+ pauseSessionOpen = true
54
69
 
55
70
  if (externalHandler) {
56
71
  store.onPause = true
57
72
  return externalHandler({ registeredVariables }).then(() => {
58
73
  store.onPause = false
59
74
  recorder.session.restore('pause')
75
+ pauseSessionOpen = false
60
76
  })
61
77
  }
62
78
 
@@ -107,6 +123,7 @@ async function parseInput(cmd) {
107
123
  if (!cmd || cmd === 'resume' || cmd === 'exit') {
108
124
  if (typeof finish === 'function') finish()
109
125
  recorder.session.restore('pause')
126
+ pauseSessionOpen = false
110
127
  rl.close()
111
128
  history.save()
112
129
  return nextStep()
@@ -265,6 +282,7 @@ function setPauseHandler(handler) {
265
282
  */
266
283
  function pauseNow(passedObject = {}) {
267
284
  if (store.dryRun) return
285
+ registerPauseListeners()
268
286
  recorder.add('Triggered pause', () => pauseSession(passedObject))
269
287
  }
270
288
 
package/lib/session.js CHANGED
@@ -109,6 +109,7 @@ function session(sessionName, config, fn) {
109
109
  output.stepShift = 0
110
110
  session.restoreVars(sessionName)
111
111
  event.dispatcher.removeListener(event.step.after, addContextToStep)
112
+ recorder.add('restore session on error', () => recorder.session.restore(`session:${sessionName}`))
112
113
  recorder.throw(e)
113
114
  return recorder.promise()
114
115
  })
@@ -124,6 +125,7 @@ function session(sessionName, config, fn) {
124
125
  session.restoreVars(sessionName)
125
126
  output.stepShift = 0
126
127
  event.dispatcher.removeListener(event.step.after, addContextToStep)
128
+ recorder.session.restore(`session:${sessionName}`)
127
129
  throw e
128
130
  })
129
131
  }
@@ -385,7 +385,9 @@ const __dirname = __dirname_fn(__filename);
385
385
  )
386
386
 
387
387
  // Write the transpiled file with updated imports
388
- const tempFile = filePath.replace(/\.ts$/, '.temp.mjs')
388
+ // Include process.pid + a random suffix so concurrent run-multiple workers
389
+ // don't write to and delete each other's temp files (see issue #5642).
390
+ const tempFile = filePath.replace(/\.ts$/, `.${process.pid}.${Math.random().toString(36).slice(2, 10)}.temp.mjs`)
389
391
  fs.writeFileSync(tempFile, jsContent)
390
392
  transpiledFiles.set(filePath, tempFile)
391
393
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "4.0.7",
3
+ "version": "4.0.8",
4
4
  "type": "module",
5
5
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
6
6
  "keywords": [