From cb15603ccb1b919fa4bec35d0e8d77409e9987e1 Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Thu, 1 Apr 2021 11:29:33 -0500 Subject: [PATCH] browser(firefox): do not report console messages twice. (#6031) References #6001 --- browser_patches/firefox/BUILD_NUMBER | 4 ++-- .../firefox/juggler/content/PageAgent.js | 2 +- .../firefox/juggler/protocol/PageHandler.js | 21 +++++++++++++++++-- test/workers.spec.ts | 15 +++++++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index bc58d7a1a9..b2d030f642 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1239 -Changed: ross.wollman@gmail.com Mon Mar 29 00:27:24 PDT 2021 +1240 +Changed: lushnikov@chromium.org Thu Apr 1 02:47:10 -05 2021 diff --git a/browser_patches/firefox/juggler/content/PageAgent.js b/browser_patches/firefox/juggler/content/PageAgent.js index 0eed1b6f7a..153da9071e 100644 --- a/browser_patches/firefox/juggler/content/PageAgent.js +++ b/browser_patches/firefox/juggler/content/PageAgent.js @@ -37,7 +37,7 @@ class WorkerData { evaluate: (options) => this._workerRuntime.send('evaluate', options), callFunction: (options) => this._workerRuntime.send('callFunction', options), getObjectProperties: (options) => this._workerRuntime.send('getObjectProperties', options), - disposeObject: (options) =>this._workerRuntime.send('disposeObject', options), + disposeObject: (options) => this._workerRuntime.send('disposeObject', options), }), ]; } diff --git a/browser_patches/firefox/juggler/protocol/PageHandler.js b/browser_patches/firefox/juggler/protocol/PageHandler.js index bab9e37462..9a1ea24fcc 100644 --- a/browser_patches/firefox/juggler/protocol/PageHandler.js +++ b/browser_patches/firefox/juggler/protocol/PageHandler.js @@ -15,10 +15,15 @@ const Cu = Components.utils; const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; const helper = new Helper(); +function hashConsoleMessage(params) { + return params.location.lineNumber + ':' + params.location.columnNumber + ':' + params.location.url; +} + class WorkerHandler { constructor(session, contentChannel, workerId) { this._session = session; this._contentWorker = contentChannel.connect(workerId); + this._workerConsoleMessages = new Set(); this._workerId = workerId; const emitWrappedProtocolEvent = eventName => { @@ -32,7 +37,10 @@ class WorkerHandler { this._eventListeners = [ contentChannel.register(workerId, { - runtimeConsole: emitWrappedProtocolEvent('Runtime.console'), + runtimeConsole: (params) => { + this._workerConsoleMessages.add(hashConsoleMessage(params)); + emitWrappedProtocolEvent('Runtime.console')(params); + }, runtimeExecutionContextCreated: emitWrappedProtocolEvent('Runtime.executionContextCreated'), runtimeExecutionContextDestroyed: emitWrappedProtocolEvent('Runtime.executionContextDestroyed'), }), @@ -111,7 +119,16 @@ class PageHandler { pageUncaughtError: emitProtocolEvent('Page.uncaughtError'), pageWorkerCreated: this._onWorkerCreated.bind(this), pageWorkerDestroyed: this._onWorkerDestroyed.bind(this), - runtimeConsole: emitProtocolEvent('Runtime.console'), + runtimeConsole: params => { + const consoleMessageHash = hashConsoleMessage(params); + for (const worker of this._workers) { + if (worker._workerConsoleMessages.has(consoleMessageHash)) { + worker._workerConsoleMessages.delete(consoleMessageHash); + return; + } + } + emitProtocolEvent('Runtime.console')(params); + }, runtimeExecutionContextCreated: emitProtocolEvent('Runtime.executionContextCreated'), runtimeExecutionContextDestroyed: emitProtocolEvent('Runtime.executionContextDestroyed'), diff --git a/test/workers.spec.ts b/test/workers.spec.ts index fd426636b7..9a6f4981db 100644 --- a/test/workers.spec.ts +++ b/test/workers.spec.ts @@ -54,6 +54,21 @@ it('should report console logs', async function({page}) { expect(page.url()).not.toContain('blob'); }); +it('should not report console logs from workers twice', (test, {browserName}) => { + test.fail(browserName === 'firefox'); +}, async function({page}) { + const messages = []; + page.on('console', msg => messages.push(msg.text())); + await Promise.all([ + page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1); console.log(2);'], {type: 'application/javascript'})))), + page.waitForEvent('console', msg => msg.text() === '1'), + page.waitForEvent('console', msg => msg.text() === '2'), + ]); + expect(messages).toEqual(['1', '2']); + // Firefox's juggler had an issue that reported worker blob urls as frame urls. + expect(page.url()).not.toContain('blob'); +}); + it('should have JSHandles for console logs', async function({page}) { const logPromise = new Promise(x => page.on('console', x)); await page.evaluate(() => new Worker(URL.createObjectURL(new Blob(['console.log(1,2,3,this)'], {type: 'application/javascript'}))));