fix(screencast): ensure that _videostarted is fired after newPage (#3807)

This commit is contained in:
Yury Semikhatsky 2020-09-08 17:01:00 -07:00 committed by GitHub
parent a5a563659b
commit af58c8acb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 17 deletions

View file

@ -21,6 +21,7 @@ import { EventEmitter } from 'events';
import { Download } from './download'; import { Download } from './download';
import { ProxySettings } from './types'; import { ProxySettings } from './types';
import { ChildProcess } from 'child_process'; import { ChildProcess } from 'child_process';
import { makeWaitForNextTask } from '../utils/utils';
export interface BrowserProcess { export interface BrowserProcess {
onclose: ((exitCode: number | null, signal: string | null) => void) | undefined; onclose: ((exitCode: number | null, signal: string | null) => void) | undefined;
@ -87,10 +88,14 @@ export abstract class Browser extends EventEmitter {
this._downloads.delete(uuid); this._downloads.delete(uuid);
} }
_videoStarted(videoId: string, file: string): Video { _videoStarted(videoId: string, file: string, pageOrError: Promise<Page | Error>) {
const video = new Video(file); const video = new Video(file);
this._idToVideo.set(videoId, video); this._idToVideo.set(videoId, video);
return video; pageOrError.then(pageOrError => {
// Emit the event in another task to ensure that newPage response is handled before.
if (pageOrError instanceof Page)
makeWaitForNextTask()(() => pageOrError.emit(Page.Events.VideoStarted, video));
});
} }
_videoFinished(videoId: string) { _videoFinished(videoId: string) {

View file

@ -762,11 +762,7 @@ class FrameSession {
this._screencastState = 'started'; this._screencastState = 'started';
this._videoRecorder = videoRecorder; this._videoRecorder = videoRecorder;
this._screencastId = screencastId; this._screencastId = screencastId;
const video = this._crPage._browserContext._browser._videoStarted(screencastId, options.outputFile); this._crPage._browserContext._browser._videoStarted(screencastId, options.outputFile, this._crPage.pageOrError());
this._crPage.pageOrError().then(pageOrError => {
if (pageOrError instanceof Page)
pageOrError.emit(Page.Events.VideoStarted, video);
}).catch(() => {});
} catch (e) { } catch (e) {
videoRecorder.stop().catch(() => {}); videoRecorder.stop().catch(() => {});
throw e; throw e;

View file

@ -258,11 +258,7 @@ export class FFPage implements PageDelegate {
} }
_onScreencastStarted(event: Protocol.Page.screencastStartedPayload) { _onScreencastStarted(event: Protocol.Page.screencastStartedPayload) {
const video = this._browserContext._browser._videoStarted(event.screencastId, event.file); this._browserContext._browser._videoStarted(event.screencastId, event.file, this.pageOrError());
this.pageOrError().then(pageOrError => {
if (pageOrError instanceof Page)
pageOrError.emit(Page.Events.VideoStarted, video);
}).catch(() => {});
} }
async exposeBinding(binding: PageBinding) { async exposeBinding(binding: PageBinding) {

View file

@ -721,11 +721,7 @@ export class WKPage implements PageDelegate {
width: options.width, width: options.width,
height: options.height, height: options.height,
}) as any; }) as any;
const video = this._browserContext._browser._videoStarted(screencastId, options.outputFile); this._browserContext._browser._videoStarted(screencastId, options.outputFile, this.pageOrError());
this.pageOrError().then(pageOrError => {
if (pageOrError instanceof Page)
pageOrError.emit(Page.Events.VideoStarted, video);
}).catch(() => {});
} catch (e) { } catch (e) {
this._recordingVideoFile = null; this._recordingVideoFile = null;
throw e; throw e;

View file

@ -281,6 +281,14 @@ describe('screencast', suite => {
await browser.close(); await browser.close();
}); });
it('should fire striclty after context.newPage', async ({browser, tmpDir}) => {
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});
const page = await context.newPage();
// Should not hang.
await page.waitForEvent('_videostarted');
await context.close();
});
it('should fire start event for popups', async ({browserType, tmpDir, server}) => { it('should fire start event for popups', async ({browserType, tmpDir, server}) => {
const browser = await browserType.launch({_videosPath: tmpDir}); const browser = await browserType.launch({_videosPath: tmpDir});
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}}); const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});