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

Fix: programmatic API cannot access retried test objects #4181

Merged
merged 2 commits into from Feb 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/runner.js
Expand Up @@ -135,6 +135,11 @@ function Runner(suite, delay) {
this.total = suite.total();
this.failures = 0;
this.on(constants.EVENT_TEST_END, function(test) {
if (test.retriedTest() && test.parent) {
var idx =
test.parent.tests && test.parent.tests.indexOf(test.retriedTest());
if (idx > -1) test.parent.tests[idx] = test;
}
self.checkGlobals(test);
});
this.on(constants.EVENT_HOOK_END, function(hook) {
Expand Down
13 changes: 13 additions & 0 deletions lib/test.js
Expand Up @@ -36,13 +36,26 @@ function Test(title, fn) {
*/
utils.inherits(Test, Runnable);

/**
* Set or get retried test
*
* @private
*/
Test.prototype.retriedTest = function(n) {
if (!arguments.length) {
return this._retriedTest;
}
this._retriedTest = n;
};

Test.prototype.clone = function() {
var test = new Test(this.title, this.fn);
test.timeout(this.timeout());
test.slow(this.slow());
test.enableTimeouts(this.enableTimeouts());
test.retries(this.retries());
test.currentRetry(this.currentRetry());
test.retriedTest(this.retriedTest() || this);
test.globals(this.globals());
test.parent = this.parent;
test.file = this.file;
Expand Down
8 changes: 8 additions & 0 deletions test/integration/fixtures/retries/early-pass.fixture.js
@@ -1,13 +1,21 @@
'use strict';
const assert = require('assert');

describe('retries', function () {
this.retries(1);
var times = 0;
var self = this;

it('should pass after 1 retry', function () {
times++;
if (times !== 2) {
throw new Error('retry error ' + times);
}
});

it('check for updated `suite.tests`', function() {
assert.equal(self.tests[0]._currentRetry, 1);
assert.ok(self.tests[0]._retriedTest);
assert.equal(self.tests[0].state, 'passed');
})
});
22 changes: 10 additions & 12 deletions test/integration/retries.spec.js
Expand Up @@ -2,6 +2,7 @@

var assert = require('assert');
var helpers = require('./helpers');
var runJSON = helpers.runMochaJSON;
var args = [];
var bang = require('../../lib/reporters/base').symbols.bang;

Expand Down Expand Up @@ -59,25 +60,22 @@ describe('retries', function() {
});

it('should exit early if test passes', function(done) {
helpers.runMochaJSON('retries/early-pass.fixture.js', args, function(
err,
res
) {
runJSON('retries/early-pass.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
return done(err);
}
assert.strictEqual(res.stats.passes, 1);
assert.strictEqual(res.stats.failures, 0);
assert.strictEqual(res.tests[0].currentRetry, 1);
assert.strictEqual(res.stats.tests, 1);
assert.strictEqual(res.code, 0);

expect(res, 'to have passed')
.and('to have passed test count', 2)
.and('to have failed test count', 0)
.and('to have retried test', 'should pass after 1 retry', 1);

done();
});
});

it('should let test override', function(done) {
helpers.runMochaJSON('retries/nested.fixture.js', args, function(err, res) {
runJSON('retries/nested.fixture.js', args, function(err, res) {
if (err) {
done(err);
return;
Expand Down
6 changes: 6 additions & 0 deletions test/unit/test.spec.js
Expand Up @@ -41,6 +41,12 @@ describe('Test', function() {
expect(this._test.clone().currentRetry(), 'to be', 1);
});

it('should add/keep the retriedTest value', function() {
var clone1 = this._test.clone();
expect(clone1.retriedTest(), 'to be', this._test);
expect(clone1.clone().retriedTest(), 'to be', this._test);
});

it('should copy the globals value', function() {
expect(this._test.clone().globals(), 'not to be empty');
});
Expand Down