mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
browser(firefox): start screencast in existing pages upon setScreencastOptions (#4045)
This makes it work in persistent context. To achieve this, we have to move screencast logic into PageTarget and make PageHandler listen to an event.
This commit is contained in:
parent
1f16ce2632
commit
133de10a47
@ -1,2 +1,2 @@
|
||||
1179
|
||||
Changed: lushnikov@chromium.org Fri Oct 2 03:14:15 PDT 2020
|
||||
1180
|
||||
Changed: dgozman@gmail.com Fri Oct 2 09:36:06 PDT 2020
|
||||
|
||||
@ -10,6 +10,7 @@ const {Preferences} = ChromeUtils.import("resource://gre/modules/Preferences.jsm
|
||||
const {ContextualIdentityService} = ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm");
|
||||
const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
|
||||
const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const helper = new Helper();
|
||||
|
||||
@ -350,6 +351,7 @@ class PageTarget {
|
||||
this._openerId = opener ? opener.id() : undefined;
|
||||
this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, this._linkedBrowser.messageManager);
|
||||
this._channelIds = new Set();
|
||||
this._screencastInfo = undefined;
|
||||
|
||||
const navigationListener = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
|
||||
@ -454,6 +456,50 @@ class PageTarget {
|
||||
return await this._channel.connect('').send('hasFailedToOverrideTimezone').catch(e => true);
|
||||
}
|
||||
|
||||
async startVideoRecording({width, height, scale, dir}) {
|
||||
// On Mac the window may not yet be visible when TargetCreated and its
|
||||
// NSWindow.windowNumber may be -1, so we wait until the window is known
|
||||
// to be initialized and visible.
|
||||
await this.windowReady();
|
||||
const file = OS.Path.join(dir, helper.generateId() + '.webm');
|
||||
if (width < 10 || width > 10000 || height < 10 || height > 10000)
|
||||
throw new Error("Invalid size");
|
||||
if (scale && (scale <= 0 || scale > 1))
|
||||
throw new Error("Unsupported scale");
|
||||
|
||||
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||
const docShell = this._gBrowser.ownerGlobal.docShell;
|
||||
// Exclude address bar and navigation control from the video.
|
||||
const rect = this.linkedBrowser().getBoundingClientRect();
|
||||
const devicePixelRatio = this._window.devicePixelRatio;
|
||||
const videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, devicePixelRatio * rect.top);
|
||||
this._screencastInfo = { videoSessionId, file };
|
||||
this.emit('screencastStarted');
|
||||
}
|
||||
|
||||
async stopVideoRecording() {
|
||||
if (!this._screencastInfo)
|
||||
throw new Error('No video recording in progress');
|
||||
const screencastInfo = this._screencastInfo;
|
||||
this._screencastInfo = undefined;
|
||||
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||
const result = new Promise(resolve =>
|
||||
Services.obs.addObserver(function onStopped(subject, topic, data) {
|
||||
if (screencastInfo.videoSessionId != data)
|
||||
return;
|
||||
|
||||
Services.obs.removeObserver(onStopped, 'juggler-screencast-stopped');
|
||||
resolve();
|
||||
}, 'juggler-screencast-stopped')
|
||||
);
|
||||
screencast.stopVideoRecording(screencastInfo.videoSessionId);
|
||||
return result;
|
||||
}
|
||||
|
||||
screencastInfo() {
|
||||
return this._screencastInfo;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
this._browserContext.pages.delete(this);
|
||||
@ -673,8 +719,14 @@ class BrowserContext {
|
||||
return result;
|
||||
}
|
||||
|
||||
setScreencastOptions(options) {
|
||||
async setScreencastOptions(options) {
|
||||
this.screencastOptions = options;
|
||||
if (!options)
|
||||
return;
|
||||
const promises = [];
|
||||
for (const page of this.pages)
|
||||
promises.push(page.startVideoRecording(options));
|
||||
await Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
|
||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@ -91,7 +90,6 @@ class PageHandler {
|
||||
this._dialogs = new Map();
|
||||
|
||||
this._enabled = false;
|
||||
this._videoSessionId = -1;
|
||||
}
|
||||
|
||||
_onWorkerCreated({workerId, frameId, url}) {
|
||||
@ -132,24 +130,23 @@ class PageHandler {
|
||||
helper.on(this._pageTarget, 'crashed', () => {
|
||||
this._session.emitEvent('Page.crashed', {});
|
||||
}),
|
||||
helper.on(this._pageTarget, 'screencastStarted', () => {
|
||||
const info = this._pageTarget.screencastInfo();
|
||||
this._session.emitEvent('Page.screencastStarted', { screencastId: '' + info.videoSessionId, file: info.file });
|
||||
}),
|
||||
]);
|
||||
|
||||
const options = this._pageTarget.browserContext().screencastOptions;
|
||||
if (options) {
|
||||
const file = OS.Path.join(options.dir, helper.generateId() + '.webm');
|
||||
// On Mac the window may not yet be visible when TargetCreated and its
|
||||
// NSWindow.windowNumber may be -1, so we wait until the window is known
|
||||
// to be initialized and visible.
|
||||
await this._pageTarget.windowReady();
|
||||
await this.startVideoRecording(Object.assign({file}, options));
|
||||
}
|
||||
if (options)
|
||||
await this._pageTarget.startVideoRecording(options);
|
||||
}
|
||||
|
||||
async dispose() {
|
||||
this._contentPage.dispose();
|
||||
helper.removeListeners(this._eventListeners);
|
||||
if (this._videoSessionId !== -1)
|
||||
await this.stopVideoRecording().catch(e => dump(`stopVideoRecording failed:\n${e}\n`));
|
||||
|
||||
if (this._pageTarget.screencastInfo())
|
||||
await this._pageTarget.stopVideoRecording().catch(e => dump(`stopVideoRecording failed:\n${e}\n`));
|
||||
}
|
||||
|
||||
async setViewportSize({viewportSize}) {
|
||||
@ -303,38 +300,8 @@ class PageHandler {
|
||||
return await worker.sendMessage(JSON.parse(message));
|
||||
}
|
||||
|
||||
startVideoRecording({file, width, height, scale}) {
|
||||
if (width < 10 || width > 10000 || height < 10 || height > 10000)
|
||||
throw new Error("Invalid size");
|
||||
if (scale && (scale <= 0 || scale > 1))
|
||||
throw new Error("Unsupported scale");
|
||||
|
||||
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||
const docShell = this._pageTarget._gBrowser.ownerGlobal.docShell;
|
||||
// Exclude address bar and navigation control from the video.
|
||||
const rect = this._pageTarget.linkedBrowser().getBoundingClientRect();
|
||||
const devicePixelRatio = this._pageTarget._window.devicePixelRatio;
|
||||
this._videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, devicePixelRatio * rect.top);
|
||||
this._session.emitEvent('Page.screencastStarted', {screencastId: '' + this._videoSessionId, file});
|
||||
}
|
||||
|
||||
async stopVideoRecording() {
|
||||
if (this._videoSessionId === -1)
|
||||
throw new Error('No video recording in progress');
|
||||
const videoSessionId = this._videoSessionId;
|
||||
this._videoSessionId = -1;
|
||||
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||
const result = new Promise(resolve =>
|
||||
Services.obs.addObserver(function onStopped(subject, topic, data) {
|
||||
if (videoSessionId != data)
|
||||
return;
|
||||
|
||||
Services.obs.removeObserver(onStopped, 'juggler-screencast-stopped');
|
||||
resolve();
|
||||
}, 'juggler-screencast-stopped')
|
||||
);
|
||||
screencast.stopVideoRecording(videoSessionId);
|
||||
return result;
|
||||
await this._pageTarget.stopVideoRecording();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user