mochajs / mocha

☕️ simple, flexible, fun javascript test framework for node.js & the browser
https://mochajs.org
MIT License
22.6k stars 3.01k forks source link

🐛 Bug: Custom describe block wrapper does not `await` for an internal process runs in mocha's `root hook` #5234

Open 0xmaayan opened 3 weeks ago

0xmaayan commented 3 weeks ago

Bug Report Checklist

Expected

I am using mocha to build a testing framework and wrapping mocha's describe block with a custom describe block function and injecting a custom internal instance to be used in tests suites by the end user.

import { describe as MochaDescribe } from "mocha";

export function describe(description: string, block: (customInstance: CustomInstance) => void) {
  MochaDescribe(description, function () {
    block(customInstance); 
  });
}

Everything was working as expected, until I added an internal process that runs as a root hook and when finishes assign the customInstance a value, that should be used in tests suites by the end user.

Actual

Looks like the custom describe block doesnt await for the root hook to finish before assigning the new global value to be used in a test suite by the end user

Minimal, Reproducible Example

// mochaConfig.ts file

const mochaConfig: CustomMochaOptions = {
    require: [path.join(__dirname, "rootHook.js")],
    parallel: true,
};

const mocha = new Mocha(mochaConfig);

// run mocha
await new Promise<number>((resolve) => {
    mocha.run(resolve);
});

// rootHook.ts file
export const mochaHooks: RootHookObject = {
  beforeAll: async function () {
    await new Promise((resolve) => setTimeout(resolve, 10000));
   // inject customInstance to the global object
   myGlobal.customInstance = {key:"value"};
  },
};

// api.ts file
export interface CustomGlobal extends NodeJS.Global {
  customInstance: {};
}

declare var global: CustomGlobal;

export var myGlobal: CustomGlobal = global;

import { describe as MochaDescribe } from "mocha";

export function describe(description: string, block: (customInstance: CustomInstance) => void) {
  MochaDescribe(description, function () {
    block(myGlobal.customInstance); 
  });
}

// test.ts file
import { describe } from "../api";

describe("my first test", (customInstance) => {

});

Versions

"mocha": "^10.7.0",
node --version v21.6.2

Additional Info

No response

JoshuaKGoldberg commented 1 week ago

Minimal, Reproducible Example

This isn't an MRE 🙂 - could you please post one that we can get running quickly locally? We're a small maintenance team and don't have the time to piece stuff together.

https://antfu.me/posts/why-reproductions-are-required -> https://antfu.me/posts/why-reproductions-are-required#reproducible-projects-or-playgrounds

Thanks!