diff --git a/lib/suite.js b/lib/suite.js index ff78e2b0e5..52ebfdc164 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -224,12 +224,23 @@ class Suite extends EventEmitter { // Allow overriding inner/nested suites // See and test-cases with chain-called timeout argument. // https://github.com/mochajs/mocha/issues/5422 + // https://github.com/mochajs/mocha/issues/6033 for (const t of this.tests) { t.timeout(this._timeout); } for (const s of this.suites) { s.timeout(this._timeout); } + for (const hooks of [ + this._beforeAll, + this._beforeEach, + this._afterAll, + this._afterEach, + ]) { + for (const h of hooks) { + h.timeout(this._timeout); + } + } return this; } diff --git a/test/unit/suite.spec.cjs b/test/unit/suite.spec.cjs index cb55d58727..c2627a5a3e 100644 --- a/test/unit/suite.spec.cjs +++ b/test/unit/suite.spec.cjs @@ -105,6 +105,24 @@ describe("Suite", function () { const newSuite = suite.timeout(5000); expect(newSuite.timeout(), "to be", 5000); }); + + it("should propagate the timeout to already-registered hooks", function () { + // https://github.com/mochajs/mocha/issues/6033 + // The chained `describe(...).timeout(N)` form creates hooks during the + // describe callback (with the suite's default timeout) and only calls + // the setter afterwards, so the new value must reach the hook arrays. + suite.beforeAll(function () {}); + suite.beforeEach(function () {}); + suite.afterAll(function () {}); + suite.afterEach(function () {}); + + suite.timeout(5000); + + expect(suite.getHooks("beforeAll")[0].timeout(), "to be", 5000); + expect(suite.getHooks("beforeEach")[0].timeout(), "to be", 5000); + expect(suite.getHooks("afterAll")[0].timeout(), "to be", 5000); + expect(suite.getHooks("afterEach")[0].timeout(), "to be", 5000); + }); }); });