chore(rpc): clear the page test spec (#2736)
This commit is contained in:
parent
aad6301aca
commit
db12ddebb3
|
|
@ -70,12 +70,15 @@ export interface PageChannel extends Channel {
|
||||||
on(event: 'bindingCall', callback: (params: BindingCallChannel) => void): this;
|
on(event: 'bindingCall', callback: (params: BindingCallChannel) => void): this;
|
||||||
on(event: 'close', callback: () => void): this;
|
on(event: 'close', callback: () => void): this;
|
||||||
on(event: 'console', callback: (params: ConsoleMessageChannel) => void): this;
|
on(event: 'console', callback: (params: ConsoleMessageChannel) => void): this;
|
||||||
|
on(event: 'crash', callback: () => void): this;
|
||||||
on(event: 'dialog', callback: (params: DialogChannel) => void): this;
|
on(event: 'dialog', callback: (params: DialogChannel) => void): this;
|
||||||
on(event: 'download', callback: (params: DownloadChannel) => void): this;
|
on(event: 'download', callback: (params: DownloadChannel) => void): this;
|
||||||
|
on(event: 'domcontentloaded', callback: () => void): this;
|
||||||
on(event: 'frameAttached', callback: (params: FrameChannel) => void): this;
|
on(event: 'frameAttached', callback: (params: FrameChannel) => void): this;
|
||||||
on(event: 'frameDetached', callback: (params: FrameChannel) => void): this;
|
on(event: 'frameDetached', callback: (params: FrameChannel) => void): this;
|
||||||
on(event: 'frameNavigated', callback: (params: { frame: FrameChannel, url: string, name: string }) => void): this;
|
on(event: 'frameNavigated', callback: (params: { frame: FrameChannel, url: string, name: string }) => void): this;
|
||||||
on(event: 'frameNavigated', callback: (params: { frame: FrameChannel, url: string, name: string }) => void): this;
|
on(event: 'frameNavigated', callback: (params: { frame: FrameChannel, url: string, name: string }) => void): this;
|
||||||
|
on(event: 'load', callback: () => void): this;
|
||||||
on(event: 'pageError', callback: (params: { error: types.Error }) => void): this;
|
on(event: 'pageError', callback: (params: { error: types.Error }) => void): this;
|
||||||
on(event: 'popup', callback: (params: PageChannel) => void): this;
|
on(event: 'popup', callback: (params: PageChannel) => void): this;
|
||||||
on(event: 'request', callback: (params: RequestChannel) => void): this;
|
on(event: 'request', callback: (params: RequestChannel) => void): this;
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,15 @@ import { helper } from '../../helper';
|
||||||
import { Browser } from './browser';
|
import { Browser } from './browser';
|
||||||
import { Connection } from '../connection';
|
import { Connection } from '../connection';
|
||||||
import { Events } from '../../events';
|
import { Events } from '../../events';
|
||||||
|
import { TimeoutSettings } from '../../timeoutSettings';
|
||||||
|
|
||||||
export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> {
|
export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> {
|
||||||
_pages = new Set<Page>();
|
_pages = new Set<Page>();
|
||||||
private _routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
private _routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
||||||
_browser: Browser | undefined;
|
_browser: Browser | undefined;
|
||||||
readonly _bindings = new Map<string, frames.FunctionWithSource>();
|
readonly _bindings = new Map<string, frames.FunctionWithSource>();
|
||||||
|
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
||||||
|
_timeoutSettings = new TimeoutSettings();
|
||||||
|
|
||||||
static from(context: BrowserContextChannel): BrowserContext {
|
static from(context: BrowserContextChannel): BrowserContext {
|
||||||
return context._object;
|
return context._object;
|
||||||
|
|
@ -45,13 +48,13 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
||||||
initializer.pages.map(p => {
|
initializer.pages.map(p => {
|
||||||
const page = Page.from(p);
|
const page = Page.from(p);
|
||||||
this._pages.add(page);
|
this._pages.add(page);
|
||||||
page._browserContext = this;
|
page._setBrowserContext(this);
|
||||||
});
|
});
|
||||||
channel.on('page', page => this._onPage(Page.from(page)));
|
channel.on('page', page => this._onPage(Page.from(page)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onPage(page: Page): void {
|
private _onPage(page: Page): void {
|
||||||
page._browserContext = this;
|
page._setBrowserContext(this);
|
||||||
this._pages.add(page);
|
this._pages.add(page);
|
||||||
this.emit(Events.BrowserContext.Page, page);
|
this.emit(Events.BrowserContext.Page, page);
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +81,7 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefaultTimeout(timeout: number) {
|
setDefaultTimeout(timeout: number) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
this._channel.setDefaultTimeoutNoReply({ timeout });
|
this._channel.setDefaultTimeoutNoReply({ timeout });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,13 +166,27 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForEvent(event: string, optionsOrPredicate?: Function | (types.TimeoutOptions & { predicate?: Function })): Promise<any> {
|
async waitForEvent(event: string, optionsOrPredicate?: Function | (types.TimeoutOptions & { predicate?: Function })): Promise<any> {
|
||||||
return waitForEvent(this, event, optionsOrPredicate);
|
const hasTimeout = optionsOrPredicate && !(optionsOrPredicate instanceof Function);
|
||||||
|
let reject: () => void;
|
||||||
|
const result = await Promise.race([
|
||||||
|
waitForEvent(this, event, optionsOrPredicate, this._timeoutSettings.timeout(hasTimeout ? optionsOrPredicate as any : {})),
|
||||||
|
new Promise((f, r) => { reject = r; this._pendingWaitForEvents.set(reject, event); })
|
||||||
|
]);
|
||||||
|
this._pendingWaitForEvents.delete(reject!);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(): Promise<void> {
|
async close(): Promise<void> {
|
||||||
await this._channel.close();
|
await this._channel.close();
|
||||||
if (this._browser)
|
if (this._browser)
|
||||||
this._browser._contexts.delete(this);
|
this._browser._contexts.delete(this);
|
||||||
|
|
||||||
|
for (const [listener, event] of this._pendingWaitForEvents) {
|
||||||
|
if (event === Events.Page.Close)
|
||||||
|
continue;
|
||||||
|
listener(new Error('Context closed'));
|
||||||
|
}
|
||||||
|
this._pendingWaitForEvents.clear();
|
||||||
this.emit(Events.BrowserContext.Close);
|
this.emit(Events.BrowserContext.Close);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,13 @@ import { Accessibility } from './accessibility';
|
||||||
import { ConsoleMessage } from './consoleMessage';
|
import { ConsoleMessage } from './consoleMessage';
|
||||||
import { Dialog } from './dialog';
|
import { Dialog } from './dialog';
|
||||||
import { Download } from './download';
|
import { Download } from './download';
|
||||||
|
import { TimeoutError } from '../../errors';
|
||||||
|
import { TimeoutSettings } from '../../timeoutSettings';
|
||||||
|
|
||||||
export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
readonly pdf: ((options?: types.PDFOptions) => Promise<Buffer>) | undefined;
|
readonly pdf: ((options?: types.PDFOptions) => Promise<Buffer>) | undefined;
|
||||||
|
|
||||||
_browserContext: BrowserContext | undefined;
|
private _browserContext: BrowserContext | undefined;
|
||||||
_ownedContext: BrowserContext | undefined;
|
_ownedContext: BrowserContext | undefined;
|
||||||
|
|
||||||
private _mainFrame: Frame;
|
private _mainFrame: Frame;
|
||||||
|
|
@ -50,6 +52,8 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
readonly keyboard: Keyboard;
|
readonly keyboard: Keyboard;
|
||||||
readonly mouse: Mouse;
|
readonly mouse: Mouse;
|
||||||
readonly _bindings = new Map<string, FunctionWithSource>();
|
readonly _bindings = new Map<string, FunctionWithSource>();
|
||||||
|
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
||||||
|
private _timeoutSettings = new TimeoutSettings();
|
||||||
|
|
||||||
static from(page: PageChannel): Page {
|
static from(page: PageChannel): Page {
|
||||||
return page._object;
|
return page._object;
|
||||||
|
|
@ -73,11 +77,14 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
this._channel.on('bindingCall', bindingCall => this._onBinding(BindingCall.from(bindingCall)));
|
this._channel.on('bindingCall', bindingCall => this._onBinding(BindingCall.from(bindingCall)));
|
||||||
this._channel.on('close', () => this._onClose());
|
this._channel.on('close', () => this._onClose());
|
||||||
this._channel.on('console', message => this.emit(Events.Page.Console, ConsoleMessage.from(message)));
|
this._channel.on('console', message => this.emit(Events.Page.Console, ConsoleMessage.from(message)));
|
||||||
|
this._channel.on('crash', () => this._onCrash());
|
||||||
this._channel.on('dialog', dialog => this.emit(Events.Page.Dialog, Dialog.from(dialog)));
|
this._channel.on('dialog', dialog => this.emit(Events.Page.Dialog, Dialog.from(dialog)));
|
||||||
|
this._channel.on('domcontentloaded', () => this.emit(Events.Page.DOMContentLoaded));
|
||||||
this._channel.on('download', download => this.emit(Events.Page.Download, Download.from(download)));
|
this._channel.on('download', download => this.emit(Events.Page.Download, Download.from(download)));
|
||||||
this._channel.on('frameAttached', frame => this._onFrameAttached(Frame.from(frame)));
|
this._channel.on('frameAttached', frame => this._onFrameAttached(Frame.from(frame)));
|
||||||
this._channel.on('frameDetached', frame => this._onFrameDetached(Frame.from(frame)));
|
this._channel.on('frameDetached', frame => this._onFrameDetached(Frame.from(frame)));
|
||||||
this._channel.on('frameNavigated', ({ frame, url, name }) => this._onFrameNavigated(Frame.from(frame), url, name));
|
this._channel.on('frameNavigated', ({ frame, url, name }) => this._onFrameNavigated(Frame.from(frame), url, name));
|
||||||
|
this._channel.on('load', () => this.emit(Events.Page.Load));
|
||||||
this._channel.on('pageError', ({ error }) => this.emit(Events.Page.PageError, parseError(error)));
|
this._channel.on('pageError', ({ error }) => this.emit(Events.Page.PageError, parseError(error)));
|
||||||
this._channel.on('popup', popup => this.emit(Events.Page.Popup, Page.from(popup)));
|
this._channel.on('popup', popup => this.emit(Events.Page.Popup, Page.from(popup)));
|
||||||
this._channel.on('request', request => this.emit(Events.Page.Request, Request.from(request)));
|
this._channel.on('request', request => this.emit(Events.Page.Request, Request.from(request)));
|
||||||
|
|
@ -87,6 +94,11 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
this._channel.on('route', ({ route, request }) => this._onRoute(Route.from(route), Request.from(request)));
|
this._channel.on('route', ({ route, request }) => this._onRoute(Route.from(route), Request.from(request)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setBrowserContext(context: BrowserContext) {
|
||||||
|
this._browserContext = context;
|
||||||
|
this._timeoutSettings = new TimeoutSettings(context._timeoutSettings);
|
||||||
|
}
|
||||||
|
|
||||||
private _onRequestFailed(request: Request, failureText: string | null) {
|
private _onRequestFailed(request: Request, failureText: string | null) {
|
||||||
request._failureText = failureText;
|
request._failureText = failureText;
|
||||||
this.emit(Events.Page.RequestFailed, request);
|
this.emit(Events.Page.RequestFailed, request);
|
||||||
|
|
@ -132,10 +144,28 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onClose() {
|
private _onClose() {
|
||||||
|
this._closed = true;
|
||||||
this._browserContext!._pages.delete(this);
|
this._browserContext!._pages.delete(this);
|
||||||
|
this._rejectPendingOperations(false);
|
||||||
this.emit(Events.Page.Close);
|
this.emit(Events.Page.Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _onCrash() {
|
||||||
|
this._rejectPendingOperations(true);
|
||||||
|
this.emit(Events.Page.Crash);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _rejectPendingOperations(isCrash: boolean) {
|
||||||
|
for (const [listener, event] of this._pendingWaitForEvents) {
|
||||||
|
if (event === Events.Page.Close && !isCrash)
|
||||||
|
continue;
|
||||||
|
if (event === Events.Page.Crash && isCrash)
|
||||||
|
continue;
|
||||||
|
listener(new Error(isCrash ? 'Page crashed' : 'Page closed'));
|
||||||
|
}
|
||||||
|
this._pendingWaitForEvents.clear();
|
||||||
|
}
|
||||||
|
|
||||||
context(): BrowserContext {
|
context(): BrowserContext {
|
||||||
return this._browserContext!;
|
return this._browserContext!;
|
||||||
}
|
}
|
||||||
|
|
@ -168,6 +198,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
setDefaultTimeout(timeout: number) {
|
setDefaultTimeout(timeout: number) {
|
||||||
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
this._channel.setDefaultTimeoutNoReply({ timeout });
|
this._channel.setDefaultTimeoutNoReply({ timeout });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,7 +311,13 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
async waitForEvent(event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
||||||
return waitForEvent(this, event, optionsOrPredicate);
|
let reject: () => void;
|
||||||
|
const result = await Promise.race([
|
||||||
|
waitForEvent(this, event, optionsOrPredicate, this._timeoutSettings.timeout(optionsOrPredicate instanceof Function ? {} : optionsOrPredicate)),
|
||||||
|
new Promise((f, r) => { reject = r; this._pendingWaitForEvents.set(reject, event); })
|
||||||
|
]);
|
||||||
|
this._pendingWaitForEvents.delete(reject!);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async goBack(options?: types.NavigateOptions): Promise<Response | null> {
|
async goBack(options?: types.NavigateOptions): Promise<Response | null> {
|
||||||
|
|
@ -477,7 +514,7 @@ export class BindingCall extends ChannelOwner<BindingCallChannel, BindingCallIni
|
||||||
try {
|
try {
|
||||||
const frame = Frame.from(this._initializer.frame);
|
const frame = Frame.from(this._initializer.frame);
|
||||||
const source = {
|
const source = {
|
||||||
context: frame._page!._browserContext!,
|
context: frame._page!.context(),
|
||||||
page: frame._page!,
|
page: frame._page!,
|
||||||
frame
|
frame
|
||||||
};
|
};
|
||||||
|
|
@ -488,22 +525,30 @@ export class BindingCall extends ChannelOwner<BindingCallChannel, BindingCallIni
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function waitForEvent(emitter: EventEmitter, event: string, optionsOrPredicate: types.WaitForEventOptions = {}): Promise<any> {
|
export async function waitForEvent(emitter: EventEmitter, event: string, optionsOrPredicate: types.WaitForEventOptions = {}, defaultTimeout: number): Promise<any> {
|
||||||
// TODO: support timeout
|
|
||||||
let predicate: Function | undefined;
|
let predicate: Function | undefined;
|
||||||
if (typeof optionsOrPredicate === 'function')
|
let timeout = defaultTimeout;
|
||||||
|
if (typeof optionsOrPredicate === 'function') {
|
||||||
predicate = optionsOrPredicate;
|
predicate = optionsOrPredicate;
|
||||||
else if (optionsOrPredicate.predicate)
|
} else if (optionsOrPredicate.predicate) {
|
||||||
|
if (optionsOrPredicate.timeout !== undefined)
|
||||||
|
timeout = optionsOrPredicate.timeout;
|
||||||
predicate = optionsOrPredicate.predicate;
|
predicate = optionsOrPredicate.predicate;
|
||||||
|
}
|
||||||
let callback: (a: any) => void;
|
let callback: (a: any) => void;
|
||||||
const result = new Promise(f => callback = f);
|
const result = new Promise(f => callback = f);
|
||||||
const listener = helper.addEventListener(emitter, event, param => {
|
const listener = helper.addEventListener(emitter, event, param => {
|
||||||
// TODO: do not detect channel by guid.
|
// TODO: do not detect channel by guid.
|
||||||
const object = param._guid ? (param as Channel)._object : param;
|
const object = param && param._guid ? (param as Channel)._object : param;
|
||||||
if (predicate && !predicate(object))
|
if (predicate && !predicate(object))
|
||||||
return;
|
return;
|
||||||
callback(object);
|
callback(object);
|
||||||
helper.removeEventListeners([listener]);
|
helper.removeEventListeners([listener]);
|
||||||
});
|
});
|
||||||
return result;
|
if (timeout === 0)
|
||||||
|
return result;
|
||||||
|
return Promise.race([
|
||||||
|
result,
|
||||||
|
new Promise((f, r) => setTimeout(() => r(new TimeoutError('Timeout while waiting for event')), timeout))
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,6 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, Browser
|
||||||
}
|
}
|
||||||
|
|
||||||
async close(): Promise<void> {
|
async close(): Promise<void> {
|
||||||
this._context.close();
|
await this._context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,11 +52,14 @@ export class PageDispatcher extends Dispatcher<Page, PageInitializer> implements
|
||||||
this._page = page;
|
this._page = page;
|
||||||
page.on(Events.Page.Close, () => this._dispatchEvent('close'));
|
page.on(Events.Page.Close, () => this._dispatchEvent('close'));
|
||||||
page.on(Events.Page.Console, message => this._dispatchEvent('console', ConsoleMessageDispatcher.from(this._scope, message)));
|
page.on(Events.Page.Console, message => this._dispatchEvent('console', ConsoleMessageDispatcher.from(this._scope, message)));
|
||||||
|
page.on(Events.Page.Crash, () => this._dispatchEvent('crash'));
|
||||||
|
page.on(Events.Page.DOMContentLoaded, () => this._dispatchEvent('domcontentloaded'));
|
||||||
page.on(Events.Page.Dialog, dialog => this._dispatchEvent('dialog', DialogDispatcher.from(this._scope, dialog)));
|
page.on(Events.Page.Dialog, dialog => this._dispatchEvent('dialog', DialogDispatcher.from(this._scope, dialog)));
|
||||||
page.on(Events.Page.Download, dialog => this._dispatchEvent('download', DownloadDispatcher.from(this._scope, dialog)));
|
page.on(Events.Page.Download, dialog => this._dispatchEvent('download', DownloadDispatcher.from(this._scope, dialog)));
|
||||||
page.on(Events.Page.FrameAttached, frame => this._onFrameAttached(frame));
|
page.on(Events.Page.FrameAttached, frame => this._onFrameAttached(frame));
|
||||||
page.on(Events.Page.FrameDetached, frame => this._onFrameDetached(frame));
|
page.on(Events.Page.FrameDetached, frame => this._onFrameDetached(frame));
|
||||||
page.on(Events.Page.FrameNavigated, frame => this._onFrameNavigated(frame));
|
page.on(Events.Page.FrameNavigated, frame => this._onFrameNavigated(frame));
|
||||||
|
page.on(Events.Page.Load, () => this._dispatchEvent('load'));
|
||||||
page.on(Events.Page.PageError, error => this._dispatchEvent('pageError', { error: serializeError(error) }));
|
page.on(Events.Page.PageError, error => this._dispatchEvent('pageError', { error: serializeError(error) }));
|
||||||
page.on(Events.Page.Popup, page => this._dispatchEvent('popup', PageDispatcher.from(this._scope, page)));
|
page.on(Events.Page.Popup, page => this._dispatchEvent('popup', PageDispatcher.from(this._scope, page)));
|
||||||
page.on(Events.Page.Request, request => this._dispatchEvent('request', RequestDispatcher.from(this._scope, request)));
|
page.on(Events.Page.Request, request => this._dispatchEvent('request', RequestDispatcher.from(this._scope, request)));
|
||||||
|
|
|
||||||
26
test/test.js
26
test/test.js
|
|
@ -95,22 +95,6 @@ function collect(browserNames) {
|
||||||
|
|
||||||
global.playwright = playwright;
|
global.playwright = playwright;
|
||||||
|
|
||||||
// Channel substitute
|
|
||||||
let connection;
|
|
||||||
let dispatcherScope;
|
|
||||||
if (process.env.PWCHANNEL) {
|
|
||||||
dispatcherScope = new DispatcherScope();
|
|
||||||
connection = new Connection();
|
|
||||||
dispatcherScope.sendMessageToClientTransport = async message => {
|
|
||||||
setImmediate(() => connection.dispatchMessageFromServer(message));
|
|
||||||
};
|
|
||||||
connection.sendMessageToServerTransport = async message => {
|
|
||||||
const result = await dispatcherScope.dispatchMessageFromClient(message);
|
|
||||||
await new Promise(f => setImmediate(f));
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const browserName of browserNames) {
|
for (const browserName of browserNames) {
|
||||||
const browserType = playwright[browserName];
|
const browserType = playwright[browserName];
|
||||||
|
|
||||||
|
|
@ -119,6 +103,16 @@ function collect(browserNames) {
|
||||||
// Channel substitute
|
// Channel substitute
|
||||||
let overridenBrowserType = browserType;
|
let overridenBrowserType = browserType;
|
||||||
if (process.env.PWCHANNEL) {
|
if (process.env.PWCHANNEL) {
|
||||||
|
const dispatcherScope = new DispatcherScope();
|
||||||
|
const connection = new Connection();
|
||||||
|
dispatcherScope.sendMessageToClientTransport = async message => {
|
||||||
|
setImmediate(() => connection.dispatchMessageFromServer(message));
|
||||||
|
};
|
||||||
|
connection.sendMessageToServerTransport = async message => {
|
||||||
|
const result = await dispatcherScope.dispatchMessageFromClient(message);
|
||||||
|
await new Promise(f => setImmediate(f));
|
||||||
|
return result;
|
||||||
|
};
|
||||||
BrowserTypeDispatcher.from(dispatcherScope, browserType);
|
BrowserTypeDispatcher.from(dispatcherScope, browserType);
|
||||||
overridenBrowserType = await connection.waitForObjectWithKnownName(browserType.name());
|
overridenBrowserType = await connection.waitForObjectWithKnownName(browserType.name());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue