From ac417e7b8fd005df565dbc6d5b7acb445802db63 Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Sat, 25 Oct 2025 07:45:13 +0000 Subject: [PATCH 1/3] Fix: preserve global timeout with BeforeSuite hook --- lib/listener/globalTimeout.js | 23 +++++++++++++++---- .../timeouts/beforeSuite_timeout_test.js | 9 ++++++++ .../codecept.beforeSuiteTimeout.conf.js | 12 ++++++++++ test/runner/timeout_test.js | 10 ++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js create mode 100644 test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js diff --git a/lib/listener/globalTimeout.js b/lib/listener/globalTimeout.js index 07bed2807..c674fc8b6 100644 --- a/lib/listener/globalTimeout.js +++ b/lib/listener/globalTimeout.js @@ -20,14 +20,29 @@ module.exports = function () { // disable timeout for BeforeSuite/AfterSuite hooks // add separate configs to them? + // When a BeforeSuite/AfterSuite hook starts we want to disable the + // per-test timeout during that hook execution only. Previously the + // code cleared `suiteTimeout` permanently which caused the suite + // level timeout to be lost for subsequent tests. Save previous + // values and restore them when the hook finishes. + let __prevTimeout = undefined + let __prevSuiteTimeout = undefined + event.dispatcher.on(event.hook.started, hook => { - if (hook instanceof BeforeSuiteHook) { + if (hook instanceof BeforeSuiteHook || hook instanceof AfterSuiteHook) { + __prevTimeout = timeout + // copy array to preserve original values + __prevSuiteTimeout = suiteTimeout.slice() timeout = null suiteTimeout = [] } - if (hook instanceof AfterSuiteHook) { - timeout = null - suiteTimeout = [] + }) + + event.dispatcher.on(event.hook.finished, hook => { + if (hook instanceof BeforeSuiteHook || hook instanceof AfterSuiteHook) { + // restore previously stored values + timeout = __prevTimeout + suiteTimeout = __prevSuiteTimeout.slice() } }) diff --git a/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js b/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js new file mode 100644 index 000000000..86242f79e --- /dev/null +++ b/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js @@ -0,0 +1,9 @@ +Feature('Timeout') + +BeforeSuite(() => { + // No stuff needed here to reproduce the issue +}) + +Scenario('enforce global timeout with BeforeSuite', ({ I }) => { + I.waitForSleep(4 * 1000) +}) diff --git a/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js b/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js new file mode 100644 index 000000000..1f5263cf2 --- /dev/null +++ b/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js @@ -0,0 +1,12 @@ +exports.config = { + tests: './*_test.js', + output: './output', + helpers: { + CustomHelper: { + require: './customHelper.js', + }, + }, + plugins: {}, + name: 'my', + timeout: 2, +} diff --git a/test/runner/timeout_test.js b/test/runner/timeout_test.js index 2f1d8c1d5..5f8d543fb 100644 --- a/test/runner/timeout_test.js +++ b/test/runner/timeout_test.js @@ -100,4 +100,14 @@ describe('CodeceptJS Timeouts', function () { done() }) }) + + it('should enforce global timeout even with BeforeSuite', done => { + exec(config_run_config('codecept.beforeSuiteTimeout.conf.js', 'enforce global timeout with BeforeSuite', true), (err, stdout) => { + debug_this_test && console.log(stdout) + expect(stdout).toContain('Timeout 2s exceeded') + expect(stdout).toContain('TestTimeoutError') + expect(err).toBeTruthy() + done() + }) + }) }) From 31ec9054156d87bf4978da3341edc7ac31e234fd Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Sat, 25 Oct 2025 07:52:59 +0000 Subject: [PATCH 2/3] test: clarify feature name for global timeout with BeforeSuite --- test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js b/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js index 86242f79e..21a2fb9f7 100644 --- a/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js +++ b/test/data/sandbox/configs/timeouts/beforeSuite_timeout_test.js @@ -1,4 +1,4 @@ -Feature('Timeout') +Feature('Global Timeout with BeforeSuite') BeforeSuite(() => { // No stuff needed here to reproduce the issue From 314456a7cdb759297b510231a68d9c1679df77dc Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Sat, 25 Oct 2025 08:02:32 +0000 Subject: [PATCH 3/3] chore: remove unused plugins field from beforeSuiteTimeout config --- .../configs/timeouts/codecept.beforeSuiteTimeout.conf.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js b/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js index 1f5263cf2..fe55427c8 100644 --- a/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js +++ b/test/data/sandbox/configs/timeouts/codecept.beforeSuiteTimeout.conf.js @@ -6,7 +6,6 @@ exports.config = { require: './customHelper.js', }, }, - plugins: {}, - name: 'my', + name: 'beforeSuiteTimeout', timeout: 2, }