diff --git a/src/browserContext.ts b/src/browserContext.ts index 46a0633f68..f8fe3305a6 100644 --- a/src/browserContext.ts +++ b/src/browserContext.ts @@ -149,7 +149,7 @@ export abstract class BrowserContext extends EventEmitter { this._timeoutSettings.setDefaultTimeout(timeout); } - _enableScreencast(options: types.ContextScreencastOptions) { + async _enableScreencast(options: types.ContextScreencastOptions) { this._screencastOptions = options; fs.mkdirSync(path.dirname(options.dir), {recursive: true}); } diff --git a/src/firefox/ffBrowser.ts b/src/firefox/ffBrowser.ts index 0837e50022..8d824874f1 100644 --- a/src/firefox/ffBrowser.ts +++ b/src/firefox/ffBrowser.ts @@ -323,6 +323,11 @@ export class FFBrowserContext extends BrowserContext { await this._browser._connection.send('Browser.setRequestInterception', { browserContextId: this._browserContextId || undefined, enabled: !!this._requestInterceptor }); } + async _enableScreencast(options: types.ContextScreencastOptions): Promise { + await super._enableScreencast(options); + await this._browser._connection.send('Browser.setScreencastOptions', Object.assign({}, options, { browserContextId: this._browserContextId || undefined})); + } + async _doClose() { assert(this._browserContextId); await this._browser._connection.send('Browser.removeBrowserContext', { browserContextId: this._browserContextId }); diff --git a/src/firefox/ffPage.ts b/src/firefox/ffPage.ts index b4bb22845f..62cf56a021 100644 --- a/src/firefox/ffPage.ts +++ b/src/firefox/ffPage.ts @@ -32,6 +32,7 @@ import { FFNetworkManager } from './ffNetworkManager'; import { Protocol } from './protocol'; import { selectors } from '../selectors'; import { rewriteErrorMessage } from '../utils/stackTrace'; +import { Screencast } from '../browserContext'; const UTILITY_WORLD_NAME = '__playwright_utility_world__'; @@ -50,6 +51,7 @@ export class FFPage implements PageDelegate { private readonly _contextIdToContext: Map; private _eventListeners: RegisteredListener[]; private _workers = new Map(); + private readonly _idToScreencast = new Map(); constructor(session: FFSession, browserContext: FFBrowserContext, opener: FFPage | null) { this._session = session; @@ -82,6 +84,8 @@ export class FFPage implements PageDelegate { helper.addEventListener(this._session, 'Page.workerDestroyed', this._onWorkerDestroyed.bind(this)), helper.addEventListener(this._session, 'Page.dispatchMessageFromWorker', this._onDispatchMessageFromWorker.bind(this)), helper.addEventListener(this._session, 'Page.crashed', this._onCrashed.bind(this)), + helper.addEventListener(this._session, 'Page.screencastStarted', this._onScreencastStarted.bind(this)), + helper.addEventListener(this._session, 'Page.screencastStopped', this._onScreencastStopped.bind(this)), ]; this._pagePromise = new Promise(f => this._pageCallback = f); session.once(FFSessionEvents.Disconnected, () => this._page._didDisconnect()); @@ -255,6 +259,20 @@ export class FFPage implements PageDelegate { this._page._didCrash(); } + _onScreencastStarted(event: Protocol.Page.screencastStartedPayload) { + const screencast = new Screencast(event.file, this._page); + this._idToScreencast.set(event.uid, screencast); + this._browserContext.emit(Events.BrowserContext.ScreencastStarted, screencast); + } + + _onScreencastStopped(event: Protocol.Page.screencastStoppedPayload) { + const screencast = this._idToScreencast.get(event.uid); + if (!screencast) + return; + this._idToScreencast.delete(event.uid); + this._browserContext.emit(Events.BrowserContext.ScreencastStopped, screencast); + } + async exposeBinding(binding: PageBinding) { await this._session.send('Page.addBinding', { name: binding.name, script: binding.source }); } diff --git a/test/screencast.spec.ts b/test/screencast.spec.ts index f2bb80e646..34c4403c5c 100644 --- a/test/screencast.spec.ts +++ b/test/screencast.spec.ts @@ -257,12 +257,12 @@ it.fail(options.CHROMIUM || (options.WEBKIT && WIN))('should capture css transfo } }); -it.fail(options.CHROMIUM || options.FIREFOX)('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => { +it.fail(options.CHROMIUM)('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => { if (!toImpl) return; // Use server side of the context. All the code below also uses server side APIs. const context = toImpl(await browser.newContext()); - context._enableScreencast({width: 640, height: 480, dir: tmpDir}); + await context._enableScreencast({width: 640, height: 480, dir: tmpDir}); expect(context._screencastOptions).toBeTruthy(); const [startEvent, newPage] = await Promise.all([