From 3ee7ae0ce499f43e7a6e422e47f5141004301cae Mon Sep 17 00:00:00 2001 From: Brian Grinstead Date: Fri, 20 Nov 2015 06:52:32 -0800 Subject: [PATCH] Bug 1222617 - Filter out service worker messages that happened before a page load;r=bkelly --- devtools/server/actors/webconsole.js | 11 ++ devtools/shared/webconsole/test/chrome.ini | 1 + devtools/shared/webconsole/test/common.js | 83 +++++++++++++ .../test/test_console_serviceworker.html | 76 +----------- .../test_console_serviceworker_cached.html | 116 ++++++++++++++++++ 5 files changed, 212 insertions(+), 75 deletions(-) create mode 100644 devtools/shared/webconsole/test/test_console_serviceworker_cached.html diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index cccca801349..026af93ec10 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -735,9 +735,20 @@ WebConsoleActor.prototype = if (!this.consoleAPIListener) { break; } + + let requestStartTime = this.window ? + this.window.performance.timing.requestStart : 0; + let cache = this.consoleAPIListener .getCachedMessages(!this.parentActor.isRootActor); cache.forEach((aMessage) => { + // Filter out messages that came from a ServiceWorker but happened + // before the page was requested. + if (aMessage.innerID === "ServiceWorker" && + requestStartTime > aMessage.timeStamp) { + return; + } + let message = this.prepareConsoleMessageForRemote(aMessage); message._type = type; messages.push(message); diff --git a/devtools/shared/webconsole/test/chrome.ini b/devtools/shared/webconsole/test/chrome.ini index 5f682baf828..bb24a3fa940 100644 --- a/devtools/shared/webconsole/test/chrome.ini +++ b/devtools/shared/webconsole/test/chrome.ini @@ -18,6 +18,7 @@ support-files = [test_consoleapi.html] [test_consoleapi_innerID.html] [test_console_serviceworker.html] +[test_console_serviceworker_cached.html] [test_console_styling.html] [test_file_uri.html] [test_reflow.html] diff --git a/devtools/shared/webconsole/test/common.js b/devtools/shared/webconsole/test/common.js index 5ee01f9d6cf..ef5ef35e11e 100644 --- a/devtools/shared/webconsole/test/common.js +++ b/devtools/shared/webconsole/test/common.js @@ -133,6 +133,16 @@ function closeDebugger(aState, aCallback) aState.client = null; } +function checkConsoleAPICalls(consoleCalls, expectedConsoleCalls) +{ + is(consoleCalls.length, expectedConsoleCalls.length, + 'received correct number of console calls'); + expectedConsoleCalls.forEach(function(aMessage, aIndex) { + info("checking received console call #" + aIndex); + checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]); + }); +} + function checkConsoleAPICall(aCall, aExpected) { if (aExpected.level != "trace" && aExpected.arguments) { @@ -243,3 +253,76 @@ function nextTest(aMessage) { return gTestState.driver.next(aMessage); } + +function withFrame(url) { + return new Promise(resolve => { + let iframe = document.createElement("iframe"); + iframe.onload = function() { + resolve(iframe); + }; + iframe.src = url; + document.body.appendChild(iframe); + }); +} + +function navigateFrame(iframe, url) { + return new Promise(resolve => { + iframe.onload = function() { + resolve(iframe); + }; + iframe.src = url; + }); +} + +function forceReloadFrame(iframe) { + return new Promise(resolve => { + iframe.onload = function() { + resolve(iframe); + }; + iframe.contentWindow.location.reload(true); + }); +} + +function withActiveServiceWorker(win, url, scope) { + let opts = {}; + if (scope) { + opts.scope = scope; + } + return win.navigator.serviceWorker.register(url, opts).then(swr => { + if (swr.active) { + return swr; + } + + // Unfortunately we can't just use navigator.serviceWorker.ready promise + // here. If the service worker is for a scope that does not cover the window + // then the ready promise will never resolve. Instead monitor the service + // workers state change events to determine when its activated. + return new Promise(resolve => { + let sw = swr.waiting || swr.installing; + sw.addEventListener('statechange', function stateHandler(evt) { + if (sw.state === 'activated') { + sw.removeEventListener('statechange', stateHandler); + resolve(swr); + } + }); + }); + }); +} + +function messageServiceWorker(win, scope, message) { + return win.navigator.serviceWorker.getRegistration(scope).then(swr => { + return new Promise(resolve => { + win.navigator.serviceWorker.onmessage = evt => { + resolve(); + }; + let sw = swr.active || swr.waiting || swr.installing; + sw.postMessage({ type: 'PING', message: message }); + }); + }) +} + +function unregisterServiceWorker(win) { + return win.navigator.serviceWorker.ready.then(swr => { + return swr.unregister(); + }); +} diff --git a/devtools/shared/webconsole/test/test_console_serviceworker.html b/devtools/shared/webconsole/test/test_console_serviceworker.html index c429974f652..75bc0946594 100644 --- a/devtools/shared/webconsole/test/test_console_serviceworker.html +++ b/devtools/shared/webconsole/test/test_console_serviceworker.html @@ -64,75 +64,6 @@ let startTest = Task.async(function*() { }); addEventListener("load", startTest); -function withFrame(url) { - return new Promise(resolve => { - let iframe = document.createElement("iframe"); - iframe.onload = function() { - resolve(iframe); - }; - iframe.src = url; - document.body.appendChild(iframe); - }); -} - -function navigateFrame(iframe, url) { - return new Promise(resolve => { - iframe.onload = function() { - resolve(iframe); - }; - iframe.src = url; - }); -} - -function forceReloadFrame(iframe) { - return new Promise(resolve => { - iframe.onload = function() { - resolve(iframe); - }; - iframe.contentWindow.location.reload(true); - }); -} - -function withActiveServiceWorker(win, url, scope) { - return win.navigator.serviceWorker.register(url, { scope: scope }).then(swr => { - if (swr.active) { - return swr; - } - - // Unfortunately we can't just use navigator.serviceWorker.ready promise - // here. If the service worker is for a scope that does not cover the window - // then the ready promise will never resolve. Instead monitor the service - // workers state change events to determine when its activated. - return new Promise(resolve => { - let sw = swr.waiting || swr.installing; - sw.addEventListener('statechange', function stateHandler(evt) { - if (sw.state === 'activated') { - sw.removeEventListener('statechange', stateHandler); - resolve(swr); - } - }); - }); - }); -} - -function messageServiceWorker(win, scope, message) { - return win.navigator.serviceWorker.getRegistration(scope).then(swr => { - return new Promise(resolve => { - win.navigator.serviceWorker.onmessage = evt => { - resolve(); - }; - let sw = swr.active || swr.waiting || swr.installing; - sw.postMessage({ type: 'PING', message: message }); - }); - }) -} - -function unregisterServiceWorker(win) { - return win.navigator.serviceWorker.ready.then(swr => { - return swr.unregister(); - }); -} - let onAttach = Task.async(function*(state, response) { onConsoleAPICall = onConsoleAPICall.bind(null, state); state.dbgClient.addListener("consoleAPICall", onConsoleAPICall); @@ -194,12 +125,7 @@ let onAttach = Task.async(function*(state, response) { info('Service worker unregistered. Checking console calls.'); state.dbgClient.removeListener("consoleAPICall", onConsoleAPICall); - is(consoleCalls.length, expectedConsoleCalls.length, - 'received correct number of console calls'); - expectedConsoleCalls.forEach(function(aMessage, aIndex) { - info("checking received console call #" + aIndex); - checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]); - }); + checkConsoleAPICalls(consoleCalls, expectedConsoleCalls); } catch(error) { ok(false, 'unexpected error: ' + error); } finally { diff --git a/devtools/shared/webconsole/test/test_console_serviceworker_cached.html b/devtools/shared/webconsole/test/test_console_serviceworker_cached.html new file mode 100644 index 00000000000..3fbd8dffd48 --- /dev/null +++ b/devtools/shared/webconsole/test/test_console_serviceworker_cached.html @@ -0,0 +1,116 @@ + + + + + Test for getCachedMessages and Service Workers + + + + + +

Test for getCachedMessages and Service Workers

+ + + +