fix(screencast): properly stop screencast on context closure (#6146)

This commit is contained in:
Yury Semikhatsky 2021-04-08 14:01:05 -07:00 committed by GitHub
parent f7e7ea93e2
commit 53d50f9b72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 8 deletions

View File

@ -93,10 +93,6 @@ export abstract class BrowserContext extends SdkObject {
}
this._closedStatus = 'closed';
this._downloads.clear();
for (const [id, video] of this._browser._idToVideo) {
if (video.context === this)
this._browser._idToVideo.delete(id);
}
this._closePromiseFulfill!(new Error('Context closed'));
this.emit(BrowserContext.Events.Close);
}

View File

@ -157,7 +157,6 @@ export class CRPage implements PageDelegate {
for (const session of this._sessions.values())
session.dispose();
this._page._didClose();
this._mainFrameSession._stopVideoRecording().catch(() => {});
}
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
@ -444,6 +443,10 @@ class FrameSession {
// Note: it is important to start video recorder before sending Page.startScreencast,
// and it is equally important to send Page.startScreencast before sending Runtime.runIfWaitingForDebugger.
await this._createVideoRecorder(screencastId, screencastOptions);
this._crPage.pageOrError().then(p => {
if (p instanceof Error)
this._stopVideoRecording().catch(() => {});
});
}
let lifecycleEventsEnabled: Promise<any>;
@ -876,6 +879,7 @@ class FrameSession {
async _startVideoRecording(options: types.PageScreencastOptions) {
const screencastId = this._screencastId;
assert(screencastId);
this._page.once(Page.Events.Close, () => this._stopVideoRecording().catch(() => {}));
const gotFirstFrame = new Promise(f => this._client.once('Page.screencastFrame', f));
await this._startScreencast(this._videoRecorder, {
format: 'jpeg',
@ -892,11 +896,11 @@ class FrameSession {
async _stopVideoRecording(): Promise<void> {
if (!this._screencastId)
return;
const recorder = this._videoRecorder!;
await this._stopScreencast(recorder);
const screencastId = this._screencastId;
this._videoRecorder = null;
this._screencastId = null;
const recorder = this._videoRecorder!;
this._videoRecorder = null;
await this._stopScreencast(recorder);
await recorder.stop().catch(() => {});
this._crPage._browserContext._browser._videoFinished(screencastId);
}

View File

@ -570,4 +570,25 @@ it.describe('screencast', () => {
expect(videoPlayer.videoWidth).toBe(374);
expect(videoPlayer.videoHeight).toBe(666);
});
it('should throw on browser close', async ({browserType, browserOptions, contextOptions}, testInfo) => {
const size = { width: 320, height: 240 };
const browser = await browserType.launch(browserOptions);
const context = await browser.newContext({
...contextOptions,
recordVideo: {
dir: testInfo.outputPath(''),
size,
},
viewport: size,
});
const page = await context.newPage();
await new Promise(r => setTimeout(r, 1000));
await browser.close();
const file = testInfo.outputPath('saved-video-');
const saveResult = await page.video().saveAs(file).catch(e => e);
expect(saveResult.message).toContain('browser has been closed');
});
});