From b3c60a8b3001642b7bd03cf86d52e8267ee5b990 Mon Sep 17 00:00:00 2001 From: Daniil Krapiunitski Date: Tue, 26 May 2026 09:30:08 +0200 Subject: [PATCH] fix(gherkin): emit test.before/after with real current test Gherkin beforeEach/afterEach pass Mocha hook Context into setup/teardown, but asyncWrapper read suite.ctx.currentTest (undefined on Context), so event.test.before received a placeholder test (title "...", empty tags). Also forward Mocha's done callback instead of no-op () => {}, so event.test.before completes before scenario Background Before hooks run. Co-authored-by: Cursor --- lib/mocha/asyncWrapper.js | 4 ++-- lib/mocha/gherkin.js | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/mocha/asyncWrapper.js b/lib/mocha/asyncWrapper.js index 811f7c148..bb25aaabd 100644 --- a/lib/mocha/asyncWrapper.js +++ b/lib/mocha/asyncWrapper.js @@ -199,7 +199,7 @@ export function setup(suite) { recorder.startUnlessRunning() import('./test.js').then(testModule => { const { enhanceMochaTest } = testModule.default || testModule - event.emit(event.test.before, enhanceMochaTest(suite?.ctx?.currentTest)) + event.emit(event.test.before, enhanceMochaTest(suite?.currentTest ?? suite?.ctx?.currentTest)) recorder.add(() => doneFn()) }) } @@ -211,7 +211,7 @@ export function teardown(suite) { recorder.startUnlessRunning() import('./test.js').then(testModule => { const { enhanceMochaTest } = testModule.default || testModule - event.emit(event.test.after, enhanceMochaTest(suite?.ctx?.currentTest)) + event.emit(event.test.after, enhanceMochaTest(suite?.currentTest ?? suite?.ctx?.currentTest)) recorder.add(() => doneFn()) }) } diff --git a/lib/mocha/gherkin.js b/lib/mocha/gherkin.js index 453e41cd9..1b8ebf76d 100644 --- a/lib/mocha/gherkin.js +++ b/lib/mocha/gherkin.js @@ -42,13 +42,12 @@ const gherkinParser = (text, file) => { suite.file = file suite.timeout(0) - suite.beforeEach('codeceptjs.before', function () { - // In Mocha, 'this' refers to the current test in beforeEach/afterEach hooks - setup(this)(() => {}) + suite.beforeEach('codeceptjs.before', function (done) { + // In Mocha, 'this' is the hook Context; currentTest is the running scenario + setup(this)(done) }) - suite.afterEach('codeceptjs.after', function () { - // In Mocha, 'this' refers to the current test in beforeEach/afterEach hooks - teardown(this)(() => {}) + suite.afterEach('codeceptjs.after', function (done) { + teardown(this)(done) }) suite.beforeAll('codeceptjs.beforeSuite', suiteSetup(suite)) suite.afterAll('codeceptjs.afterSuite', suiteTeardown(suite))