Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/src/api/class-browsercontext.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ await context.CloseAsync();

This event is not emitted.

## event: BrowserContext.bringToFront
## event: BrowserContext.pickLocator
* 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
Emitted when a client calls [`method: Page.pickLocator`] 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
Expand Down
13 changes: 12 additions & 1 deletion packages/dashboard/src/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,20 @@ function tabFavicon(url: string): string {

const BUTTONS = ['left', 'middle', 'right'] as const;

export const Dashboard: React.FC<{ browser: string }> = ({ browser }) => {
export const Dashboard: React.FC<{
browser: string;
autoInteractive?: boolean;
onAutoInteractiveConsumed?: () => void;
}> = ({ browser, autoInteractive, onAutoInteractiveConsumed }) => {
const client = React.useContext(DashboardClientContext);
const [interactive, setInteractive] = React.useState(false);

React.useEffect(() => {
if (!autoInteractive)
return;
setInteractive(true);
onAutoInteractiveConsumed?.();
}, [autoInteractive, onAutoInteractiveConsumed]);
const [tabs, setTabs] = React.useState<Tab[] | null>(null);
const [url, setUrl] = React.useState('');
const [frame, setFrame] = React.useState<DashboardChannelEvents['frame']>();
Expand Down
1 change: 1 addition & 0 deletions packages/dashboard/src/dashboardChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type DashboardChannelEvents = {
tabs: { target: ContextTarget; tabs: Tab[] };
frame: { target: PageTarget; data: string; viewportWidth: number; viewportHeight: number };
elementPicked: { target: PageTarget; selector: string };
pickLocator: { target: PageTarget };
};

export type MouseButton = 'left' | 'middle' | 'right';
Expand Down
18 changes: 17 additions & 1 deletion packages/dashboard/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Grid } from './grid';
import { SessionModel } from './sessionModel';
import { DashboardClient } from './dashboardClient';

import type { DashboardChannelEvents } from './dashboardChannel';
import type { DashboardClientChannel } from './dashboardClient';

applyTheme();
Expand Down Expand Up @@ -54,6 +55,7 @@ if (document.hidden)
const App: React.FC = () => {
const [, setRevision] = React.useState(0);
const [sessionGuid, setSessionGuid] = React.useState<string | undefined>(parseHash);
const [autoInteractiveBrowser, setAutoInteractiveBrowser] = React.useState<string | undefined>();

React.useEffect(() => model.subscribe(() => setRevision(r => r + 1)), []);

Expand All @@ -63,8 +65,22 @@ const App: React.FC = () => {
return () => window.removeEventListener('popstate', onPopState);
}, []);

React.useEffect(() => {
const onPickLocator = (params: DashboardChannelEvents['pickLocator']) => {
setAutoInteractiveBrowser(params.target.browser);
if (parseHash() !== params.target.browser)
navigate('#session=' + encodeURIComponent(params.target.browser));
};
client.on('pickLocator', onPickLocator);
return () => client.off('pickLocator', onPickLocator);
}, []);

const content = sessionGuid
? <Dashboard browser={sessionGuid} />
? <Dashboard
browser={sessionGuid}
autoInteractive={autoInteractiveBrowser === sessionGuid}
onAutoInteractiveConsumed={() => setAutoInteractiveBrowser(undefined)}
/>
: <Grid model={model} />;

return <DashboardClientContext.Provider value={client}>{content}</DashboardClientContext.Provider>;
Expand Down
86 changes: 43 additions & 43 deletions packages/playwright-client/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8225,13 +8225,6 @@ 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.
Expand Down Expand Up @@ -8312,6 +8305,13 @@ export interface BrowserContext {
*/
on(event: 'page', listener: (page: Page) => any): this;

/**
* Emitted when a client calls [page.pickLocator()](https://playwright.dev/docs/api/class-page#page-pick-locator) 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: 'picklocator', listener: (page: Page) => any): this;

/**
* Emitted when a request is issued from any pages created through this context. The [request] object is read-only. To
* only listen for requests from a particular page, use
Expand Down Expand Up @@ -8369,11 +8369,6 @@ 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.
*/
Expand All @@ -8394,6 +8389,11 @@ export interface BrowserContext {
*/
once(event: 'page', 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: 'picklocator', 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.
*/
Expand Down Expand Up @@ -8429,13 +8429,6 @@ 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.
Expand Down Expand Up @@ -8516,6 +8509,13 @@ export interface BrowserContext {
*/
addListener(event: 'page', listener: (page: Page) => any): this;

/**
* Emitted when a client calls [page.pickLocator()](https://playwright.dev/docs/api/class-page#page-pick-locator) 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: 'picklocator', listener: (page: Page) => any): this;

/**
* Emitted when a request is issued from any pages created through this context. The [request] object is read-only. To
* only listen for requests from a particular page, use
Expand Down Expand Up @@ -8573,11 +8573,6 @@ 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`.
*/
Expand All @@ -8598,6 +8593,11 @@ export interface BrowserContext {
*/
removeListener(event: 'page', listener: (page: Page) => any): this;

/**
* Removes an event listener added by `on` or `addListener`.
*/
removeListener(event: 'picklocator', listener: (page: Page) => any): this;

/**
* Removes an event listener added by `on` or `addListener`.
*/
Expand Down Expand Up @@ -8633,11 +8633,6 @@ 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`.
*/
Expand All @@ -8658,6 +8653,11 @@ export interface BrowserContext {
*/
off(event: 'page', listener: (page: Page) => any): this;

/**
* Removes an event listener added by `on` or `addListener`.
*/
off(event: 'picklocator', listener: (page: Page) => any): this;

/**
* Removes an event listener added by `on` or `addListener`.
*/
Expand Down Expand Up @@ -8693,13 +8693,6 @@ 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.
Expand Down Expand Up @@ -8780,6 +8773,13 @@ export interface BrowserContext {
*/
prependListener(event: 'page', listener: (page: Page) => any): this;

/**
* Emitted when a client calls [page.pickLocator()](https://playwright.dev/docs/api/class-page#page-pick-locator) 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: 'picklocator', listener: (page: Page) => any): this;

/**
* Emitted when a request is issued from any pages created through this context. The [request] object is read-only. To
* only listen for requests from a particular page, use
Expand Down Expand Up @@ -9489,13 +9489,6 @@ export interface BrowserContext {
*/
waitForEvent(event: 'backgroundpage', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise<boolean>, timeout?: number } | ((page: Page) => boolean | Promise<boolean>)): Promise<Page>;

/**
* 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<boolean>, timeout?: number } | ((page: Page) => boolean | Promise<boolean>)): Promise<Page>;

/**
* Emitted when Browser context gets closed. This might happen because of one of the following:
* - Browser context is closed.
Expand Down Expand Up @@ -9576,6 +9569,13 @@ export interface BrowserContext {
*/
waitForEvent(event: 'page', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise<boolean>, timeout?: number } | ((page: Page) => boolean | Promise<boolean>)): Promise<Page>;

/**
* Emitted when a client calls [page.pickLocator()](https://playwright.dev/docs/api/class-page#page-pick-locator) 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: 'picklocator', optionsOrPredicate?: { predicate?: (page: Page) => boolean | Promise<boolean>, timeout?: number } | ((page: Page) => boolean | Promise<boolean>)): Promise<Page>;

/**
* Emitted when a request is issued from any pages created through this context. The [request] object is read-only. To
* only listen for requests from a particular page, use
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
dialog.dismiss().catch(() => {});
}
});
this._channel.on('bringToFront', ({ page }) => this.emit(Events.BrowserContext.BringToFront, Page.from(page)));
this._channel.on('pickLocator', ({ page }) => this.emit(Events.BrowserContext.PickLocator, 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));
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/client/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const Events = {
},

BrowserContext: {
BringToFront: 'bringtofront',
PickLocator: 'picklocator',
Console: 'console',
Close: 'close',
Dialog: 'dialog',
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/protocol/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ scheme.BrowserContextInitializer = tObject({
scheme.BrowserContextBindingCallEvent = tObject({
binding: tChannel(['BindingCall']),
});
scheme.BrowserContextBringToFrontEvent = tObject({
scheme.BrowserContextPickLocatorEvent = tObject({
page: tChannel(['Page']),
});
scheme.BrowserContextConsoleEvent = tObject({
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright-core/src/server/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import type * as types from './types';
import type * as channels from '@protocol/channels';

const BrowserContextEvent = {
BringToFront: 'bringtofront',
PickLocator: 'picklocator',
Console: 'console',
Close: 'close',
Page: 'page',
Expand All @@ -66,7 +66,7 @@ const BrowserContextEvent = {
} as const;

export type BrowserContextEventMap = {
[BrowserContextEvent.BringToFront]: [page: Page];
[BrowserContextEvent.PickLocator]: [page: Page];
[BrowserContextEvent.Console]: [message: ConsoleMessage];
[BrowserContextEvent.Close]: [];
[BrowserContextEvent.Page]: [page: Page];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
this.addObjectListener(BrowserContext.Events.Page, page => {
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.PickLocator, page => {
this._dispatchEvent('pickLocator', { page: PageDispatcher.from(this, page) });
});
this.addObjectListener(BrowserContext.Events.Close, () => {
this._dispatchEvent('close');
Expand Down
1 change: 0 additions & 1 deletion packages/playwright-core/src/server/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,6 @@ export class Page extends SdkObject<PageEventMap> {

async bringToFront(progress: Progress): Promise<void> {
await progress.race(this.delegate.bringToFront());
this.emitOnContext(BrowserContext.Events.BringToFront, this);
}

async addInitScript(progress: Progress, source: string) {
Expand Down
1 change: 1 addition & 0 deletions packages/playwright-core/src/server/recorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ export class Recorder extends EventEmitter<RecorderEventMap> implements Instrume
}

async pickLocator(progress: Progress, page: Page): Promise<string> {
page.emitOnContext(BrowserContext.Events.PickLocator, page);
if (this._mode !== 'none')
await progress.race(this.setMode('none'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ export class DashboardConnection implements Transport {
});
}

emitPickLocator(att: AttachedBrowser, pageGuid: string) {
this.sendEvent?.('pickLocator', {
target: { browser: att.browserGuid, context: att.contextGuid, page: pageGuid },
});
}

private _pushSessions = () => {
if (this._pushSessionsScheduled)
return;
Expand Down Expand Up @@ -205,6 +211,11 @@ class AttachedBrowser {
if (!this._selectedPage)
this._selectPage(page).catch(() => {});
}),
eventsHelper.addEventListener(this._context, 'picklocator', page => {
this._selectPage(page)
.then(() => this._owner.emitPickLocator(this, this._pageId(page)))
.catch(() => {});
}),
);
const pages = this._context.pages();
if (pages.length > 0)
Expand Down
Loading
Loading