adamgruber / mochawesome

A Gorgeous HTML/CSS Reporter for Mocha.js
https://gitter.im/mochawesome/general
MIT License
1.06k stars 160 forks source link

Using mocha parallel=true and retries=1 options it throws an Uncaught TypeError #356

Closed NazarYermolenko closed 2 years ago

NazarYermolenko commented 2 years ago

Using mocha parallel=true and retries=1 options it throws an Uncaught TypeError

Code Reproduce Test which will fail, configuration of Mocha with options retries=1 and parallel=true, and configured MochaAwesom and test should contain addContext() function

Expected behavior The report shows failed tests and count of retries

Screenshots image

Environment (please complete the following information):

NazarYermolenko commented 2 years ago

The exception it throws:


     Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Test'
    |     property 'parent' -> object with constructor 'Suite'
    |     property 'ctx' -> object with constructor 'Context'
    |     property '_runnable' -> object with constructor 'Test'
    --- property '_retriedTest' closes the circle
      at stringify (<anonymous>)
      at writeChannelMessage (internal/child_process/serialization.js:117:20)
      at process.target._send (internal/child_process.js:780:17)
      at process.target.send (internal/child_process.js:678:19)
      at /home/newfire/Desktop/work/qa-ui/node_modules/workerpool/src/worker.js:131:22```

It appears only if the test failed, retried, and failed again.
adamgruber commented 2 years ago

@kolbasik Thoughts on if this is related to your latest changes to parallel processing?

kolbasik commented 2 years ago

Hi @adamgruber , I will try to reproduce the issue

NazarYermolenko commented 2 years ago

@kolbasik Have you detected the issue?

kolbasik commented 2 years ago

HI @NazarYermolenko , yes.

The issue is in this line: https://github.com/mochajs/mocha/blob/master/lib/test.js#L96 Mocha serializes the data from the agent and then deserialize it into kind of Mocha objects. It would not be the real object of Suite, Tests or Hooks. It would be the plain objects with the same fields and method. JSON does not support methods and after deserialization Mocha expects some functions not objects. So Mocha has made a trick if a field name has the '$$' prefix then it creates a function which return the object. Serialization:

Test.prototype.serialize = function serialize() {
  return {
    $$fullTitle: this.fullTitle(),
    $$retriedTest: this._retriedTest || null,
    body: this.body,
    ...
  };
};

After deserialization:

const test = {
   fullTitle: () => json["$$fullTitle"],
   retriedTest: () => json["$$retriedTest"],
   body: json["body"]
}

The issue is that this._retriedTest is not serialized by serialize method from the test. It's serialized by custom implementation of JSON.serialize which tries to dump the whole object. Where the circle is the following: test -> retriedTest -> parent -> tests -> test .

So I have ignored the retriedTest field from serialization since it is not used in the mochawesome report.