Skip to content

Commit a0ae921

Browse files
author
DavertMik
committed
refactored timeouts to fix tests
1 parent 29e1be1 commit a0ae921

File tree

7 files changed

+39
-16
lines changed

7 files changed

+39
-16
lines changed

lib/actor.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ const MetaStep = require('./step/meta')
33
const recordStep = require('./step/record')
44
const container = require('./container')
55
const { methodsOfObject } = require('./utils')
6-
const { TIMEOUT_ORDER } = require('./step/timeout')
7-
const recorder = require('./recorder')
6+
const { TIMEOUT_ORDER } = require('./timeout')
87
const event = require('./event')
98
const store = require('./store')
109
const output = require('./output')

lib/listener/globalTimeout.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const recorder = require('../recorder')
44
const Config = require('../config')
55
const store = require('../store')
66
const debug = require('debug')('codeceptjs:timeout')
7-
const { TIMEOUT_ORDER } = require('../step/timeout')
7+
const { TIMEOUT_ORDER, TimeoutError, TestTimeoutError } = require('../timeout')
88
const { BeforeSuiteHook, AfterSuiteHook } = require('../mocha/hooks')
99

1010
module.exports = function () {
@@ -119,25 +119,33 @@ module.exports = function () {
119119
}
120120
})
121121

122+
event.dispatcher.on(event.step.after, step => {
123+
if (typeof timeout !== 'number') return
124+
if (!store.timeouts) return
125+
126+
recorder.catchWithoutStop(err => {
127+
if (timeout && err instanceof TimeoutError && +Date.now() - step.startTime >= timeout) {
128+
debug('Step failed due to global test or suite timeout')
129+
throw new TestTimeoutError(currentTimeout)
130+
}
131+
throw err
132+
})
133+
})
134+
122135
event.dispatcher.on(event.step.finished, step => {
123136
if (!store.timeouts) {
124137
debug('step', step.toCode().trim(), 'timeout disabled')
125138
return
126139
}
127140

141+
if (typeof timeout === 'number') debug('Timeout', timeout)
142+
128143
debug(`step ${step.toCode().trim()}:${step.status} duration`, step.duration)
129144
if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration
130145

131146
if (typeof timeout === 'number' && timeout <= 0 && recorder.isRunning()) {
132147
debug(`step ${step.toCode().trim()} timed out`)
133-
if (currentTest && currentTest.callback) {
134-
debug(`Failing test ${currentTest.title} with timeout ${currentTimeout}s`)
135-
recorder.reset()
136-
// replace mocha timeout with custom timeout
137-
currentTest.timeout(0.1)
138-
currentTest.callback(new Error(`Timeout ${currentTimeout}s exceeded (with Before hook)`))
139-
currentTest.timedOut = true
140-
}
148+
recorder.throw(new TestTimeoutError(currentTimeout))
141149
}
142150
})
143151
}

lib/plugin/stepTimeout.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const event = require('../event')
2-
const { TIMEOUT_ORDER } = require('../step/timeout')
2+
const { TIMEOUT_ORDER } = require('../timeout')
33

44
const defaultConfig = {
55
timeout: 150,

lib/recorder.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const promiseRetry = require('promise-retry')
33
const chalk = require('chalk')
44
const { printObjectProperties } = require('./utils')
55
const { log } = require('./output')
6-
6+
const { TimeoutError } = require('./timeout')
77
const MAX_TASKS = 100
88

99
let promise
@@ -386,7 +386,7 @@ function getTimeoutPromise(timeoutMs, taskName) {
386386
return [
387387
new Promise((done, reject) => {
388388
timer = setTimeout(() => {
389-
reject(new Error(`Action ${taskName} was interrupted on step timeout ${timeoutMs}ms`))
389+
reject(new TimeoutError(`Action ${taskName} was interrupted on step timeout ${timeoutMs}ms`))
390390
}, timeoutMs || 2e9)
391391
}),
392392
timer,

lib/step/base.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const color = require('chalk')
22
const Secret = require('../secret')
3-
const { getCurrentTimeout } = require('./timeout')
3+
const { getCurrentTimeout } = require('../timeout')
44
const { ucfirst, humanizeString, serializeError } = require('../utils')
55

66
const STACK_LINE = 5

lib/step/record.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const recorder = require('../recorder')
33
const StepConfig = require('./config')
44
const { debug } = require('../output')
55
const store = require('../store')
6-
const { TIMEOUT_ORDER } = require('./timeout')
6+
const { TIMEOUT_ORDER } = require('../timeout')
77
const retryStep = require('./retry')
88
function recordStep(step, args) {
99
step.status = 'queued'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,23 @@ function getCurrentTimeout(timeouts) {
3636
return totalTimeout
3737
}
3838

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+
3953
module.exports = {
4054
TIMEOUT_ORDER,
4155
getCurrentTimeout,
56+
TimeoutError,
57+
TestTimeoutError,
4258
}

0 commit comments

Comments
 (0)