diff --git a/packages/puppeteer-core/src/common/bidi/BrowsingContext.ts b/packages/puppeteer-core/src/common/bidi/BrowsingContext.ts index 7163eb8f5e5..ab1bfa55981 100644 --- a/packages/puppeteer-core/src/common/bidi/BrowsingContext.ts +++ b/packages/puppeteer-core/src/common/bidi/BrowsingContext.ts @@ -147,7 +147,7 @@ export class BrowsingContext extends Realm { info: Bidi.BrowsingContext.Info, browserName: string ) { - super(connection, info.context); + super(connection); this.#id = info.context; this.#url = info.url; this.#parent = info.parent; @@ -167,7 +167,7 @@ export class BrowsingContext extends Realm { } createRealmForSandbox(): Realm { - return new Realm(this.connection, this.#id); + return new Realm(this.connection); } get url(): string { diff --git a/packages/puppeteer-core/src/common/bidi/Realm.ts b/packages/puppeteer-core/src/common/bidi/Realm.ts index 29a38addbe5..dfb04f9b59e 100644 --- a/packages/puppeteer-core/src/common/bidi/Realm.ts +++ b/packages/puppeteer-core/src/common/bidi/Realm.ts @@ -7,7 +7,6 @@ import {scriptInjector} from '../ScriptInjector.js'; import {EvaluateFunc, HandleFor} from '../types.js'; import { PuppeteerURL, - debugError, getSourcePuppeteerURLIfAvailable, isString, } from '../util.js'; @@ -27,43 +26,52 @@ export const getSourceUrlComment = (url: string): string => { export class Realm extends EventEmitter { readonly connection: Connection; - readonly #id: string; + #id!: string; #sandbox!: Sandbox; - constructor(connection: Connection, id: string) { + constructor(connection: Connection) { super(); this.connection = connection; - this.#id = id; } get target(): Bidi.Script.Target { return { - context: this.#id, + context: this.#sandbox.environment._id, sandbox: this.#sandbox.name, }; } + handleRealmDestroyed = async ( + params: Bidi.Script.RealmDestroyed['params'] + ): Promise => { + if (params.realm === this.#id) { + // Note: The Realm is destroyed, so in theory the handle should be as + // well. + this.internalPuppeteerUtil = undefined; + } + }; + + handleRealmCreated = (params: Bidi.Script.RealmCreated['params']): void => { + if ( + params.type === 'window' && + params.context === this.#sandbox.environment._id && + params.sandbox === this.#sandbox.name + ) { + this.#id = params.realm; + void this.#sandbox.taskManager.rerunAll(); + } + }; + setSandbox(sandbox: Sandbox): void { this.#sandbox = sandbox; - - // TODO: Tack correct realm similar to BrowsingContexts - this.connection.on(Bidi.ChromiumBidi.Script.EventNames.RealmCreated, () => { - void this.#sandbox.taskManager.rerunAll(); - }); - // TODO(jrandolf): We should try to find a less brute-force way of doing - // this. + this.connection.on( + Bidi.ChromiumBidi.Script.EventNames.RealmCreated, + this.handleRealmCreated + ); this.connection.on( Bidi.ChromiumBidi.Script.EventNames.RealmDestroyed, - async () => { - const promise = this.internalPuppeteerUtil; - this.internalPuppeteerUtil = undefined; - try { - await (await promise)?.dispose(); - } catch (error) { - debugError(error); - } - } + this.handleRealmDestroyed ); } @@ -189,6 +197,17 @@ export class Realm extends EventEmitter { ? BidiSerializer.deserialize(result.result) : createBidiHandle(sandbox, result.result); } + + [Symbol.dispose](): void { + this.connection.off( + Bidi.ChromiumBidi.Script.EventNames.RealmCreated, + this.handleRealmCreated + ); + this.connection.off( + Bidi.ChromiumBidi.Script.EventNames.RealmDestroyed, + this.handleRealmDestroyed + ); + } } /**