From 6b27459ba0137af860cd3b78e881612313dcd828 Mon Sep 17 00:00:00 2001 From: Andrey Belym Date: Thu, 6 Sep 2018 18:22:33 +0300 Subject: [PATCH] Wait until outStream is finished (closes #2502) --- src/reporter/index.js | 17 +++++++++++++++++ src/runner/index.js | 28 ++++++++++++++++------------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/reporter/index.js b/src/reporter/index.js index 626d242a114..a4d412bcb11 100644 --- a/src/reporter/index.js +++ b/src/reporter/index.js @@ -1,14 +1,17 @@ import { find, sortBy } from 'lodash'; +import promisifyEvent from 'promisify-event'; import ReporterPluginHost from './plugin-host'; export default class Reporter { constructor (plugin, task, outStream) { this.plugin = new ReporterPluginHost(plugin, outStream); + this.disposed = false; this.passed = 0; this.skipped = task.tests.filter(test => test.skip).length; this.testCount = task.tests.length - this.skipped; this.reportQueue = Reporter._createReportQueue(task); + this.outStream = outStream; this._assignTaskEventHandlers(task); } @@ -129,4 +132,18 @@ export default class Reporter { this.plugin.reportTaskDone(endTime, this.passed, task.warningLog.messages); }); } + + async dispose () { + if (this.disposed) + return; + + this.disposed = true; + + if (!this.outStream) + return; + + this.outStream.end(); + + await promisifyEvent(this.outStream, 'finish'); + } } diff --git a/src/runner/index.js b/src/runner/index.js index 57918ea4bf4..d3722c9ec33 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -37,18 +37,22 @@ export default class Runner extends EventEmitter { }; } - static async _disposeTaskAndRelatedAssets (task, browserSet, testedApp) { + static async _disposeTaskAndRelatedAssets (task, browserSet, reporters, testedApp) { task.abort(); task.removeAllListeners(); - await Runner._disposeBrowserSetAndTestedApp(browserSet, testedApp); + await Runner._disposeAssets(browserSet, reporters, testedApp); } - static async _disposeBrowserSetAndTestedApp (browserSet, testedApp) { - await browserSet.dispose(); + static async _disposeAssets (browserSet, reporters, testedApp) { + const disposeReportersPromise = Promise.all(reporters.map(reporter => reporter.dispose())); + const testedAppKillPromise = testedApp ? testedApp.kill() : Promise.resolve(); - if (testedApp) - await testedApp.kill(); + await Promise.all([ + browserSet.dispose(), + disposeReportersPromise, + testedAppKillPromise + ]); } _createCancelablePromise (taskPromise) { @@ -68,7 +72,7 @@ export default class Runner extends EventEmitter { } // Run task - async _getTaskResult (task, browserSet, reporter, testedApp) { + async _getTaskResult (task, browserSet, reporters, testedApp) { task.on('browser-job-done', job => browserSet.releaseConnection(job.browserConnection)); var promises = [ @@ -83,21 +87,21 @@ export default class Runner extends EventEmitter { await Promise.race(promises); } catch (err) { - await Runner._disposeTaskAndRelatedAssets(task, browserSet, testedApp); + await Runner._disposeTaskAndRelatedAssets(task, browserSet, reporters, testedApp); throw err; } - await Runner._disposeBrowserSetAndTestedApp(browserSet, testedApp); + await Runner._disposeAssets(browserSet, reporters, testedApp); - return reporter.testCount - reporter.passed; + return reporters[0].testCount - reporters[0].passed; } _runTask (reporterPlugins, browserSet, tests, testedApp) { var completed = false; var task = new Task(tests, browserSet.browserConnectionGroups, this.proxy, this.opts); var reporters = reporterPlugins.map(reporter => new Reporter(reporter.plugin, task, reporter.outStream)); - var completionPromise = this._getTaskResult(task, browserSet, reporters[0], testedApp); + var completionPromise = this._getTaskResult(task, browserSet, reporters, testedApp); task.once('start', startHandlingTestErrors); @@ -118,7 +122,7 @@ export default class Runner extends EventEmitter { var cancelTask = async () => { if (!completed) - await Runner._disposeTaskAndRelatedAssets(task, browserSet, testedApp); + await Runner._disposeTaskAndRelatedAssets(task, browserSet, reporters, testedApp); }; return { completionPromise, cancelTask };