diff --git a/src/server/chromium/crPage.ts b/src/server/chromium/crPage.ts index f0bfdc562a..d5fb77ae40 100644 --- a/src/server/chromium/crPage.ts +++ b/src/server/chromium/crPage.ts @@ -217,14 +217,6 @@ export class CRPage implements PageDelegate { await this._mainFrameSession._client.send('Emulation.setDefaultBackgroundColorOverride', { color }); } - async startScreencast(options: types.PageScreencastOptions): Promise { - await this._mainFrameSession._startScreencast(createGuid(), options); - } - - async stopScreencast(): Promise { - await this._mainFrameSession._stopScreencast(); - } - async takeScreenshot(format: 'png' | 'jpeg', documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined): Promise { const { visualViewport } = await this._mainFrameSession._client.send('Page.getLayoutMetrics'); if (!documentRect) { @@ -335,7 +327,6 @@ class FrameSession { private _swappedIn = false; private _videoRecorder: VideoRecorder | null = null; private _screencastId: string | null = null; - private _screencastState: 'stopped' | 'starting' | 'started' = 'stopped'; constructor(crPage: CRPage, client: CRSession, targetId: string, parentSession: FrameSession | null) { this._client = client; @@ -777,44 +768,30 @@ class FrameSession { } async _startScreencast(screencastId: string, options: types.PageScreencastOptions): Promise { - if (this._screencastState !== 'stopped') - throw new Error('Already started'); - const videoRecorder = await VideoRecorder.launch(options); - this._screencastState = 'starting'; - try { - this._screencastState = 'started'; - this._videoRecorder = videoRecorder; - this._screencastId = screencastId; - this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage.pageOrError()); - await Promise.all([ - this._client.send('Page.startScreencast', { - format: 'jpeg', - quality: 90, - maxWidth: options.width, - maxHeight: options.height, - }), - new Promise(f => this._client.once('Page.screencastFrame', f)) - ]); - } catch (e) { - videoRecorder.stop().catch(() => {}); - throw e; - } + assert(!this._screencastId); + this._videoRecorder = await VideoRecorder.launch(options); + this._screencastId = screencastId; + const gotFirstFrame = new Promise(f => this._client.once('Page.screencastFrame', f)); + await this._client.send('Page.startScreencast', { + format: 'jpeg', + quality: 90, + maxWidth: options.width, + maxHeight: options.height, + }); + this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage.pageOrError()); + await gotFirstFrame; } async _stopScreencast(): Promise { - if (this._screencastState !== 'started') - throw new Error('No screencast in progress, current state: ' + this._screencastState); - try { - await this._client.send('Page.stopScreencast'); - } finally { - const recorder = this._videoRecorder!; - const screencastId = this._screencastId!; - this._videoRecorder = null; - this._screencastId = null; - this._screencastState = 'stopped'; - await recorder.stop().catch(() => {}); - this._crPage._browserContext._browser._videoFinished(screencastId); - } + if (!this._screencastId) + return; + await this._client._sendMayFail('Page.stopScreencast'); + const recorder = this._videoRecorder!; + const screencastId = this._screencastId; + this._videoRecorder = null; + this._screencastId = null; + await recorder.stop().catch(() => {}); + this._crPage._browserContext._browser._videoFinished(screencastId); } async _updateExtraHTTPHeaders(initial: boolean): Promise { diff --git a/src/server/firefox/ffPage.ts b/src/server/firefox/ffPage.ts index bd2e4edaa1..f436358367 100644 --- a/src/server/firefox/ffPage.ts +++ b/src/server/firefox/ffPage.ts @@ -380,18 +380,6 @@ export class FFPage implements PageDelegate { throw new Error('Not implemented'); } - async startScreencast(options: types.PageScreencastOptions): Promise { - this._session.send('Page.startVideoRecording', { - file: options.outputFile, - width: options.width, - height: options.height, - }); - } - - async stopScreencast(): Promise { - await this._session.send('Page.stopVideoRecording'); - } - async takeScreenshot(format: 'png' | 'jpeg', documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined): Promise { if (!documentRect) { const context = await this._page.mainFrame()._utilityContext(); diff --git a/src/server/page.ts b/src/server/page.ts index 192a6c7b30..35cbad687a 100644 --- a/src/server/page.ts +++ b/src/server/page.ts @@ -61,8 +61,6 @@ export interface PageDelegate { canScreenshotOutsideViewport(): boolean; resetViewport(): Promise; // Only called if canScreenshotOutsideViewport() returns false. setBackgroundColor(color?: { r: number; g: number; b: number; a: number; }): Promise; - startScreencast(options: types.PageScreencastOptions): Promise; - stopScreencast(): Promise; takeScreenshot(format: string, documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined): Promise; isElementHandle(remoteObject: any): boolean; diff --git a/src/server/webkit/wkPage.ts b/src/server/webkit/wkPage.ts index d654b462eb..4f28ab2954 100644 --- a/src/server/webkit/wkPage.ts +++ b/src/server/webkit/wkPage.ts @@ -119,7 +119,7 @@ export class WKPage implements PageDelegate { const size = this._browserContext._options.recordVideo.size || this._browserContext._options.viewport || { width: 1280, height: 720 }; const outputFile = path.join(this._browserContext._options.recordVideo.dir, createGuid() + '.webm'); promises.push(this._browserContext._ensureVideosPath().then(() => { - return this.startScreencast({ + return this._startScreencast({ ...size, outputFile, }); @@ -712,8 +712,7 @@ export class WKPage implements PageDelegate { } async closePage(runBeforeUnload: boolean): Promise { - if (this._recordingVideoFile) - await this.stopScreencast(); + await this._stopScreencast(); await this._pageProxySession.sendMayFail('Target.close', { targetId: this._session.sessionId, runBeforeUnload @@ -728,28 +727,22 @@ export class WKPage implements PageDelegate { await this._session.send('Page.setDefaultBackgroundColorOverride', { color }); } - async startScreencast(options: types.PageScreencastOptions): Promise { - if (this._recordingVideoFile) - throw new Error('Already recording'); + async _startScreencast(options: types.PageScreencastOptions): Promise { + assert(!this._recordingVideoFile); + const { screencastId } = await this._pageProxySession.send('Screencast.start', { + file: options.outputFile, + width: options.width, + height: options.height, + }); this._recordingVideoFile = options.outputFile; - try { - const {screencastId} = await this._pageProxySession.send('Screencast.start', { - file: options.outputFile, - width: options.width, - height: options.height, - }) as any; - this._browserContext._browser._videoStarted(this._browserContext, screencastId, options.outputFile, this.pageOrError()); - } catch (e) { - this._recordingVideoFile = null; - throw e; - } + this._browserContext._browser._videoStarted(this._browserContext, screencastId, options.outputFile, this.pageOrError()); } - async stopScreencast(): Promise { + async _stopScreencast(): Promise { if (!this._recordingVideoFile) - throw new Error('No video recording in progress'); + return; + await this._pageProxySession.sendMayFail('Screencast.stop'); this._recordingVideoFile = null; - await this._pageProxySession.send('Screencast.stop'); } async takeScreenshot(format: string, documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined): Promise {