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 { ProxySettings } from './types';
import { ChildProcess } from 'child_process';
import { makeWaitForNextTask } from '../utils/utils';
export interface BrowserProcess {
onclose: ((exitCode: number | null, signal: string | null) => void) | undefined;
@ -87,10 +88,14 @@ export abstract class Browser extends EventEmitter {
this._downloads.delete(uuid);
}
_videoStarted(videoId: string, file: string): Video {
_videoStarted(videoId: string, file: string, pageOrError: Promise<Page | Error>) {
const video = new Video(file);
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) {

View file

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

View file

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

View file

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

View file

@ -281,6 +281,14 @@ describe('screencast', suite => {
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}) => {
const browser = await browserType.launch({_videosPath: tmpDir});
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});