From 15d80f47a227839e9b0d54aeddf49b9aa9afe8aa Mon Sep 17 00:00:00 2001 From: Vojta Jina Date: Fri, 19 Jul 2013 20:38:45 -0700 Subject: [PATCH] fix: detect a full page reload, show error and recover We need to make this even better, by providing which test caused the page reload. Before that, the adapters need to report spec_start. Even after that, the information which test caused the page reload does not have to be correct. Multiple tests can run within a single event loop (and they do, until there is an async test), so the developer has to set `jasmine.UPDATE_INTERVAL = -1` to know what test caused the page reload. Closes #27 --- static/karma.src.js | 20 +++++++++++++++++--- test/client/karma.spec.js | 12 ++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/static/karma.src.js b/static/karma.src.js index e88295b15..93b4bf33b 100644 --- a/static/karma.src.js +++ b/static/karma.src.js @@ -54,6 +54,9 @@ var Karma = function(socket, context, navigator, location) { this.VERSION = VERSION; this.setupContext = function(contextWindow) { + if (hasError) { + return; + } var getConsole = function(currentWindow) { return currentWindow.console || { @@ -72,6 +75,13 @@ var Karma = function(socket, context, navigator, location) { return contextWindow.__karma__.error.apply(contextWindow.__karma__, arguments); }; + contextWindow.onbeforeunload = function(e, b) { + if (context.src !== 'about:blank') { + // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) + contextWindow.__karma__.error('Some of your tests did a full page reload!'); + } + }; + // patch the console var localConsole = contextWindow.console = getConsole(contextWindow); var browserConsoleLog = localConsole.log; @@ -170,7 +180,7 @@ var Karma = function(socket, context, navigator, location) { // we are not going to execute at all this.error = function(msg, url, line) { hasError = true; - socket.emit('error', msg + '\nat ' + url + ':' + line); + socket.emit('error', url ? msg + '\nat ' + url + (line ? ':' + line : '') : msg); this.complete(); return false; }; @@ -180,8 +190,12 @@ var Karma = function(socket, context, navigator, location) { }; this.complete = function(result) { - socket.emit('complete', result || {}); - clearContext(); + // give the browser some time to breath, there could be a page reload, but because a bunch of + // tests could run in the same event loop, we wouldn't notice. + setTimeout(function() { + socket.emit('complete', result || {}); + clearContext(); + }, 0); }; this.info = function(info) { diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 0a7ca0f69..e2229021f 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -45,6 +45,18 @@ describe('karma', function() { }); + it('should not set up context if there was an error', function() { + var mockWindow = {}; + + k.error('page reload'); + k.setupContext(mockWindow); + + expect(mockWindow.__karma__).toBeUndefined(); + expect(mockWindow.onbeforeunload).toBeUndefined(); + expect(mockWindow.onerror).toBeUndefined(); + }); + + it('should report navigator name', function() { var spyInfo = jasmine.createSpy('onInfo').andCallFake(function(info) { expect(info.name).toBe('Fake browser name');