Skip to content
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

Thrown error in afterEach as a root hook plugin is ignored in watchmode #4347

Closed
2 tasks done
eps1lon opened this issue Jun 25, 2020 · 5 comments · Fixed by #4382
Closed
2 tasks done

Thrown error in afterEach as a root hook plugin is ignored in watchmode #4347

eps1lon opened this issue Jun 25, 2020 · 5 comments · Fixed by #4382
Labels
type: bug a defect, confirmed by a maintainer

Comments

@eps1lon
Copy link

eps1lon commented Jun 25, 2020

Prerequisites

  • Checked that your issue hasn't already been filed by cross-referencing issues with the faq label
  • [ ] Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn't just a feature that actually isn't supported in the environment in question or a bug in your code. Not syntax related
  • [ ] '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, your usage of Mocha, or Mocha itself Not related to code under test
  • Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with: node node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend that you not install Mocha globally.

Description

Steps to Reproduce

Full repro: https://github.com/eps1lon/repro-mocha-root-hook-throw

// test.js
it("root hooks tests onces", () => {});
it("root hooks tests twice", () => {});

// `hooks.js`
module.exports = {
  mochaHooks: {
    afterEach() {
      throw new Error("Threw in root afterEach");
    },
  },
};

// .mocharc.js
module.exports = {
  require: [require.resolve("./hooks")],
};
  • mocha test.js fails as expected
  • mocha test.js --watch passes unexpectedly

Expected behavior:

afterEach as a root hook behave the same as "local" hooks with regard to thrown errors.

Actual behavior:

Thrown error is ignored in afterEach in watchmode

Reproduces how often:

All the time

Versions

  • The output of mocha --version and node node_modules/.bin/mocha --version: 8.0.1
    mocha --version does not work because I didn't install it globally
  • The output of node --version: 12.16.2
  • Your operating system
    • name and version: Ubuntu 18.04.4 LTS
    • architecture (32 or 64-bit): 64bit
  • Your shell (e.g., bash, zsh, PowerShell, cmd): fish, version 2.7.1
  • Your browser and version (if running browser tests): N/A
  • Any third-party Mocha-related modules (and their versions): N/A
  • Any code transpiler (e.g., TypeScript, CoffeeScript, Babel) being used (and its version): N/A

Additional Information

N/A

@boneskull
Copy link
Member

This might be the same root problem as #4344.

@eps1lon
Copy link
Author

eps1lon commented Jul 14, 2020

One more related issue: console logs are ignored in root hook plugins in watchmode.

@eps1lon eps1lon changed the title Thrown error in afterEach as a root hook is ignored in watchmode Thrown error in afterEach as a root hook plugin is ignored in watchmode Jul 14, 2020
@boneskull
Copy link
Member

that sounds like a bug

@indieisaconcept
Copy link
Contributor

Hit this issue myself recently. I did a little digging & issue seems to be caused by the cloning the suite on L40.

beforeRun({mocha}) {
// I don't know why we're cloning the root suite.
const rootSuite = mocha.suite.clone();
// this `require` is needed because the require cache has been cleared. the dynamic
// exports set via the below call to `mocha.ui()` won't work properly if a
// test depends on this module (see `required-tokens.spec.js`).
const Mocha = require('../mocha');
// ... and now that we've gotten a new module, we need to use it again due
// to `mocha.ui()` call
const newMocha = new Mocha(mocha.options);
// don't know why this is needed
newMocha.suite = rootSuite;
// nor this
newMocha.suite.ctx = new Context();
// reset the list of files
newMocha.files = collectFiles(fileCollectParams);
// because we've swapped out the root suite (see the `run` inner function
// in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.
newMocha.ui(newMocha.options.ui);
// in parallel mode, the main Mocha process doesn't actually load the
// files. this flag prevents `mocha.run()` from autoloading.
newMocha.lazyLoadFiles(true);
return newMocha;
},

It looks like suite.clone() doesn't copy over any of the hooks.

