diff --git a/packages/playwright-core/src/cli/driver.ts b/packages/playwright-core/src/cli/driver.ts index 34b75ac0f6..0cec6b4dae 100644 --- a/packages/playwright-core/src/cli/driver.ts +++ b/packages/playwright-core/src/cli/driver.ts @@ -90,6 +90,38 @@ class ProtocolHandler { constructor(playwright: Playwright) { this._playwright = playwright; + playwright.instrumentation.addListener({ + onPageOpen: () => this._sendSnapshot(), + onPageNavigated: () => this._sendSnapshot(), + onPageClose: () => this._sendSnapshot(), + }, null); + } + + private _sendSnapshot() { + const browsers = []; + for (const browser of this._playwright.allBrowsers()) { + const b = { + name: browser.options.name, + guid: browser.guid, + contexts: [] as any[] + }; + browsers.push(b); + for (const context of browser.contexts()) { + const c = { + guid: context.guid, + pages: [] as any[] + }; + b.contexts.push(c); + for (const page of context.pages()) { + const p = { + guid: page.guid, + url: page.mainFrame().url() + }; + c.pages.push(p); + } + } + } + process.send!({ method: 'browsersChanged', params: { browsers } }); } async resetForReuse() { diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index b5eb170eef..d351c4a4a2 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -239,7 +239,7 @@ export class FrameManager { frame._onClearLifecycle(); const navigationEvent: NavigationEvent = { url, name, newDocument: frame._currentDocument, isPublic: true }; - frame.emit(Frame.Events.InternalNavigation, navigationEvent); + this._fireInternalFrameNavigation(frame, navigationEvent); if (!initial) { debugLogger.log('api', ` navigated to "${url}"`); this._page.frameNavigatedToNewDocument(frame); @@ -254,7 +254,7 @@ export class FrameManager { return; frame._url = url; const navigationEvent: NavigationEvent = { url, name: frame._name, isPublic: true }; - frame.emit(Frame.Events.InternalNavigation, navigationEvent); + this._fireInternalFrameNavigation(frame, navigationEvent); debugLogger.log('api', ` navigated to "${url}"`); } @@ -272,7 +272,7 @@ export class FrameManager { isPublic: !(documentId && frame._redirectedNavigations.has(documentId)), }; frame.setPendingDocument(undefined); - frame.emit(Frame.Events.InternalNavigation, navigationEvent); + this._fireInternalFrameNavigation(frame, navigationEvent); } frameDetached(frameId: string) { @@ -462,6 +462,12 @@ export class FrameManager { if (ws) ws.error(errorMessage); } + + private _fireInternalFrameNavigation(frame: Frame, event: NavigationEvent) { + frame.emit(Frame.Events.InternalNavigation, event); + if (event.isPublic && !frame.parentFrame()) + frame.instrumentation.onPageNavigated(frame._page, event.url); + } } export class Frame extends SdkObject { diff --git a/packages/playwright-core/src/server/instrumentation.ts b/packages/playwright-core/src/server/instrumentation.ts index f2bf68ecb7..e464e8e336 100644 --- a/packages/playwright-core/src/server/instrumentation.ts +++ b/packages/playwright-core/src/server/instrumentation.ts @@ -63,6 +63,7 @@ export interface Instrumentation { onAfterCall(sdkObject: SdkObject, metadata: CallMetadata): Promise; onEvent(sdkObject: SdkObject, metadata: CallMetadata): void; onPageOpen(page: Page): void; + onPageNavigated(page: Page, url: string): void; onPageClose(page: Page): void; onBrowserOpen(browser: Browser): void; onBrowserClose(browser: Browser): void; @@ -75,6 +76,7 @@ export interface InstrumentationListener { onAfterCall?(sdkObject: SdkObject, metadata: CallMetadata): Promise; onEvent?(sdkObject: SdkObject, metadata: CallMetadata): void; onPageOpen?(page: Page): void; + onPageNavigated?(page: Page, url: string): void; onPageClose?(page: Page): void; onBrowserOpen?(browser: Browser): void; onBrowserClose?(browser: Browser): void;