Skip to content

🐛 Bug: mocha should reload --require'd root hook modules on watch reruns #5352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
4 tasks done
jedwards1211 opened this issue May 1, 2025 · 2 comments
Open
4 tasks done
Assignees
Labels
status: in triage a maintainer should (re-)triage (review) this issue type: bug a defect, confirmed by a maintainer

Comments

@jedwards1211
Copy link

jedwards1211 commented May 1, 2025

Bug Report Checklist

  • I have read and agree to Mocha's Code of Conduct and Contributing Guidelines
  • I have searched for related issues and issues with the faq label, but none matched my issue.
  • I have 'smoke tested' the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, my usage of Mocha, or Mocha itself.
  • I want to provide a PR to resolve this

Expected

I'm building a chai plugin to do snapshot testing; it needs to get the Mocha currentTest somehow; it seems like a root hooks module is the only way.

This works for the first test run, but in watch mode reruns a new instance of the hooks module is getting loaded by tests requiring it, whereas Mocha calls the hooks on the first instance of the hooks module. I expected Mocha to also reload the hooks module so that it is the same module instance as the tests see in every rerun.

In general it seems like there's no clean way to make a chai plugin access the current test where I don't have to manually pass it in from each test suite?

What I expected when running the code below is for the initial run and subsequent reruns to each output a matching hook module and defined test file like so:

$ pnpm test

> [email protected] test /Users/andy/gh/mocha-root-hook-modules-issue
> mocha --watch -r test/hook.js test/setup.js test/test.js

loading hook module 0.6662139062019405
loading setup module


hook module 0.6662139062019405 set _currentTest to: <Test Title>
matchScreenshot method got hook id: 0.6662139062019405
matchScreenshot method got current test file: /Users/andy/gh/mocha-root-hook-modules-issue/test/test.js
  ✔ <Test Title>

  1 passing (4ms)

ℹ [mocha] waiting for changes...
rs
loading setup module
loading hook module 0.36167345256862715


hook module 0.36167345256862715 set _currentTest to: <Test Title>
matchScreenshot method got hook id: 0.36167345256862715
matchScreenshot method got current test file: /Users/andy/gh/mocha-root-hook-modules-issue/test/test.js
  ✔ <Test Title>

  1 passing (2ms)

ℹ [mocha] waiting for changes...

Actual

$ pnpm test

> [email protected] test /Users/andy/gh/mocha-root-hook-modules-issue
> mocha --watch -r test/hook.js test/setup.js test/test.js

loading hook module 0.6662139062019405
loading setup module


hook module 0.6662139062019405 set _currentTest to: <Test Title>
matchScreenshot method got hook id: 0.6662139062019405
matchScreenshot method got current test file: /Users/andy/gh/mocha-root-hook-modules-issue/test/test.js
  ✔ <Test Title>

  1 passing (4ms)

ℹ [mocha] waiting for changes...
rs
loading setup module
loading hook module 0.36167345256862715
#                   ~~~~~~~~~~~~~~~~~~~

hook module 0.6662139062019405 set _currentTest to: <Test Title>
#           ~~~~~~~~~~~~~~~~~~
matchScreenshot method got hook id: 0.36167345256862715
#                                   ~~~~~~~~~~~~~~~~~~~
matchScreenshot method got current test file: undefined
  ✔ <Test Title>

  1 passing (2ms)

ℹ [mocha] waiting for changes...

Minimal, Reproducible Example

package.json

{
  "name": "mocha-root-hook-modules-issue",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha --watch -r test/hook.js test/setup.js test/test.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^4",
    "mocha": "^11.2.2"
  }
}

test/hook.js

const id = Math.random()
console.error('loading hook module', id)

let _currentTest

exports.id = id
exports.getCurrentTest = () => _currentTest

exports.mochaHooks = {
  beforeEach() {
    _currentTest = this.currentTest
    console.log(`hook module ${id} set _currentTest to:`, _currentTest?.title)
  }
}

test/setup.js

console.log('loading setup module')

const chai = require('chai')
const {getCurrentTest, id} = require('./hook')

chai.use(function (chai, utils) {
  const {Assertion} = chai

  Assertion.addMethod('matchScreenshot', () => {
    const currentTest = getCurrentTest()
    console.log('matchScreenshot method got hook id:', id)
    console.log('matchScreenshot method got current test file:', currentTest?.file)
  })
})

test/test.js

const {it} = require('mocha')
const {expect} = require('chai')

it('<Test Title>', () => {
  const element = '<in a real test this would be a WebDriver element>'
  expect(element).to.matchScreenshot()
})

Versions

Mocha 11.2.2
Node 20.10.0

Additional Info

Right now the unsatisfying workaround is to set globalThis._currentTest = this.currentTest in my root hook.

@jedwards1211 jedwards1211 added status: in triage a maintainer should (re-)triage (review) this issue type: bug a defect, confirmed by a maintainer labels May 1, 2025
@jedwards1211
Copy link
Author

I don't know if there's some reason y'all think the original module's hook should keep being invoked on watch mode reruns, it's hard for me to imagine any concrete benefits to that, but if not I'm willing to work on a PR to fix it

@mark-wiemer
Copy link
Member

Hi, I'm relatively new to contributing to Mocha (joined in Jan), but I'll be happy to look into this shortly. Thanks for the clear repro steps, I'll see what I can do :)

@mark-wiemer mark-wiemer self-assigned this May 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: in triage a maintainer should (re-)triage (review) this issue type: bug a defect, confirmed by a maintainer
Projects
None yet
Development

No branches or pull requests

2 participants