From 56de81d684d26cc89a6fb7a02715a77cb65800e0 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 15 Apr 2026 15:16:27 -0700 Subject: [PATCH] feat(page): add bringtofront event --- docs/src/api/class-browsercontext.md | 7 +++ packages/playwright-client/types/types.d.ts | 43 +++++++++++++++++++ .../src/client/browserContext.ts | 1 + packages/playwright-core/src/client/events.ts | 1 + .../playwright-core/src/protocol/validator.ts | 3 ++ .../src/server/browserContext.ts | 2 + .../dispatchers/browserContextDispatcher.ts | 3 ++ packages/playwright-core/src/server/page.ts | 1 + packages/playwright-core/types/types.d.ts | 43 +++++++++++++++++++ packages/protocol/src/channels.d.ts | 5 +++ packages/protocol/src/protocol.yml | 4 ++ 11 files changed, 113 insertions(+) diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index 4b9f0b7fc7ecd..e8099c2999340 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -68,6 +68,13 @@ await context.CloseAsync(); This event is not emitted. +## event: BrowserContext.bringToFront +* since: v1.60 +- argument: <[Page]> + +Emitted when a client calls [`method: Page.bringToFront`] on a page in this context. The event is dispatched to all +clients connected to the context, including the one that initiated the call. + ## property: BrowserContext.clock * since: v1.45 - type: <[Clock]> diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index a8cd0cf0dc87a..2ea72b8d39263 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -8225,6 +8225,13 @@ export interface BrowserContext { */ on(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + on(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -8362,6 +8369,11 @@ export interface BrowserContext { */ once(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. + */ + once(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. */ @@ -8417,6 +8429,13 @@ export interface BrowserContext { */ addListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + addListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -8554,6 +8573,11 @@ export interface BrowserContext { */ removeListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Removes an event listener added by `on` or `addListener`. + */ + removeListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Removes an event listener added by `on` or `addListener`. */ @@ -8609,6 +8633,11 @@ export interface BrowserContext { */ off(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Removes an event listener added by `on` or `addListener`. + */ + off(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Removes an event listener added by `on` or `addListener`. */ @@ -8664,6 +8693,13 @@ export interface BrowserContext { */ prependListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + prependListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -9453,6 +9489,13 @@ export interface BrowserContext { */ waitForEvent(event: 'backgroundpage', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise, timeout?: number } | ((page: Page) => boolean | Promise)): Promise; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + waitForEvent(event: 'bringtofront', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise, timeout?: number } | ((page: Page) => boolean | Promise)): Promise; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index 4d593e83ddab8..4ad2b16926b5d 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -149,6 +149,7 @@ export class BrowserContext extends ChannelOwner dialog.dismiss().catch(() => {}); } }); + this._channel.on('bringToFront', ({ page }) => this.emit(Events.BrowserContext.BringToFront, Page.from(page))); this._channel.on('request', ({ request, page }) => this._onRequest(network.Request.from(request), Page.fromNullable(page))); this._channel.on('requestFailed', ({ request, failureText, responseEndTiming, page }) => this._onRequestFailed(network.Request.from(request), responseEndTiming, failureText, Page.fromNullable(page))); this._channel.on('requestFinished', params => this._onRequestFinished(params)); diff --git a/packages/playwright-core/src/client/events.ts b/packages/playwright-core/src/client/events.ts index 5eb1cb711783d..b5c4279c67bbd 100644 --- a/packages/playwright-core/src/client/events.ts +++ b/packages/playwright-core/src/client/events.ts @@ -39,6 +39,7 @@ export const Events = { }, BrowserContext: { + BringToFront: 'bringtofront', Console: 'console', Close: 'close', Dialog: 'dialog', diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index d090e28ad459f..ce574850eb308 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -941,6 +941,9 @@ scheme.BrowserContextInitializer = tObject({ scheme.BrowserContextBindingCallEvent = tObject({ binding: tChannel(['BindingCall']), }); +scheme.BrowserContextBringToFrontEvent = tObject({ + page: tChannel(['Page']), +}); scheme.BrowserContextConsoleEvent = tObject({ type: tString, text: tString, diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index 7173434c8370e..f4d6d2f7c0626 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -45,6 +45,7 @@ import type * as types from './types'; import type * as channels from '@protocol/channels'; const BrowserContextEvent = { + BringToFront: 'bringtofront', Console: 'console', Close: 'close', Page: 'page', @@ -65,6 +66,7 @@ const BrowserContextEvent = { } as const; export type BrowserContextEventMap = { + [BrowserContextEvent.BringToFront]: [page: Page]; [BrowserContextEvent.Console]: [message: ConsoleMessage]; [BrowserContextEvent.Close]: []; [BrowserContextEvent.Page]: [page: Page]; diff --git a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts index 69453cfaccca3..bba8e78ccf209 100644 --- a/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/browserContextDispatcher.ts @@ -105,6 +105,9 @@ export class BrowserContextDispatcher extends Dispatcher { this._dispatchEvent('page', { page: PageDispatcher.from(this, page) }); }); + this.addObjectListener(BrowserContext.Events.BringToFront, page => { + this._dispatchEvent('bringToFront', { page: PageDispatcher.from(this, page) }); + }); this.addObjectListener(BrowserContext.Events.Close, () => { this._dispatchEvent('close'); this._dispose(); diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 257b657ba3d00..c074b91d502a2 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -648,6 +648,7 @@ export class Page extends SdkObject { async bringToFront(progress: Progress): Promise { await progress.race(this.delegate.bringToFront()); + this.emitOnContext(BrowserContext.Events.BringToFront, this); } async addInitScript(progress: Progress, source: string) { diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index a8cd0cf0dc87a..2ea72b8d39263 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -8225,6 +8225,13 @@ export interface BrowserContext { */ on(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + on(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -8362,6 +8369,11 @@ export interface BrowserContext { */ once(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. + */ + once(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Adds an event listener that will be automatically removed after it is triggered once. See `addListener` for more information about this event. */ @@ -8417,6 +8429,13 @@ export interface BrowserContext { */ addListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + addListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -8554,6 +8573,11 @@ export interface BrowserContext { */ removeListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Removes an event listener added by `on` or `addListener`. + */ + removeListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Removes an event listener added by `on` or `addListener`. */ @@ -8609,6 +8633,11 @@ export interface BrowserContext { */ off(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Removes an event listener added by `on` or `addListener`. + */ + off(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Removes an event listener added by `on` or `addListener`. */ @@ -8664,6 +8693,13 @@ export interface BrowserContext { */ prependListener(event: 'backgroundpage', listener: (page: Page) => any): this; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + prependListener(event: 'bringtofront', listener: (page: Page) => any): this; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. @@ -9453,6 +9489,13 @@ export interface BrowserContext { */ waitForEvent(event: 'backgroundpage', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise, timeout?: number } | ((page: Page) => boolean | Promise)): Promise; + /** + * Emitted when a client calls [page.bringToFront()](https://playwright.dev/docs/api/class-page#page-bring-to-front) + * on a page in this context. The event is dispatched to all clients connected to the context, including the one that + * initiated the call. + */ + waitForEvent(event: 'bringtofront', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise, timeout?: number } | ((page: Page) => boolean | Promise)): Promise; + /** * Emitted when Browser context gets closed. This might happen because of one of the following: * - Browser context is closed. diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index 4f0613005cfa1..a7ca57cf277bd 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -1647,6 +1647,7 @@ export type BrowserContextInitializer = { }; export interface BrowserContextEventTarget { on(event: 'bindingCall', callback: (params: BrowserContextBindingCallEvent) => void): this; + on(event: 'bringToFront', callback: (params: BrowserContextBringToFrontEvent) => void): this; on(event: 'console', callback: (params: BrowserContextConsoleEvent) => void): this; on(event: 'close', callback: (params: BrowserContextCloseEvent) => void): this; on(event: 'dialog', callback: (params: BrowserContextDialogEvent) => void): this; @@ -1700,6 +1701,9 @@ export interface BrowserContextChannel extends BrowserContextEventTarget, EventT export type BrowserContextBindingCallEvent = { binding: BindingCallChannel, }; +export type BrowserContextBringToFrontEvent = { + page: PageChannel, +}; export type BrowserContextConsoleEvent = { type: string, text: string, @@ -2075,6 +2079,7 @@ export type BrowserContextClockSetSystemTimeResult = void; export interface BrowserContextEvents { 'bindingCall': BrowserContextBindingCallEvent; + 'bringToFront': BrowserContextBringToFrontEvent; 'console': BrowserContextConsoleEvent; 'close': BrowserContextCloseEvent; 'dialog': BrowserContextDialogEvent; diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 0cdaf38f6dcf6..2387fdd7cc304 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -1516,6 +1516,10 @@ BrowserContext: parameters: binding: BindingCall + bringToFront: + parameters: + page: Page + console: parameters: $mixin: ConsoleMessage