mocha/lib/suite.js

Lines 117 to 127 in 7d3151d

Suite.prototype.clone = function() {
var suite = new Suite(this.title);
debug('clone');
suite.ctx = this.ctx;
suite.root = this.root;
suite.timeout(this.timeout());
suite.retries(this.retries());
suite.slow(this.slow());
suite.bail(this.bail());
return suite;
};

I did a quick local patch to add these & watch worked as expected with root hooks.

indieisaconcept added a commit to indieisaconcept/mocha that referenced this issue Jul 26, 2020
## Rationale
Tests with root level hooks are ignored when running in watch mode.
This occurs on initial & subsequent runs.

## Changes

- extended `suite.clone` to clone hooks

This change was necessary to ensure that when a suite is cloned during
the setup phase for watch that hooks are available on the newly cloned
suite.

Note the use of `suite.clone` appears to be only used in to
`lib/cli/run-watch`. I did consider making the cloning of hooks
optional but opted not to as this `suite.clone` is internal `mocha` &
not publicly referenced in the API documentation.

Tests for `suite.clone` have been amended to reflect the above change.

- Extended integration tests for watch to take into consideration
  hooks

## Refs

- mochajs/issues/4347
indieisaconcept added a commit to indieisaconcept/mocha that referenced this issue Jul 26, 2020
## Rationale
Tests with root level hooks are ignored when running in watch mode.
This occurs on initial & subsequent runs.

## Changes

- extended `suite.clone` to clone hooks

This change was necessary to ensure that when a suite is cloned during
the setup phase for watch that hooks are available on the newly cloned
suite.

Note the use of `suite.clone` appears to be only used in
`lib/cli/run-watch`. I did consider making the cloning of hooks
optional but opted not to as `suite.clone` is internal to `mocha` & not
publicly referenced in the API documentation.

Tests for `suite.clone` have been amended to reflect the above change.

- Extended integration tests for watch to take into consideration
  hooks

## Refs

- mochajs/issues/4347
@indieisaconcept
Copy link
Contributor

FYI I've submitted a PR to address. #4382

indieisaconcept added a commit to indieisaconcept/mocha that referenced this issue Jul 26, 2020
## Rationale
Tests with root level hooks are ignored when running in watch mode.
This occurs on initial & subsequent runs.

## Changes

- extended `suite.clone` to clone hooks

This change was necessary to ensure that when a suite is cloned during
the setup phase for watch that hooks are available on the newly cloned
suite.

Note the use of `suite.clone` appears to be only used in
`lib/cli/run-watch`. I did consider making the cloning of hooks
optional but opted not to as `suite.clone` is internal to `mocha` & not
publicly referenced in the API documentation.

Tests for `suite.clone` have been amended to reflect the above change.

- Extended integration tests for watch to take into consideration
  hooks

## Refs

- mochajs/issues/4347
indieisaconcept added a commit to indieisaconcept/mocha that referenced this issue Jul 26, 2020
## Rationale
Tests with root level hooks are ignored when running in watch mode.
This occurs on initial & subsequent runs.

## Changes

- updated `lib/cli/run-watch` to re-initialise rootHooks

As we have swapped out the root suite it is necessary to re-initialize
root level hooks again.

- Extended integration tests for watch to take into consideration
  hooks

## Refs

- mochajs/issues/4347
@boneskull boneskull added type: bug a defect, confirmed by a maintainer and removed unconfirmed-bug labels Jul 29, 2020
boneskull pushed a commit that referenced this issue Jul 29, 2020
## Rationale
Tests with root level hooks are ignored when running in watch mode.
This occurs on initial & subsequent runs.

## Changes

- updated `lib/cli/run-watch` to re-initialise rootHooks

As we have swapped out the root suite it is necessary to re-initialize
root level hooks again.

- Extended integration tests for watch to take into consideration
  hooks

## Refs

- /issues/4347
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug a defect, confirmed by a maintainer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants