diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 8cc6c0dda5..4e7ef4d9d5 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1333 -Changed: lushnikov@chromium.org Tue Jul 5 18:02:39 MSK 2022 +1334 +Changed: lushnikov@chromium.org Wed Jul 6 00:25:34 MSK 2022 diff --git a/browser_patches/firefox/juggler/content/PageAgent.js b/browser_patches/firefox/juggler/content/PageAgent.js index b31d5c08a3..1fd9c0b05a 100644 --- a/browser_patches/firefox/juggler/content/PageAgent.js +++ b/browser_patches/firefox/juggler/content/PageAgent.js @@ -101,7 +101,6 @@ class PageAgent { helper.addObserver(this._filePickerShown.bind(this), 'juggler-file-picker-shown'), helper.addEventListener(this._messageManager, 'DOMContentLoaded', this._onDOMContentLoaded.bind(this)), helper.addObserver(this._onDocumentOpenLoad.bind(this), 'juggler-document-open-loaded'), - helper.addEventListener(this._messageManager, 'error', this._onError.bind(this)), helper.on(this._frameTree, 'load', this._onLoad.bind(this)), helper.on(this._frameTree, 'frameattached', this._onFrameAttached.bind(this)), helper.on(this._frameTree, 'framedetached', this._onFrameDetached.bind(this)), @@ -129,6 +128,7 @@ class PageAgent { }); }), this._runtime.events.onConsoleMessage(msg => this._browserPage.emit('runtimeConsole', msg)), + this._runtime.events.onRuntimeError(this._onRuntimeError.bind(this)), this._runtime.events.onExecutionContextCreated(this._onExecutionContextCreated.bind(this)), this._runtime.events.onExecutionContextDestroyed(this._onExecutionContextDestroyed.bind(this)), this._runtime.events.onBindingCalled(this._onBindingCalled.bind(this)), @@ -273,15 +273,11 @@ class PageAgent { }); } - _onError(errorEvent) { - const docShell = errorEvent.target.ownerGlobal.docShell; - const frame = this._frameTree.frameForDocShell(docShell); - if (!frame) - return; + _onRuntimeError({ executionContext, message, stack }) { this._browserPage.emit('pageUncaughtError', { - frameId: frame.id(), - message: errorEvent.message, - stack: errorEvent.error && typeof errorEvent.error.stack === 'string' ? errorEvent.error.stack : '', + frameId: executionContext.auxData().frameId, + message: message.toString(), + stack: stack.toString(), }); } diff --git a/browser_patches/firefox/juggler/content/Runtime.js b/browser_patches/firefox/juggler/content/Runtime.js index ef23526c17..20c046a1db 100644 --- a/browser_patches/firefox/juggler/content/Runtime.js +++ b/browser_patches/firefox/juggler/content/Runtime.js @@ -71,6 +71,7 @@ class Runtime { // Use plain callbacks instead. this.events = { onConsoleMessage: createEvent(), + onRuntimeError: createEvent(), onErrorFromWorker: createEvent(), onExecutionContextCreated: createEvent(), onExecutionContextDestroyed: createEvent(), @@ -129,7 +130,7 @@ class Runtime { observe: message => { if (!(message instanceof Ci.nsIScriptError) || !message.outerWindowID || - !message.category || disallowedMessageCategories.has(message.category) || message.hasException) { + !message.category || disallowedMessageCategories.has(message.category)) { return; } const errorWindow = Services.wm.getOuterWindowWithId(message.outerWindowID); @@ -138,26 +139,35 @@ class Runtime { return; } const executionContext = this._windowToExecutionContext.get(errorWindow); - if (!executionContext) + if (!executionContext) { return; + } const typeNames = { [Ci.nsIConsoleMessage.debug]: 'debug', [Ci.nsIConsoleMessage.info]: 'info', [Ci.nsIConsoleMessage.warn]: 'warn', [Ci.nsIConsoleMessage.error]: 'error', }; - emitEvent(this.events.onConsoleMessage, { - args: [{ - value: message.message, - }], - type: typeNames[message.logLevel], - executionContextId: executionContext.id(), - location: { - lineNumber: message.lineNumber, - columnNumber: message.columnNumber, - url: message.sourceName, - }, - }); + if (!message.hasException) { + emitEvent(this.events.onConsoleMessage, { + args: [{ + value: message.message, + }], + type: typeNames[message.logLevel], + executionContextId: executionContext.id(), + location: { + lineNumber: message.lineNumber, + columnNumber: message.columnNumber, + url: message.sourceName, + }, + }); + } else { + emitEvent(this.events.onRuntimeError, { + executionContext, + message: message.errorMessage, + stack: message.stack.toString(), + }); + } }, }; Services.console.registerListener(consoleServiceListener); diff --git a/tests/page/page-event-pageerror.spec.ts b/tests/page/page-event-pageerror.spec.ts index ea56f63f98..07ce00e411 100644 --- a/tests/page/page-event-pageerror.spec.ts +++ b/tests/page/page-event-pageerror.spec.ts @@ -132,3 +132,17 @@ it('should handle window', async ({ page, browserName, isElectron }) => { it('should remove a listener of a non-existing event handler', async ({ page }) => { page.removeListener('pageerror', () => {}); }); + +it('should emit error from unhandled rejects', async ({ page, browserName }) => { + it.fixme(browserName === 'firefox', 'see https://github.com/microsoft/playwright/issues/14165'); + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/14165' }); + const [error] = await Promise.all([ + page.waitForEvent('pageerror'), + page.setContent(` + + `), + ]); + expect(error.message).toBe('sad :('); +});