mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-15 14:11:50 +03:00
chore: remove ExtendedEventEmitter and inline waitForEvent (#2529)
This commit is contained in:
parent
8ee19d53e7
commit
1bb33650b0
@ -21,12 +21,13 @@ import { Page, PageBinding } from './page';
|
||||
import { TimeoutSettings } from './timeoutSettings';
|
||||
import * as types from './types';
|
||||
import { Events } from './events';
|
||||
import { ExtendedEventEmitter } from './extendedEventEmitter';
|
||||
import { Download } from './download';
|
||||
import { BrowserBase } from './browser';
|
||||
import { InnerLogger, Logger } from './logger';
|
||||
import { FunctionWithSource } from './frames';
|
||||
import * as debugSupport from './debug/debugSupport';
|
||||
import { EventEmitter } from 'events';
|
||||
import { ProgressController } from './progress';
|
||||
|
||||
type CommonContextOptions = {
|
||||
viewport?: types.Size | null,
|
||||
@ -76,13 +77,13 @@ export interface BrowserContext {
|
||||
close(): Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class BrowserContextBase extends ExtendedEventEmitter implements BrowserContext {
|
||||
export abstract class BrowserContextBase extends EventEmitter implements BrowserContext {
|
||||
readonly _timeoutSettings = new TimeoutSettings();
|
||||
readonly _pageBindings = new Map<string, PageBinding>();
|
||||
readonly _options: BrowserContextOptions;
|
||||
_routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
||||
_closed = false;
|
||||
private readonly _closePromise: Promise<Error>;
|
||||
readonly _closePromise: Promise<Error>;
|
||||
private _closePromiseFulfill: ((error: Error) => void) | undefined;
|
||||
readonly _permissions = new Map<string, string[]>();
|
||||
readonly _downloads = new Set<Download>();
|
||||
@ -101,16 +102,12 @@ export abstract class BrowserContextBase extends ExtendedEventEmitter implements
|
||||
await debugSupport.installConsoleHelpers(this);
|
||||
}
|
||||
|
||||
protected _abortPromiseForEvent(event: string) {
|
||||
return event === Events.BrowserContext.Close ? super._abortPromiseForEvent(event) : this._closePromise;
|
||||
}
|
||||
|
||||
protected _getLogger(): InnerLogger {
|
||||
return this._logger;
|
||||
}
|
||||
|
||||
protected _getTimeoutSettings(): TimeoutSettings {
|
||||
return this._timeoutSettings;
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._logger, this._timeoutSettings.timeout(options));
|
||||
if (event !== Events.BrowserContext.Close)
|
||||
this._closePromise.then(error => progressController.abort(error));
|
||||
return progressController.run(progress => helper.waitForEvent(progress, this, event, options.predicate));
|
||||
}
|
||||
|
||||
_browserClosed() {
|
||||
|
@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { helper, RegisteredListener } from './helper';
|
||||
import { ProgressController } from './progress';
|
||||
import { InnerLogger } from './logger';
|
||||
import { TimeoutSettings } from './timeoutSettings';
|
||||
|
||||
export abstract class ExtendedEventEmitter extends EventEmitter {
|
||||
protected _abortPromiseForEvent(event: string) {
|
||||
return new Promise<Error>(() => void 0);
|
||||
}
|
||||
protected abstract _getLogger(): InnerLogger;
|
||||
protected abstract _getTimeoutSettings(): TimeoutSettings;
|
||||
|
||||
async waitForEvent(event: string, optionsOrPredicate: Function | { predicate?: Function, timeout?: number } = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const { predicate = () => true } = options;
|
||||
|
||||
const progressController = new ProgressController(this._getLogger(), this._getTimeoutSettings().timeout(options));
|
||||
this._abortPromiseForEvent(event).then(error => progressController.abort(error));
|
||||
|
||||
return progressController.run(async progress => {
|
||||
const listeners: RegisteredListener[] = [];
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
listeners.push(helper.addEventListener(this, event, eventArg => {
|
||||
try {
|
||||
if (!predicate(eventArg))
|
||||
return;
|
||||
resolve(eventArg);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}));
|
||||
});
|
||||
progress.cleanupWhenAborted(() => helper.removeEventListeners(listeners));
|
||||
|
||||
const result = await promise;
|
||||
helper.removeEventListeners(listeners);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
@ -21,6 +21,8 @@ import * as fs from 'fs';
|
||||
import * as removeFolder from 'rimraf';
|
||||
import * as util from 'util';
|
||||
import * as types from './types';
|
||||
import { Progress } from './progress';
|
||||
|
||||
const removeFolderAsync = util.promisify(removeFolder);
|
||||
|
||||
export type RegisteredListener = {
|
||||
@ -278,6 +280,25 @@ class Helper {
|
||||
return removeFolderAsync(dir).catch((err: Error) => console.error(err));
|
||||
}));
|
||||
}
|
||||
|
||||
static async waitForEvent(progress: Progress, emitter: EventEmitter, event: string, predicate?: Function): Promise<any> {
|
||||
const listeners: RegisteredListener[] = [];
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
listeners.push(helper.addEventListener(emitter, event, eventArg => {
|
||||
try {
|
||||
if (predicate && !predicate(eventArg))
|
||||
return;
|
||||
resolve(eventArg);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}));
|
||||
});
|
||||
progress.cleanupWhenAborted(() => helper.removeEventListeners(listeners));
|
||||
const result = await promise;
|
||||
helper.removeEventListeners(listeners);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export function assert(value: any, message?: string): asserts value {
|
||||
|
23
src/page.ts
23
src/page.ts
@ -28,10 +28,10 @@ import { Events } from './events';
|
||||
import { BrowserContext, BrowserContextBase } from './browserContext';
|
||||
import { ConsoleMessage, ConsoleMessageLocation } from './console';
|
||||
import * as accessibility from './accessibility';
|
||||
import { ExtendedEventEmitter } from './extendedEventEmitter';
|
||||
import { EventEmitter } from 'events';
|
||||
import { FileChooser } from './fileChooser';
|
||||
import { logError, InnerLogger } from './logger';
|
||||
import { ProgressController } from './progress';
|
||||
|
||||
export interface PageDelegate {
|
||||
readonly rawMouse: input.RawMouse;
|
||||
@ -88,7 +88,7 @@ type PageState = {
|
||||
extraHTTPHeaders: network.Headers | null;
|
||||
};
|
||||
|
||||
export class Page extends ExtendedEventEmitter {
|
||||
export class Page extends EventEmitter {
|
||||
private _closed = false;
|
||||
private _closedCallback: () => void;
|
||||
private _closedPromise: Promise<void>;
|
||||
@ -138,18 +138,6 @@ export class Page extends ExtendedEventEmitter {
|
||||
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
||||
}
|
||||
|
||||
protected _abortPromiseForEvent(event: string) {
|
||||
return this._disconnectedPromise;
|
||||
}
|
||||
|
||||
protected _getLogger(): InnerLogger {
|
||||
return this._logger;
|
||||
}
|
||||
|
||||
protected _getTimeoutSettings(): TimeoutSettings {
|
||||
return this._timeoutSettings;
|
||||
}
|
||||
|
||||
_didClose() {
|
||||
assert(!this._closed, 'Page closed twice');
|
||||
this._closed = true;
|
||||
@ -337,6 +325,13 @@ export class Page extends ExtendedEventEmitter {
|
||||
return this.waitForEvent(Events.Page.Response, { predicate, timeout: options.timeout });
|
||||
}
|
||||
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._logger, this._timeoutSettings.timeout(options));
|
||||
this._disconnectedPromise.then(error => progressController.abort(error));
|
||||
return progressController.run(progress => helper.waitForEvent(progress, this, event, options.predicate));
|
||||
}
|
||||
|
||||
async goBack(options?: types.NavigateOptions): Promise<network.Response | null> {
|
||||
const waitPromise = this.waitForNavigation(options);
|
||||
const result = await this._delegate.goBack();
|
||||
|
@ -19,7 +19,6 @@ import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
|
||||
import { CRConnection, CRSession } from '../chromium/crConnection';
|
||||
import { CRExecutionContext } from '../chromium/crExecutionContext';
|
||||
import { Events } from '../events';
|
||||
import { ExtendedEventEmitter } from '../extendedEventEmitter';
|
||||
import * as js from '../javascript';
|
||||
import { InnerLogger, Logger } from '../logger';
|
||||
import { Page } from '../page';
|
||||
@ -30,7 +29,9 @@ import { BrowserServer } from './browserServer';
|
||||
import { launchProcess, waitForLine } from './processLauncher';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
import type {BrowserWindow} from 'electron';
|
||||
import { runAbortableTask } from '../progress';
|
||||
import { runAbortableTask, ProgressController } from '../progress';
|
||||
import { EventEmitter } from 'events';
|
||||
import { helper } from '../helper';
|
||||
|
||||
type ElectronLaunchOptions = {
|
||||
args?: string[],
|
||||
@ -55,7 +56,7 @@ interface ElectronPage extends Page {
|
||||
_browserWindowId: number;
|
||||
}
|
||||
|
||||
export class ElectronApplication extends ExtendedEventEmitter {
|
||||
export class ElectronApplication extends EventEmitter {
|
||||
private _logger: InnerLogger;
|
||||
private _browserContext: CRBrowserContext;
|
||||
private _nodeConnection: CRConnection;
|
||||
@ -128,6 +129,14 @@ export class ElectronApplication extends ExtendedEventEmitter {
|
||||
this._nodeConnection.close();
|
||||
}
|
||||
|
||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||
const options = typeof optionsOrPredicate === 'function' ? { predicate: optionsOrPredicate } : optionsOrPredicate;
|
||||
const progressController = new ProgressController(this._logger, this._timeoutSettings.timeout(options));
|
||||
if (event !== ElectronEvents.ElectronApplication.Close)
|
||||
this._browserContext._closePromise.then(error => progressController.abort(error));
|
||||
return progressController.run(progress => helper.waitForEvent(progress, this, event, options.predicate));
|
||||
}
|
||||
|
||||
async _init() {
|
||||
this._nodeSession.once('Runtime.executionContextCreated', event => {
|
||||
this._nodeExecutionContext = new js.ExecutionContext(new CRExecutionContext(this._nodeSession, event.context));
|
||||
@ -152,14 +161,6 @@ export class ElectronApplication extends ExtendedEventEmitter {
|
||||
async evaluateHandle<R, Arg>(pageFunction: types.FuncOn<any, Arg, R>, arg: Arg): Promise<types.SmartHandle<R>> {
|
||||
return this._nodeElectronHandle!.evaluateHandle(pageFunction, arg);
|
||||
}
|
||||
|
||||
protected _getLogger(): InnerLogger {
|
||||
return this._logger;
|
||||
}
|
||||
|
||||
protected _getTimeoutSettings(): TimeoutSettings {
|
||||
return this._timeoutSettings;
|
||||
}
|
||||
}
|
||||
|
||||
export class Electron {
|
||||
|
@ -185,4 +185,6 @@ export type ProxySettings = {
|
||||
bypass?: string,
|
||||
username?: string,
|
||||
password?: string
|
||||
}
|
||||
};
|
||||
|
||||
export type WaitForEventOptions = Function | { predicate?: Function, timeout?: number };
|
||||
|
Loading…
Reference in New Issue
Block a user