From 4f4746541e6b538feb6739d1374b3241520b9868 Mon Sep 17 00:00:00 2001 From: Nico Jansen Date: Mon, 17 Feb 2020 17:16:23 +0100 Subject: [PATCH] fix(client): prevent race condition in clear context --- client/karma.js | 59 +++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/client/karma.js b/client/karma.js index edefcdb14..988824908 100644 --- a/client/karma.js +++ b/client/karma.js @@ -1,3 +1,4 @@ +// @ts-check var stringify = require('../common/stringify') var constant = require('./constants') var util = require('../common/util') @@ -89,8 +90,8 @@ function Karma (socket, iframe, opener, navigator, location, document) { childWindow.close() } childWindow = opener(url) - // run context on parent element (client_with_context) - // using window.__karma__.scriptUrls to get the html element strings and load them dynamically + // run context on parent element (client_with_context) + // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { @@ -120,14 +121,25 @@ function Karma (socket, iframe, opener, navigator, location, document) { } loadScript(0) } - // run in iframe + // run in iframe } else { iframe.src = policy.createURL(url) } } + this.scheduleExecution = function (execution) { + if (reloadingContext) { + this.scheduledExecution = execution + } else { + execution() + } + } + this.onbeforeunload = function () { - if (!reloadingContext) { + if (reloadingContext) { + self.scheduledExecution && self.scheduledExecution() + self.scheduledExecution = undefined + } else { // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) self.error('Some of your tests did a full page reload!') } @@ -259,24 +271,29 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.on('execute', function (cfg) { - // reset startEmitted and reload the iframe - startEmitted = false - self.config = cfg - // if not clearing context, reloadingContext always true to prevent beforeUnload error - reloadingContext = !self.config.clearContext - navigateContextTo(constant.CONTEXT_URL) - - if (self.config.clientDisplayNone) { - [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { - el.style.display = 'none' - }) - } + // clearing context can be in progress, make sure to schedule execution after it. + // See https://github.com/karma-runner/karma/issues/3424 + self.scheduleExecution(() => { + // reset startEmitted and reload the iframe + startEmitted = false + self.config = cfg + + // if not clearing context, reloadingContext always true to prevent beforeUnload error + reloadingContext = !self.config.clearContext + navigateContextTo(constant.CONTEXT_URL) + + if (self.config.clientDisplayNone) { + [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { + el.style.display = 'none' + }) + } - // clear the console before run - // works only on FF (Safari, Chrome do not allow to clear console from js source) - if (window.console && window.console.clear) { - window.console.clear() - } + // clear the console before run + // works only on FF (Safari, Chrome do not allow to clear console from js source) + if (window.console && window.console.clear) { + window.console.clear() + } + }) }) socket.on('stop', function () { this.complete()