diff --git a/packages/puppeteer-core/src/api/Frame.ts b/packages/puppeteer-core/src/api/Frame.ts index 6695f14a6ec8a..c79ab9fdb04a2 100644 --- a/packages/puppeteer-core/src/api/Frame.ts +++ b/packages/puppeteer-core/src/api/Frame.ts @@ -830,6 +830,11 @@ export abstract class Frame extends EventEmitter { */ abstract parentFrame(): Frame | null; + /** + * The root of this frame, if any. + */ + abstract rootFrame(): Frame | null; + /** * An array of child frames. */ diff --git a/packages/puppeteer-core/src/bidi/Frame.ts b/packages/puppeteer-core/src/bidi/Frame.ts index c1bf67cb55059..b1e62ce7a76d8 100644 --- a/packages/puppeteer-core/src/bidi/Frame.ts +++ b/packages/puppeteer-core/src/bidi/Frame.ts @@ -132,6 +132,14 @@ export class BidiFrame extends Frame { return this.#page.frame(this._parentId ?? ''); } + override rootFrame(): BidiFrame | null { + if (this.parentFrame() === null) { + return this; + } else { + return this.parentFrame()!.rootFrame(); + } + } + override childFrames(): BidiFrame[] { return this.#page.childFrames(this.#context.id); } diff --git a/packages/puppeteer-core/src/cdp/Frame.ts b/packages/puppeteer-core/src/cdp/Frame.ts index 7d2af981066ca..66b991fb0320d 100644 --- a/packages/puppeteer-core/src/cdp/Frame.ts +++ b/packages/puppeteer-core/src/cdp/Frame.ts @@ -287,6 +287,14 @@ export class CdpFrame extends Frame { return this._frameManager._frameTree.parentFrame(this._id) || null; } + override rootFrame(): CdpFrame | null { + if (this.parentFrame() === null) { + return this; + } else { + return this.parentFrame()!.rootFrame(); + } + } + override childFrames(): CdpFrame[] { return this._frameManager._frameTree.childFrames(this._id); } @@ -295,9 +303,9 @@ export class CdpFrame extends Frame { if (this.isOOPFrame()) { return this._frameManager._deviceRequestPromptManager(this.#client); } - const parentFrame = this.parentFrame(); - assert(parentFrame !== null); - return parentFrame.#deviceRequestPromptManager(); + const rootFrame = this.rootFrame(); + assert(rootFrame !== null); + return rootFrame._frameManager._deviceRequestPromptManager(this.#client); } @throwIfDetached