From 63f255574d2189309418a42a60343b037e5977a9 Mon Sep 17 00:00:00 2001 From: dmitriy96 Date: Thu, 22 Mar 2018 19:13:07 +0300 Subject: [PATCH] fix: retry button retries multiple times --- lib/gui/app.js | 35 ++++++- .../tool-runner-factory/base-tool-runner.js | 4 + test/lib/gui/app.js | 95 +++++++++++++++++++ test/utils.js | 6 +- 4 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 test/lib/gui/app.js diff --git a/lib/gui/app.js b/lib/gui/app.js index cc82e4078..17ce99276 100644 --- a/lib/gui/app.js +++ b/lib/gui/app.js @@ -1,5 +1,7 @@ 'use strict'; +const _ = require('lodash'); + const ToolRunnerFactory = require('./tool-runner-factory'); module.exports = class App { @@ -7,14 +9,30 @@ module.exports = class App { const {program} = configs; this._tool = ToolRunnerFactory.create(program.name(), paths, tool, configs); + + this._browserConfigs = []; + this._retryCache = {}; } initialize() { return this._tool.initialize(); } - run(tests = []) { - return this._tool.run(tests); + run(tests) { + return _.isEmpty(tests) + ? this._tool.run(tests) + : this._runWithoutRetries(tests); + } + + _runWithoutRetries(tests) { + if (_.isEmpty(this._browserConfigs)) { + this._browserConfigs = _.map(this._tool.config.getBrowserIds(), (id) => this._tool.config.forBrowser(id)); + } + + this._disableRetries(); + + return this._tool.run(tests) + .finally(() => this._restoreRetries()); } updateReferenceImage(failedSuites = []) { @@ -28,4 +46,17 @@ module.exports = class App { get data() { return this._tool.tree; } + + _disableRetries() { + this._browserConfigs.forEach((broConfig) => { + this._retryCache[broConfig.id] = broConfig.retry; + broConfig.retry = 0; + }); + } + + _restoreRetries() { + this._browserConfigs.forEach((broConfig) => { + broConfig.retry = this._retryCache[broConfig.id]; + }); + } }; diff --git a/lib/gui/tool-runner-factory/base-tool-runner.js b/lib/gui/tool-runner-factory/base-tool-runner.js index 58eff3bf7..578cf6f50 100644 --- a/lib/gui/tool-runner-factory/base-tool-runner.js +++ b/lib/gui/tool-runner-factory/base-tool-runner.js @@ -28,6 +28,10 @@ module.exports = class ToolRunner { this._reportBuilder = ReportBuilderFactory.create(toolName, tool.config, pluginConfig); } + get config() { + return this._tool.config; + } + get tree() { return this._tree; } diff --git a/test/lib/gui/app.js b/test/lib/gui/app.js new file mode 100644 index 000000000..02602098e --- /dev/null +++ b/test/lib/gui/app.js @@ -0,0 +1,95 @@ +'use strict'; + +const _ = require('lodash'); +const Promise = require('bluebird'); + +const App = require('lib/gui/app'); +const ToolRunnerFactory = require('lib/gui/tool-runner-factory'); +const {stubTool, stubConfig} = require('../../utils'); + +describe('lib/gui/app', () => { + const sandbox = sinon.createSandbox().usingPromise(Promise); + let tool; + let toolRunner; + + const mkApp_ = (opts = {}) => { + opts = _.defaults(opts, { + paths: 'paths', + tool: stubTool(), + configs: {program: {name: () => 'tool'}} + }); + + return new App(opts.paths, opts.tool, opts.configs); + }; + + const mkToolRunner_ = (tool = {}) => { + return { + run: sandbox.stub().named('run').resolves(), + config: tool.config + }; + }; + + beforeEach(() => { + const browserConfigs = { + bro1: {id: 'bro1', retry: 1}, + bro2: {id: 'bro2', retry: 2} + }; + tool = stubTool(stubConfig(browserConfigs)); + toolRunner = mkToolRunner_(tool); + + sandbox.stub(ToolRunnerFactory, 'create').returns(toolRunner); + }); + + afterEach(() => sandbox.restore()); + + describe('run', () => { + it('should run all tests with retries from config', () => { + let retryBeforeRun; + toolRunner.run.callsFake(() => { + retryBeforeRun = tool.config.forBrowser('bro1').retry; + return Promise.resolve(); + }); + + return mkApp_({tool}) + .run() + .then(() => assert.equal(retryBeforeRun, 1)); + }); + + it('should run specified tests with no retries', () => { + let bro1RetryBeforeRun; + let bro2RetryBeforeRun; + toolRunner.run.callsFake(() => { + bro1RetryBeforeRun = tool.config.forBrowser('bro1').retry; + bro2RetryBeforeRun = tool.config.forBrowser('bro2').retry; + return Promise.resolve(); + }); + + return mkApp_({tool}) + .run(['test']) + .then(() => { + assert.equal(bro1RetryBeforeRun, 0); + assert.equal(bro2RetryBeforeRun, 0); + }); + }); + + it('should restore config retry values after run', () => { + return mkApp_({tool}) + .run(['test']) + .then(() => { + assert.equal(tool.config.forBrowser('bro1').retry, 1); + assert.equal(tool.config.forBrowser('bro2').retry, 2); + }); + }); + + it('should restore config retry values even after error', () => { + toolRunner.run.rejects(); + + return mkApp_({tool}) + .run(['test']) + .catch(() => { + assert.equal(tool.config.forBrowser('bro1').retry, 1); + assert.equal(tool.config.forBrowser('bro2').retry, 2); + }); + }); + }); +}); diff --git a/test/utils.js b/test/utils.js index 2044b9e25..52937a6de 100644 --- a/test/utils.js +++ b/test/utils.js @@ -2,10 +2,10 @@ const QEmitter = require('qemitter'); -exports.stubConfig = () => { +exports.stubConfig = (browserConfigs = {}) => { return { - getBrowserIds: sinon.stub().returns([]), - forBrowser: sinon.stub() + getBrowserIds: sinon.stub().named('getBrowserIds').returns(Object.keys(browserConfigs)), + forBrowser: sinon.stub().named('forBrowser').callsFake((bro) => browserConfigs[bro]) }; };