question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Mocha reporter exits before async tasks complete

See original GitHub issue

Current behavior:

A custom Mocha reporter that performs asynchronous tasks on receiving the ‘end’ event cannot complete because the Mocha process is exited. Synchronous actions, however long they may be, can finish.

Mocha has a --exit and --no-exit arg described here: https://mochajs.org/#-exit. By default in Mocha 4.0 + the no-exit arg is supplied which does wait for asychronous functions to complete and so when running in ‘vanilla’ Mocha this is not an issue, however it looks like Cypress is passing the --exit arg to Mocha.

Desired behavior:

Either change behavior of Cypress to default to Mocha --no-exit or provide a way to pass through args to Mocha so that the --no-exit arg can be passed through to Mocha on cypress run.

Test code to reproduce

Here is an example custom mocha reporter to reproduce the issue. The function called on the ‘end’ event takes 10 seconds to complete.

// example-reporter.js
const mocha = require('mocha');
module.exports = exampleReporter;

function exampleReporter(runner, options) {
  mocha.reporters.Base.call(this, runner);

  function wait(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  runner.on('end', function() {
      console.log('started');
      wait(10000).then(() => console.log('finished'));
  });
}

If you run this using ‘vanilla’ Mocha where the default is for the --no-exit option is passed you will find the you see both the ‘started’ and ‘finished’ logged to the console, 10 seconds apart.

However if you run using Cypress with this command (using the example project):

$(npm bin)/cypress run --spec "cypress/integration/examples/actions.spec.js" --reporter example-reporter.js

You will see that only ‘started’ is printed to console and Mocha exits. I am specifying a single spec here for clarity, if you run multiple specs you will may see the ‘finished’ appear when the next spec is running because Mocha is still running, but the point is that, for a custom reporter, it was what happens at the completion of all specs that really matters.

Versions

Tested with Cypress 4.4.1

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:18
  • Comments:8

github_iconTop GitHub Comments

2reactions
Amrrxcommented, Mar 22, 2022

Hello, I believe there is a better alternative workaround than using the deasync library.

The Idea

Using the (child_process) Nodejs builtin module, you can start a new sub process from the parent process, in which the main mocha runner is running inside, then you can de attach this child process to run separately in the background even if the parent process is going to die.

The Implementation

Using the (spawn) function from Nodejs, I have successfully solved the issue using such configuration.

spawn('node', [`${__dirname}/distributer.js`], {
                detached: true, // To detach the child process from the parent process
                stdio: 'inherit', // To inherit the parent process stdio which makes the sub process write to the main parent terminal window
                env: Object.assign(process.env, {
                    special_data_config: JSON.stringify(userconfig),
                    test_run_data: JSON.stringify(this.dataObject)
                }) //Some extra data for my reporter
            }).unref();

The (spawn) function is builtin function which takes 3 attributes. 1- A command to be executed (I will run the main (node) command to execute my published file) 2- An array of arguments to be concatenated with the command (I included my publisher file path) 3- An options object which is optional in case you want to pass some extra data and some other configuration.

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given sub process to exit, use the subprocess.unref() method. Doing so will cause the parent’s event loop to not include the child in its reference count, allowing the parent to exit independently of the child

By inheriting the stdio, the sub process can write to the main terminal and by default the CI/CD runner cannot ignore.

Doing though, only cause me a little effort to separate my publisher file from the main mocha runner (index) file as they were coupled to each others. then I passed my runner final data to the reporter publisher to the rest on another process.

Keep in mind that you have to pass any extra data as as (String) only and then you can parse and sanitize it inside your child process. And that may be better instead of making your child process read from a file on disk or pass it as a command args which lead to some security issues.

I have implemented such a workaround and it works well on my reporter even on my CI/CD pipeline and I hope it can work with you too.

Nodejs child_process module docs

0reactions
FFdhorkincommented, Apr 2, 2021

@jprealini Check out this PR: https://github.com/Vivify-Ideas/cypress-testrail-reporter/pull/16. I don’t know if it will get approved, but given salty-cypress-testrail-reporter forks from this repo, you can probably make the same type of changes in salty-cypress-testrrail-reporter

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mocha.run() exits without awaiting async tests - Stack Overflow
The problem I'm encountering is that mocha.run() executes and exits the node process without continuing with the rest of the code. It is...
Read more >
Mocha - API Manual
Mocha. simple, flexible, fun. Mocha is a feature-rich JavaScript test framework running on Node.js and the browser, making asynchronous testing simple and ...
Read more >
Mocha - the fun, simple, flexible JavaScript test framework
Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. Mocha tests run ......
Read more >
mochajs/mocha - Gitter
describe('Subscriptions Routes', () => { before(async function ... through coveralls but if any failed test crashes the whole build, there is no point....
Read more >
Command-line usage - mocha - w3resource
Before version v4.0.0, Mocha would force its own process to exit once it ... will not wait for async tasks in a required...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found