diff --git a/src/common/Page.ts b/src/common/Page.ts index 0ba3c21bce1c6..c5f6e3e0c0332 100644 --- a/src/common/Page.ts +++ b/src/common/Page.ts @@ -16,7 +16,7 @@ import type { Readable } from 'stream'; -import { EventEmitter } from './EventEmitter.js'; +import { EventEmitter, Handler } from './EventEmitter.js'; import { Connection, CDPSession, @@ -459,6 +459,7 @@ export class Page extends EventEmitter { private _disconnectPromise?: Promise; private _userDragInterceptionEnabled = false; + private _handlerMap = new WeakMap(); /** * @internal @@ -623,11 +624,15 @@ export class Page extends EventEmitter { handler: (event: PageEventObject[K]) => void ): EventEmitter { if (eventName === 'request') { - return super.on(eventName, (event: HTTPRequest) => { + const wrap = (event: HTTPRequest) => { event.enqueueInterceptAction(() => handler(event as PageEventObject[K]) ); - }); + }; + + this._handlerMap.set(handler, wrap); + + return super.on(eventName, wrap); } return super.on(eventName, handler); } @@ -641,6 +646,17 @@ export class Page extends EventEmitter { return super.once(eventName, handler); } + off( + eventName: K, + handler: (event: PageEventObject[K]) => void + ): EventEmitter { + if (eventName === 'request') { + handler = this._handlerMap.get(handler) || handler; + } + + return super.off(eventName, handler); + } + /** * This method is typically coupled with an action that triggers file * choosing. The following example clicks a button that issues a file chooser diff --git a/test/page.spec.ts b/test/page.spec.ts index bd65a07f3c599..9fb6809b4d5d7 100644 --- a/test/page.spec.ts +++ b/test/page.spec.ts @@ -139,6 +139,23 @@ describe('Page', function () { // Two now because we added the handler back. expect(handler.callCount).toBe(2); }); + + it('should correctly added and removed request events', async () => { + const { page, server } = getTestState(); + + const handler = sinon.spy(); + page.on('request', handler); + await page.goto(server.EMPTY_PAGE); + expect(handler.callCount).toBe(1); + page.off('request', handler); + await page.goto(server.EMPTY_PAGE); + // Still one because we removed the handler. + expect(handler.callCount).toBe(1); + page.on('request', handler); + await page.goto(server.EMPTY_PAGE); + // Two now because we added the handler back. + expect(handler.callCount).toBe(2); + }); }); describeFailsFirefox('Page.Events.error', function () {