feat(rpc): log api calls into LoggerSink (#2904)
This commit is contained in:
parent
c63b706aac
commit
6674458496
|
|
@ -21,6 +21,7 @@ import { Page } from './page';
|
|||
import { ChannelOwner } from './channelOwner';
|
||||
import { Events } from '../../events';
|
||||
import { CDPSession } from './cdpSession';
|
||||
import { LoggerSink } from '../../loggerSink';
|
||||
|
||||
export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||
readonly _contexts = new Set<BrowserContext>();
|
||||
|
|
@ -36,8 +37,8 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
|||
return browser ? Browser.from(browser) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: BrowserInitializer) {
|
||||
super(parent, guid, initializer, true);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserInitializer) {
|
||||
super(parent, type, guid, initializer, true);
|
||||
this._channel.on('close', () => {
|
||||
this._isConnected = false;
|
||||
this.emit(Events.Browser.Disconnected);
|
||||
|
|
@ -47,10 +48,12 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
|||
this._closedPromise = new Promise(f => this.once(Events.Browser.Disconnected, f));
|
||||
}
|
||||
|
||||
async newContext(options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||
delete (options as any).logger;
|
||||
async newContext(options: types.BrowserContextOptions & { logger?: LoggerSink } = {}): Promise<BrowserContext> {
|
||||
const logger = options.logger;
|
||||
options = { ...options, logger: undefined };
|
||||
const context = BrowserContext.from(await this._channel.newContext(options));
|
||||
this._contexts.add(context);
|
||||
context._logger = logger || this._logger;
|
||||
context._browser = this;
|
||||
return context;
|
||||
}
|
||||
|
|
@ -59,8 +62,7 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
|||
return [...this._contexts];
|
||||
}
|
||||
|
||||
async newPage(options: types.BrowserContextOptions = {}): Promise<Page> {
|
||||
delete (options as any).logger;
|
||||
async newPage(options: types.BrowserContextOptions & { logger?: LoggerSink } = {}): Promise<Page> {
|
||||
const context = await this.newContext(options);
|
||||
const page = await context.newPage();
|
||||
page._ownedContext = context;
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
|||
return context ? BrowserContext.from(context) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: BrowserContextInitializer) {
|
||||
super(parent, guid, initializer, true);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserContextInitializer) {
|
||||
super(parent, type, guid, initializer, true);
|
||||
initializer.pages.forEach(p => {
|
||||
const page = Page.from(p);
|
||||
this._pages.add(page);
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ export class BrowserServer extends ChannelOwner<BrowserServerChannel, BrowserSer
|
|||
return (server as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: BrowserServerInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserServerInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._channel.on('close', () => this.emit(Events.BrowserServer.Close));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,15 +20,16 @@ import { Browser } from './browser';
|
|||
import { BrowserContext } from './browserContext';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { BrowserServer } from './browserServer';
|
||||
import { LoggerSink } from '../../loggerSink';
|
||||
|
||||
export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeInitializer> {
|
||||
|
||||
static from(browserTyep: BrowserTypeChannel): BrowserType {
|
||||
return (browserTyep as any)._object;
|
||||
static from(browserType: BrowserTypeChannel): BrowserType {
|
||||
return (browserType as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: BrowserTypeInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserTypeInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
executablePath(): string {
|
||||
|
|
@ -39,23 +40,32 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
|||
return this._initializer.name;
|
||||
}
|
||||
|
||||
async launch(options: types.LaunchOptions = {}): Promise<Browser> {
|
||||
delete (options as any).logger;
|
||||
return Browser.from(await this._channel.launch(options));
|
||||
async launch(options: types.LaunchOptions & { logger?: LoggerSink } = {}): Promise<Browser> {
|
||||
const logger = options.logger;
|
||||
options = { ...options, logger: undefined };
|
||||
const browser = Browser.from(await this._channel.launch(options));
|
||||
browser._logger = logger;
|
||||
return browser;
|
||||
}
|
||||
|
||||
async launchServer(options: types.LaunchServerOptions = {}): Promise<BrowserServer> {
|
||||
delete (options as any).logger;
|
||||
async launchServer(options: types.LaunchServerOptions & { logger?: LoggerSink } = {}): Promise<BrowserServer> {
|
||||
options = { ...options, logger: undefined };
|
||||
return BrowserServer.from(await this._channel.launchServer(options));
|
||||
}
|
||||
|
||||
async launchPersistentContext(userDataDir: string, options: types.LaunchOptions & types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||
delete (options as any).logger;
|
||||
return BrowserContext.from(await this._channel.launchPersistentContext({ userDataDir, ...options }));
|
||||
async launchPersistentContext(userDataDir: string, options: types.LaunchOptions & types.BrowserContextOptions & { logger?: LoggerSink } = {}): Promise<BrowserContext> {
|
||||
const logger = options.logger;
|
||||
options = { ...options, logger: undefined };
|
||||
const context = BrowserContext.from(await this._channel.launchPersistentContext({ userDataDir, ...options }));
|
||||
context._logger = logger;
|
||||
return context;
|
||||
}
|
||||
|
||||
async connect(options: types.ConnectOptions): Promise<Browser> {
|
||||
delete (options as any).logger;
|
||||
return Browser.from(await this._channel.connect(options));
|
||||
async connect(options: types.ConnectOptions & { logger?: LoggerSink }): Promise<Browser> {
|
||||
const logger = options.logger;
|
||||
options = { ...options, logger: undefined };
|
||||
const browser = Browser.from(await this._channel.connect(options));
|
||||
browser._logger = logger;
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ export class CDPSession extends ChannelOwner<CDPSessionChannel, CDPSessionInitia
|
|||
removeListener: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
once: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: CDPSessionInitializer) {
|
||||
super(parent, guid, initializer, true);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: CDPSessionInitializer) {
|
||||
super(parent, type, guid, initializer, true);
|
||||
|
||||
this._channel.on('event', ({ method, params }) => this.emit(method, params));
|
||||
this._channel.on('disconnected', () => this._dispose());
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { EventEmitter } from 'events';
|
|||
import { Channel } from '../channels';
|
||||
import { Connection } from './connection';
|
||||
import { assert } from '../../helper';
|
||||
import { LoggerSink } from '../../loggerSink';
|
||||
|
||||
export abstract class ChannelOwner<T extends Channel = Channel, Initializer = {}> extends EventEmitter {
|
||||
private _connection: Connection;
|
||||
|
|
@ -27,21 +28,25 @@ export abstract class ChannelOwner<T extends Channel = Channel, Initializer = {}
|
|||
// Only "isScope" channel owners have registered objects inside.
|
||||
private _objects = new Map<string, ChannelOwner>();
|
||||
|
||||
readonly _type: string;
|
||||
readonly _guid: string;
|
||||
readonly _channel: T;
|
||||
readonly _initializer: Initializer;
|
||||
_logger: LoggerSink | undefined;
|
||||
|
||||
constructor(parent: ChannelOwner | Connection, guid: string, initializer: Initializer, isScope?: boolean) {
|
||||
constructor(parent: ChannelOwner | Connection, type: string, guid: string, initializer: Initializer, isScope?: boolean) {
|
||||
super();
|
||||
|
||||
this._connection = parent instanceof Connection ? parent : parent._connection;
|
||||
this._type = type;
|
||||
this._guid = guid;
|
||||
this._isScope = !!isScope;
|
||||
this._parent = parent instanceof Connection ? undefined : parent;
|
||||
|
||||
this._connection._objects.set(guid, this);
|
||||
if (this._parent)
|
||||
if (this._parent) {
|
||||
this._parent._objects.set(guid, this);
|
||||
this._logger = this._parent._logger;
|
||||
}
|
||||
|
||||
const base = new EventEmitter();
|
||||
this._channel = new Proxy(base, {
|
||||
|
|
@ -60,7 +65,23 @@ export abstract class ChannelOwner<T extends Channel = Channel, Initializer = {}
|
|||
return obj.addListener;
|
||||
if (prop === 'removeEventListener')
|
||||
return obj.removeListener;
|
||||
return (params: any) => this._connection.sendMessageToServer({ guid, method: String(prop), params });
|
||||
|
||||
return async (params: any) => {
|
||||
const method = String(prop);
|
||||
const apiName = this._type + '.' + method;
|
||||
if (this._logger && this._logger.isEnabled('api', 'info'))
|
||||
this._logger.log('api', 'info', `=> ${apiName} started`, [], { color: 'cyan' });
|
||||
try {
|
||||
const result = await this._connection.sendMessageToServer({ guid, method: String(prop), params });
|
||||
if (this._logger && this._logger.isEnabled('api', 'info'))
|
||||
this._logger.log('api', 'info', `=> ${apiName} succeeded`, [], { color: 'cyan' });
|
||||
return result;
|
||||
} catch (e) {
|
||||
if (this._logger && this._logger.isEnabled('api', 'info'))
|
||||
this._logger.log('api', 'info', `=> ${apiName} failed`, [], { color: 'cyan' });
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
},
|
||||
});
|
||||
(this._channel as any)._object = this;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import { Channel } from '../channels';
|
|||
|
||||
class Root extends ChannelOwner<Channel, {}> {
|
||||
constructor(connection: Connection) {
|
||||
super(connection, '', {}, true);
|
||||
super(connection, '', '', {}, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -131,59 +131,58 @@ export class Connection {
|
|||
initializer = this._replaceGuidsWithChannels(initializer);
|
||||
switch (type) {
|
||||
case 'bindingCall':
|
||||
result = new BindingCall(parent, guid, initializer);
|
||||
result = new BindingCall(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'browser':
|
||||
result = new Browser(parent, guid, initializer);
|
||||
result = new Browser(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'browserServer':
|
||||
result = new BrowserServer(parent, guid, initializer);
|
||||
result = new BrowserServer(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'browserType':
|
||||
result = new BrowserType(parent, guid, initializer);
|
||||
result = new BrowserType(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'cdpSession':
|
||||
// Chromium-specific.
|
||||
result = new CDPSession(parent, guid, initializer);
|
||||
result = new CDPSession(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'context':
|
||||
result = new BrowserContext(parent, guid, initializer);
|
||||
result = new BrowserContext(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'consoleMessage':
|
||||
result = new ConsoleMessage(parent, guid, initializer);
|
||||
result = new ConsoleMessage(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'dialog':
|
||||
result = new Dialog(parent, guid, initializer);
|
||||
result = new Dialog(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'download':
|
||||
result = new Download(parent, guid, initializer);
|
||||
result = new Download(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'elementHandle':
|
||||
result = new ElementHandle(parent, guid, initializer);
|
||||
result = new ElementHandle(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'frame':
|
||||
result = new Frame(parent, guid, initializer);
|
||||
result = new Frame(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'jsHandle':
|
||||
result = new JSHandle(parent, guid, initializer);
|
||||
result = new JSHandle(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'page':
|
||||
result = new Page(parent, guid, initializer);
|
||||
result = new Page(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'playwright':
|
||||
result = new Playwright(parent, guid, initializer);
|
||||
result = new Playwright(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'request':
|
||||
result = new Request(parent, guid, initializer);
|
||||
result = new Request(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'response':
|
||||
result = new Response(parent, guid, initializer);
|
||||
result = new Response(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'route':
|
||||
result = new Route(parent, guid, initializer);
|
||||
result = new Route(parent, type, guid, initializer);
|
||||
break;
|
||||
case 'worker':
|
||||
result = new Worker(parent, guid, initializer);
|
||||
result = new Worker(parent, type, guid, initializer);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Missing type ' + type);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ export class ConsoleMessage extends ChannelOwner<ConsoleMessageChannel, ConsoleM
|
|||
return (message as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: ConsoleMessageInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: ConsoleMessageInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
type(): string {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ export class Dialog extends ChannelOwner<DialogChannel, DialogInitializer> {
|
|||
return (dialog as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: DialogInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: DialogInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
type(): string {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ export class Download extends ChannelOwner<DownloadChannel, DownloadInitializer>
|
|||
return (download as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: DownloadInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: DownloadInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
url(): string {
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> {
|
|||
return handle ? ElementHandle.from(handle) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: JSHandleInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: JSHandleInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._elementChannel = this._channel as ElementHandleChannel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ export class Frame extends ChannelOwner<FrameChannel, FrameInitializer> {
|
|||
return frame ? Frame.from(frame) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: FrameInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: FrameInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._parentFrame = Frame.fromNullable(initializer.parentFrame);
|
||||
if (this._parentFrame)
|
||||
this._parentFrame._childFrames.add(this);
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ export class JSHandle<T = any> extends ChannelOwner<JSHandleChannel, JSHandleIni
|
|||
return handle ? JSHandle.from(handle) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: JSHandleInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: JSHandleInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._preview = this._initializer.preview;
|
||||
this._channel.on('previewUpdated', preview => this._preview = preview);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ export class Request extends ChannelOwner<RequestChannel, RequestInitializer> {
|
|||
return request ? Request.from(request) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: RequestInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: RequestInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._redirectedFrom = Request.fromNullable(initializer.redirectedFrom);
|
||||
if (this._redirectedFrom)
|
||||
this._redirectedFrom._redirectedTo = this;
|
||||
|
|
@ -137,8 +137,8 @@ export class Route extends ChannelOwner<RouteChannel, RouteInitializer> {
|
|||
return (route as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: RouteInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: RouteInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
request(): Request {
|
||||
|
|
@ -170,8 +170,8 @@ export class Response extends ChannelOwner<ResponseChannel, ResponseInitializer>
|
|||
return response ? Response.from(response) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: ResponseInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: ResponseInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
url(): string {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
|||
return page ? Page.from(page) : null;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: PageInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: PageInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this.accessibility = new Accessibility(this._channel);
|
||||
this.keyboard = new Keyboard(this._channel);
|
||||
this.mouse = new Mouse(this._channel);
|
||||
|
|
@ -522,8 +522,8 @@ export class BindingCall extends ChannelOwner<BindingCallChannel, BindingCallIni
|
|||
return (channel as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: BindingCallInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BindingCallInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
async call(func: FunctionWithSource) {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ export class Playwright extends ChannelOwner<PlaywrightChannel, PlaywrightInitia
|
|||
webkit: BrowserType;
|
||||
devices: types.Devices;
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: PlaywrightInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: PlaywrightInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this.chromium = BrowserType.from(initializer.chromium);
|
||||
this.firefox = BrowserType.from(initializer.firefox);
|
||||
this.webkit = BrowserType.from(initializer.webkit);
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ export class Worker extends ChannelOwner<WorkerChannel, WorkerInitializer> {
|
|||
return (worker as any)._object;
|
||||
}
|
||||
|
||||
constructor(parent: ChannelOwner, guid: string, initializer: WorkerInitializer) {
|
||||
super(parent, guid, initializer);
|
||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: WorkerInitializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this._channel.on('close', () => {
|
||||
if (this._page)
|
||||
this._page._workers.delete(this);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const utils = require('./utils');
|
||||
const {FFOX, CHROMIUM, WEBKIT, USES_HOOKS} = utils.testOptions(browserType);
|
||||
const {FFOX, CHROMIUM, WEBKIT, WIN, USES_HOOKS} = utils.testOptions(browserType);
|
||||
|
||||
describe('Playwright', function() {
|
||||
describe('browserType.launch', function() {
|
||||
|
|
|
|||
|
|
@ -18,33 +18,45 @@ const fs = require('fs');
|
|||
const path = require('path');
|
||||
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = require('./utils').testOptions(browserType);
|
||||
|
||||
describe.skip(CHANNEL)('Logger', function() {
|
||||
describe('Logger', function() {
|
||||
it('should log', async({browserType, defaultBrowserOptions}) => {
|
||||
const log = [];
|
||||
const browser = await browserType.launch({...defaultBrowserOptions, logger: {
|
||||
log: (name, severity, message) => log.push({name, severity, message}),
|
||||
isEnabled: (name, severity) => severity !== 'verbose'
|
||||
}});
|
||||
await browser.newContext();
|
||||
await browser.close();
|
||||
expect(log.length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.name.includes('browser')).length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.severity === 'info').length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.message.includes('<launching>')).length > 0).toBeTruthy();
|
||||
if (CHANNEL) {
|
||||
expect(log.filter(item => item.message.includes('browser.newContext started')).length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.message.includes('browser.newContext succeeded')).length > 0).toBeTruthy();
|
||||
} else {
|
||||
expect(log.filter(item => item.message.includes('browserType.launch started')).length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.message.includes('browserType.launch succeeded')).length > 0).toBeTruthy();
|
||||
}
|
||||
});
|
||||
it('should log context-level', async({browserType, defaultBrowserOptions}) => {
|
||||
const log = [];
|
||||
const browser = await browserType.launch(defaultBrowserOptions);
|
||||
const page = await browser.newPage({
|
||||
const context = await browser.newContext({
|
||||
logger: {
|
||||
log: (name, severity, message) => log.push({name, severity, message}),
|
||||
isEnabled: (name, severity) => severity !== 'verbose'
|
||||
}
|
||||
});
|
||||
const page = await context.newPage();
|
||||
await page.setContent('<button>Button</button>');
|
||||
await page.click('button');
|
||||
await browser.close();
|
||||
|
||||
expect(log.length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.message.includes('waiting for element')).length > 0).toBeTruthy();
|
||||
if (CHANNEL) {
|
||||
expect(log.filter(item => item.message.includes('context.newPage')).length > 0).toBeTruthy();
|
||||
expect(log.filter(item => item.message.includes('frame.click')).length > 0).toBeTruthy();
|
||||
} else {
|
||||
expect(log.filter(item => item.message.includes('page.click')).length > 0).toBeTruthy();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue