feat(firefox): support context-level screencast api (#3555)

This commit is contained in:
Yury Semikhatsky 2020-08-20 19:49:30 -07:00 committed by GitHub
parent 7a492831a1
commit 1f0e9db0a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 3 deletions

View file

@ -149,7 +149,7 @@ export abstract class BrowserContext extends EventEmitter {
this._timeoutSettings.setDefaultTimeout(timeout);
}
_enableScreencast(options: types.ContextScreencastOptions) {
async _enableScreencast(options: types.ContextScreencastOptions) {
this._screencastOptions = options;
fs.mkdirSync(path.dirname(options.dir), {recursive: true});
}

View file

@ -323,6 +323,11 @@ export class FFBrowserContext extends BrowserContext {
await this._browser._connection.send('Browser.setRequestInterception', { browserContextId: this._browserContextId || undefined, enabled: !!this._requestInterceptor });
}
async _enableScreencast(options: types.ContextScreencastOptions): Promise<void> {
await super._enableScreencast(options);
await this._browser._connection.send('Browser.setScreencastOptions', Object.assign({}, options, { browserContextId: this._browserContextId || undefined}));
}
async _doClose() {
assert(this._browserContextId);
await this._browser._connection.send('Browser.removeBrowserContext', { browserContextId: this._browserContextId });

View file

@ -32,6 +32,7 @@ import { FFNetworkManager } from './ffNetworkManager';
import { Protocol } from './protocol';
import { selectors } from '../selectors';
import { rewriteErrorMessage } from '../utils/stackTrace';
import { Screencast } from '../browserContext';
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
@ -50,6 +51,7 @@ export class FFPage implements PageDelegate {
private readonly _contextIdToContext: Map<string, dom.FrameExecutionContext>;
private _eventListeners: RegisteredListener[];
private _workers = new Map<string, { frameId: string, session: FFSession }>();
private readonly _idToScreencast = new Map<string, Screencast>();
constructor(session: FFSession, browserContext: FFBrowserContext, opener: FFPage | null) {
this._session = session;
@ -82,6 +84,8 @@ export class FFPage implements PageDelegate {
helper.addEventListener(this._session, 'Page.workerDestroyed', this._onWorkerDestroyed.bind(this)),
helper.addEventListener(this._session, 'Page.dispatchMessageFromWorker', this._onDispatchMessageFromWorker.bind(this)),
helper.addEventListener(this._session, 'Page.crashed', this._onCrashed.bind(this)),
helper.addEventListener(this._session, 'Page.screencastStarted', this._onScreencastStarted.bind(this)),
helper.addEventListener(this._session, 'Page.screencastStopped', this._onScreencastStopped.bind(this)),
];
this._pagePromise = new Promise(f => this._pageCallback = f);
session.once(FFSessionEvents.Disconnected, () => this._page._didDisconnect());
@ -255,6 +259,20 @@ export class FFPage implements PageDelegate {
this._page._didCrash();
}
_onScreencastStarted(event: Protocol.Page.screencastStartedPayload) {
const screencast = new Screencast(event.file, this._page);
this._idToScreencast.set(event.uid, screencast);
this._browserContext.emit(Events.BrowserContext.ScreencastStarted, screencast);
}
_onScreencastStopped(event: Protocol.Page.screencastStoppedPayload) {
const screencast = this._idToScreencast.get(event.uid);
if (!screencast)
return;
this._idToScreencast.delete(event.uid);
this._browserContext.emit(Events.BrowserContext.ScreencastStopped, screencast);
}
async exposeBinding(binding: PageBinding) {
await this._session.send('Page.addBinding', { name: binding.name, script: binding.source });
}

View file

@ -257,12 +257,12 @@ it.fail(options.CHROMIUM || (options.WEBKIT && WIN))('should capture css transfo
}
});
it.fail(options.CHROMIUM || options.FIREFOX)('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => {
it.fail(options.CHROMIUM)('should fire start/stop events when page created/closed', async({browser, tmpDir, server, toImpl}) => {
if (!toImpl)
return;
// Use server side of the context. All the code below also uses server side APIs.
const context = toImpl(await browser.newContext());
context._enableScreencast({width: 640, height: 480, dir: tmpDir});
await context._enableScreencast({width: 640, height: 480, dir: tmpDir});
expect(context._screencastOptions).toBeTruthy();
const [startEvent, newPage] = await Promise.all([