Using mocha parallel=true and retries=1 options it throws an Uncaught TypeError
NazarYermolenko opened this issue · comments
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
Environment (please complete the following information):
- Ubuntu
- Mocha 9.1.2
- Mochawesome 6.3.0
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.
@kolbasik Thoughts on if this is related to your latest changes to parallel processing?
Hi @adamgruber , I will try to reproduce the issue
@kolbasik Have you detected the issue?
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.