From a995e3324b9da02c9cda8ad26e2695a853c28f30 Mon Sep 17 00:00:00 2001 From: Juerg B <44573692+juergba@users.noreply.github.com> Date: Mon, 24 Feb 2020 18:18:32 +0100 Subject: [PATCH] Fix: programmatic API cannot access retried test objects (#4181) --- lib/runner.js | 5 +++++ lib/test.js | 13 +++++++++++ .../fixtures/retries/early-pass.fixture.js | 8 +++++++ test/integration/retries.spec.js | 22 +++++++++---------- test/unit/test.spec.js | 6 +++++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/runner.js b/lib/runner.js index f96b020320..17fa290432 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -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) { diff --git a/lib/test.js b/lib/test.js index f32008a85b..65122b260c 100644 --- a/lib/test.js +++ b/lib/test.js @@ -36,6 +36,18 @@ 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()); @@ -43,6 +55,7 @@ Test.prototype.clone = function() { 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; diff --git a/test/integration/fixtures/retries/early-pass.fixture.js b/test/integration/fixtures/retries/early-pass.fixture.js index ddad40399e..87ef703a7a 100644 --- a/test/integration/fixtures/retries/early-pass.fixture.js +++ b/test/integration/fixtures/retries/early-pass.fixture.js @@ -1,8 +1,10 @@ '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++; @@ -10,4 +12,10 @@ describe('retries', function () { 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'); + }) }); diff --git a/test/integration/retries.spec.js b/test/integration/retries.spec.js index 3225dafbc4..e076595d7d 100644 --- a/test/integration/retries.spec.js +++ b/test/integration/retries.spec.js @@ -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; @@ -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; diff --git a/test/unit/test.spec.js b/test/unit/test.spec.js index 6192bf9f7f..4cff662c89 100644 --- a/test/unit/test.spec.js +++ b/test/unit/test.spec.js @@ -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'); });