feat(rpc): ensure feature-detection works as before (#2898)
For this, some tests are migrated from skip() to feature detection, like our users would do.
This commit is contained in:
parent
2151757621
commit
9fd30e58e2
|
|
@ -98,11 +98,7 @@ export interface BrowserContextChannel extends Channel {
|
||||||
on(event: 'crServiceWorker', callback: (params: WorkerChannel) => void): this;
|
on(event: 'crServiceWorker', callback: (params: WorkerChannel) => void): this;
|
||||||
crNewCDPSession(params: { page: PageChannel }): Promise<CDPSessionChannel>;
|
crNewCDPSession(params: { page: PageChannel }): Promise<CDPSessionChannel>;
|
||||||
}
|
}
|
||||||
export type BrowserContextInitializer = {
|
export type BrowserContextInitializer = {};
|
||||||
pages: PageChannel[],
|
|
||||||
crBackgroundPages: PageChannel[],
|
|
||||||
crServiceWorkers: WorkerChannel[],
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
export interface PageChannel extends Channel {
|
export interface PageChannel extends Channel {
|
||||||
|
|
@ -117,7 +113,6 @@ export interface PageChannel extends Channel {
|
||||||
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: 'load', callback: () => 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;
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,15 @@ import { BrowserContext } from './browserContext';
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { Events } from '../../events';
|
import { Events } from '../../events';
|
||||||
import { CDPSession } from './cdpSession';
|
|
||||||
import { LoggerSink } from '../../loggerSink';
|
import { LoggerSink } from '../../loggerSink';
|
||||||
|
import { BrowserType } from './browserType';
|
||||||
|
|
||||||
export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||||
readonly _contexts = new Set<BrowserContext>();
|
readonly _contexts = new Set<BrowserContext>();
|
||||||
private _isConnected = true;
|
private _isConnected = true;
|
||||||
private _isClosedOrClosing = false;
|
private _isClosedOrClosing = false;
|
||||||
private _closedPromise: Promise<void>;
|
private _closedPromise: Promise<void>;
|
||||||
|
readonly _browserType: BrowserType;
|
||||||
|
|
||||||
static from(browser: BrowserChannel): Browser {
|
static from(browser: BrowserChannel): Browser {
|
||||||
return (browser as any)._object;
|
return (browser as any)._object;
|
||||||
|
|
@ -39,6 +40,7 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||||
|
|
||||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserInitializer) {
|
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserInitializer) {
|
||||||
super(parent, type, guid, initializer, true);
|
super(parent, type, guid, initializer, true);
|
||||||
|
this._browserType = parent as BrowserType;
|
||||||
this._channel.on('close', () => {
|
this._channel.on('close', () => {
|
||||||
this._isConnected = false;
|
this._isConnected = false;
|
||||||
this.emit(Events.Browser.Disconnected);
|
this.emit(Events.Browser.Disconnected);
|
||||||
|
|
@ -54,7 +56,6 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||||
const context = BrowserContext.from(await this._channel.newContext(options));
|
const context = BrowserContext.from(await this._channel.newContext(options));
|
||||||
this._contexts.add(context);
|
this._contexts.add(context);
|
||||||
context._logger = logger || this._logger;
|
context._logger = logger || this._logger;
|
||||||
context._browser = this;
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,16 +82,4 @@ export class Browser extends ChannelOwner<BrowserChannel, BrowserInitializer> {
|
||||||
}
|
}
|
||||||
await this._closedPromise;
|
await this._closedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async newBrowserCDPSession(): Promise<CDPSession> {
|
|
||||||
return CDPSession.from(await this._channel.crNewBrowserCDPSession());
|
|
||||||
}
|
|
||||||
|
|
||||||
async startTracing(page?: Page, options: { path?: string; screenshots?: boolean; categories?: string[]; } = {}) {
|
|
||||||
await this._channel.crStartTracing({ ...options, page: page ? page._channel : undefined });
|
|
||||||
}
|
|
||||||
|
|
||||||
async stopTracing(): Promise<Buffer> {
|
|
||||||
return Buffer.from(await this._channel.crStopTracing(), 'base64');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,13 @@ import { helper } from '../../helper';
|
||||||
import { Browser } from './browser';
|
import { Browser } from './browser';
|
||||||
import { Events } from '../../events';
|
import { Events } from '../../events';
|
||||||
import { TimeoutSettings } from '../../timeoutSettings';
|
import { TimeoutSettings } from '../../timeoutSettings';
|
||||||
import { CDPSession } from './cdpSession';
|
import { BrowserType } from './browserType';
|
||||||
import { Events as ChromiumEvents } from '../../chromium/events';
|
|
||||||
import { Worker } from './worker';
|
|
||||||
|
|
||||||
export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> {
|
export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserContextInitializer> {
|
||||||
_pages = new Set<Page>();
|
_pages = new Set<Page>();
|
||||||
_crBackgroundPages = new Set<Page>();
|
|
||||||
_crServiceWorkers = new Set<Worker>();
|
|
||||||
private _routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
private _routes: { url: types.URLMatch, handler: network.RouteHandler }[] = [];
|
||||||
_browser: Browser | undefined;
|
readonly _browser: Browser | undefined;
|
||||||
|
readonly _browserType: BrowserType;
|
||||||
readonly _bindings = new Map<string, frames.FunctionWithSource>();
|
readonly _bindings = new Map<string, frames.FunctionWithSource>();
|
||||||
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
||||||
_timeoutSettings = new TimeoutSettings();
|
_timeoutSettings = new TimeoutSettings();
|
||||||
|
|
@ -52,43 +49,22 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
||||||
|
|
||||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserContextInitializer) {
|
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserContextInitializer) {
|
||||||
super(parent, type, guid, initializer, true);
|
super(parent, type, guid, initializer, true);
|
||||||
initializer.pages.forEach(p => {
|
if (parent instanceof Browser) {
|
||||||
const page = Page.from(p);
|
this._browser = parent;
|
||||||
this._pages.add(page);
|
this._browserType = this._browser._browserType;
|
||||||
page._setBrowserContext(this);
|
} else {
|
||||||
});
|
// Launching persistent context does not produce a browser at all.
|
||||||
|
this._browserType = parent as BrowserType;
|
||||||
|
}
|
||||||
|
|
||||||
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('page', page => this._onPage(Page.from(page)));
|
this._channel.on('page', page => this._onPage(Page.from(page)));
|
||||||
this._channel.on('route', ({ route, request }) => this._onRoute(network.Route.from(route), network.Request.from(request)));
|
this._channel.on('route', ({ route, request }) => this._onRoute(network.Route.from(route), network.Request.from(request)));
|
||||||
this._closedPromise = new Promise(f => this.once(Events.BrowserContext.Close, f));
|
this._closedPromise = new Promise(f => this.once(Events.BrowserContext.Close, f));
|
||||||
|
|
||||||
initializer.crBackgroundPages.forEach(p => {
|
|
||||||
const page = Page.from(p);
|
|
||||||
this._crBackgroundPages.add(page);
|
|
||||||
page._setBrowserContext(this);
|
|
||||||
});
|
|
||||||
this._channel.on('crBackgroundPage', pageChannel => {
|
|
||||||
const page = Page.from(pageChannel);
|
|
||||||
page._setBrowserContext(this);
|
|
||||||
this._crBackgroundPages.add(page);
|
|
||||||
this.emit(ChromiumEvents.CRBrowserContext.BackgroundPage, page);
|
|
||||||
});
|
|
||||||
initializer.crServiceWorkers.forEach(w => {
|
|
||||||
const worker = Worker.from(w);
|
|
||||||
worker._context = this;
|
|
||||||
this._crServiceWorkers.add(worker);
|
|
||||||
});
|
|
||||||
this._channel.on('crServiceWorker', serviceWorkerChannel => {
|
|
||||||
const worker = Worker.from(serviceWorkerChannel);
|
|
||||||
worker._context = this;
|
|
||||||
this._crServiceWorkers.add(worker);
|
|
||||||
this.emit(ChromiumEvents.CRBrowserContext.ServiceWorker, worker);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onPage(page: Page): void {
|
private _onPage(page: Page): void {
|
||||||
page._setBrowserContext(this);
|
|
||||||
this._pages.add(page);
|
this._pages.add(page);
|
||||||
this.emit(Events.BrowserContext.Page, page);
|
this.emit(Events.BrowserContext.Page, page);
|
||||||
}
|
}
|
||||||
|
|
@ -234,16 +210,4 @@ export class BrowserContext extends ChannelOwner<BrowserContextChannel, BrowserC
|
||||||
}
|
}
|
||||||
await this._closedPromise;
|
await this._closedPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
async newCDPSession(page: Page): Promise<CDPSession> {
|
|
||||||
return CDPSession.from(await this._channel.crNewCDPSession({ page: page._channel }));
|
|
||||||
}
|
|
||||||
|
|
||||||
backgroundPages(): Page[] {
|
|
||||||
return [...this._crBackgroundPages];
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceWorkers(): Worker[] {
|
|
||||||
return [...this._crServiceWorkers];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export class BrowserType extends ChannelOwner<BrowserTypeChannel, BrowserTypeIni
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserTypeInitializer) {
|
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserTypeInitializer) {
|
||||||
super(parent, type, guid, initializer);
|
super(parent, type, guid, initializer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
executablePath(): string {
|
executablePath(): string {
|
||||||
|
|
|
||||||
33
src/rpc/client/chromiumBrowser.ts
Normal file
33
src/rpc/client/chromiumBrowser.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* 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 { Page } from './page';
|
||||||
|
import { CDPSession } from './cdpSession';
|
||||||
|
import { Browser } from './browser';
|
||||||
|
|
||||||
|
export class ChromiumBrowser extends Browser {
|
||||||
|
async newBrowserCDPSession(): Promise<CDPSession> {
|
||||||
|
return CDPSession.from(await this._channel.crNewBrowserCDPSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
async startTracing(page?: Page, options: { path?: string; screenshots?: boolean; categories?: string[]; } = {}) {
|
||||||
|
await this._channel.crStartTracing({ ...options, page: page ? page._channel : undefined });
|
||||||
|
}
|
||||||
|
|
||||||
|
async stopTracing(): Promise<Buffer> {
|
||||||
|
return Buffer.from(await this._channel.crStopTracing(), 'base64');
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/rpc/client/chromiumBrowserContext.ts
Normal file
56
src/rpc/client/chromiumBrowserContext.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2017 Google Inc. All rights reserved.
|
||||||
|
* Modifications 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 { Page } from './page';
|
||||||
|
import { BrowserContextInitializer } from '../channels';
|
||||||
|
import { ChannelOwner } from './channelOwner';
|
||||||
|
import { CDPSession } from './cdpSession';
|
||||||
|
import { Events as ChromiumEvents } from '../../chromium/events';
|
||||||
|
import { Worker } from './worker';
|
||||||
|
import { BrowserContext } from './browserContext';
|
||||||
|
|
||||||
|
export class ChromiumBrowserContext extends BrowserContext {
|
||||||
|
_backgroundPages = new Set<Page>();
|
||||||
|
_serviceWorkers = new Set<Worker>();
|
||||||
|
|
||||||
|
constructor(parent: ChannelOwner, type: string, guid: string, initializer: BrowserContextInitializer) {
|
||||||
|
super(parent, type, guid, initializer);
|
||||||
|
this._channel.on('crBackgroundPage', pageChannel => {
|
||||||
|
const page = Page.from(pageChannel);
|
||||||
|
this._backgroundPages.add(page);
|
||||||
|
this.emit(ChromiumEvents.CRBrowserContext.BackgroundPage, page);
|
||||||
|
});
|
||||||
|
this._channel.on('crServiceWorker', serviceWorkerChannel => {
|
||||||
|
const worker = Worker.from(serviceWorkerChannel);
|
||||||
|
worker._context = this;
|
||||||
|
this._serviceWorkers.add(worker);
|
||||||
|
this.emit(ChromiumEvents.CRBrowserContext.ServiceWorker, worker);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundPages(): Page[] {
|
||||||
|
return [...this._backgroundPages];
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceWorkers(): Worker[] {
|
||||||
|
return [...this._serviceWorkers];
|
||||||
|
}
|
||||||
|
|
||||||
|
async newCDPSession(page: Page): Promise<CDPSession> {
|
||||||
|
return CDPSession.from(await this._channel.crNewCDPSession({ page: page._channel }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,8 @@ import { BrowserServer } from './browserServer';
|
||||||
import { CDPSession } from './cdpSession';
|
import { CDPSession } from './cdpSession';
|
||||||
import { Playwright } from './playwright';
|
import { Playwright } from './playwright';
|
||||||
import { Channel } from '../channels';
|
import { Channel } from '../channels';
|
||||||
|
import { ChromiumBrowser } from './chromiumBrowser';
|
||||||
|
import { ChromiumBrowserContext } from './chromiumBrowserContext';
|
||||||
|
|
||||||
class Root extends ChannelOwner<Channel, {}> {
|
class Root extends ChannelOwner<Channel, {}> {
|
||||||
constructor(connection: Connection) {
|
constructor(connection: Connection) {
|
||||||
|
|
@ -133,7 +135,10 @@ export class Connection {
|
||||||
result = new BindingCall(parent, type, guid, initializer);
|
result = new BindingCall(parent, type, guid, initializer);
|
||||||
break;
|
break;
|
||||||
case 'browser':
|
case 'browser':
|
||||||
result = new Browser(parent, type, guid, initializer);
|
if ((parent as BrowserType).name() === 'chromium')
|
||||||
|
result = new ChromiumBrowser(parent, type, guid, initializer);
|
||||||
|
else
|
||||||
|
result = new Browser(parent, type, guid, initializer);
|
||||||
break;
|
break;
|
||||||
case 'browserServer':
|
case 'browserServer':
|
||||||
result = new BrowserServer(parent, type, guid, initializer);
|
result = new BrowserServer(parent, type, guid, initializer);
|
||||||
|
|
@ -145,7 +150,12 @@ export class Connection {
|
||||||
result = new CDPSession(parent, type, guid, initializer);
|
result = new CDPSession(parent, type, guid, initializer);
|
||||||
break;
|
break;
|
||||||
case 'context':
|
case 'context':
|
||||||
result = new BrowserContext(parent, type, guid, initializer);
|
// Launching persistent context produces BrowserType parent directly for BrowserContext.
|
||||||
|
const browserType = parent instanceof Browser ? parent._browserType : parent as BrowserType;
|
||||||
|
if (browserType.name() === 'chromium')
|
||||||
|
result = new ChromiumBrowserContext(parent, type, guid, initializer);
|
||||||
|
else
|
||||||
|
result = new BrowserContext(parent, type, guid, initializer);
|
||||||
break;
|
break;
|
||||||
case 'consoleMessage':
|
case 'consoleMessage':
|
||||||
result = new ConsoleMessage(parent, type, guid, initializer);
|
result = new ConsoleMessage(parent, type, guid, initializer);
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,7 @@ import { Buffer } from 'buffer';
|
||||||
import { Coverage } from './coverage';
|
import { Coverage } from './coverage';
|
||||||
|
|
||||||
export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
|
private _browserContext: BrowserContext;
|
||||||
private _browserContext: BrowserContext | undefined;
|
|
||||||
_ownedContext: BrowserContext | undefined;
|
_ownedContext: BrowserContext | undefined;
|
||||||
|
|
||||||
private _mainFrame: Frame;
|
private _mainFrame: Frame;
|
||||||
|
|
@ -54,10 +53,12 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
readonly accessibility: Accessibility;
|
readonly accessibility: Accessibility;
|
||||||
readonly keyboard: Keyboard;
|
readonly keyboard: Keyboard;
|
||||||
readonly mouse: Mouse;
|
readonly mouse: Mouse;
|
||||||
readonly coverage: Coverage;
|
coverage: Coverage | null = null;
|
||||||
|
pdf?: (options?: types.PDFOptions) => Promise<Buffer>;
|
||||||
|
|
||||||
readonly _bindings = new Map<string, FunctionWithSource>();
|
readonly _bindings = new Map<string, FunctionWithSource>();
|
||||||
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
private _pendingWaitForEvents = new Map<(error: Error) => void, string>();
|
||||||
private _timeoutSettings = new TimeoutSettings();
|
private _timeoutSettings: TimeoutSettings;
|
||||||
_isPageCall = false;
|
_isPageCall = false;
|
||||||
|
|
||||||
static from(page: PageChannel): Page {
|
static from(page: PageChannel): Page {
|
||||||
|
|
@ -70,10 +71,12 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
|
|
||||||
constructor(parent: ChannelOwner, type: string, guid: string, initializer: PageInitializer) {
|
constructor(parent: ChannelOwner, type: string, guid: string, initializer: PageInitializer) {
|
||||||
super(parent, type, guid, initializer);
|
super(parent, type, guid, initializer);
|
||||||
|
this._browserContext = parent as BrowserContext;
|
||||||
|
this._timeoutSettings = new TimeoutSettings(this._browserContext._timeoutSettings);
|
||||||
|
|
||||||
this.accessibility = new Accessibility(this._channel);
|
this.accessibility = new Accessibility(this._channel);
|
||||||
this.keyboard = new Keyboard(this._channel);
|
this.keyboard = new Keyboard(this._channel);
|
||||||
this.mouse = new Mouse(this._channel);
|
this.mouse = new Mouse(this._channel);
|
||||||
this.coverage = new Coverage(this._channel);
|
|
||||||
|
|
||||||
this._mainFrame = Frame.from(initializer.mainFrame);
|
this._mainFrame = Frame.from(initializer.mainFrame);
|
||||||
this._mainFrame._page = this;
|
this._mainFrame._page = this;
|
||||||
|
|
@ -101,11 +104,11 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
this._channel.on('response', response => this.emit(Events.Page.Response, Response.from(response)));
|
this._channel.on('response', response => this.emit(Events.Page.Response, Response.from(response)));
|
||||||
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)));
|
||||||
this._channel.on('worker', worker => this._onWorker(Worker.from(worker)));
|
this._channel.on('worker', worker => this._onWorker(Worker.from(worker)));
|
||||||
}
|
|
||||||
|
|
||||||
_setBrowserContext(context: BrowserContext) {
|
if (this._browserContext._browserType.name() === 'chromium') {
|
||||||
this._browserContext = context;
|
this.coverage = new Coverage(this._channel);
|
||||||
this._timeoutSettings = new TimeoutSettings(context._timeoutSettings);
|
this.pdf = options => this._pdf(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onRequestFailed(request: Request, failureText: string | null) {
|
private _onRequestFailed(request: Request, failureText: string | null) {
|
||||||
|
|
@ -142,7 +145,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._browserContext!._onRoute(route, request);
|
this._browserContext._onRoute(route, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onBinding(bindingCall: BindingCall) {
|
async _onBinding(bindingCall: BindingCall) {
|
||||||
|
|
@ -151,7 +154,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
bindingCall.call(func);
|
bindingCall.call(func);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._browserContext!._onBinding(bindingCall);
|
this._browserContext._onBinding(bindingCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWorker(worker: Worker): void {
|
_onWorker(worker: Worker): void {
|
||||||
|
|
@ -162,7 +165,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
|
|
||||||
private _onClose() {
|
private _onClose() {
|
||||||
this._closed = true;
|
this._closed = true;
|
||||||
this._browserContext!._pages.delete(this);
|
this._browserContext._pages.delete(this);
|
||||||
this._rejectPendingOperations(false);
|
this._rejectPendingOperations(false);
|
||||||
this.emit(Events.Page.Close);
|
this.emit(Events.Page.Close);
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +187,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
context(): BrowserContext {
|
context(): BrowserContext {
|
||||||
return this._browserContext!;
|
return this._browserContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
async opener(): Promise<Page | null> {
|
async opener(): Promise<Page | null> {
|
||||||
|
|
@ -280,7 +283,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
async exposeBinding(name: string, binding: FunctionWithSource) {
|
async exposeBinding(name: string, binding: FunctionWithSource) {
|
||||||
if (this._bindings.has(name))
|
if (this._bindings.has(name))
|
||||||
throw new Error(`Function "${name}" has been already registered`);
|
throw new Error(`Function "${name}" has been already registered`);
|
||||||
if (this._browserContext!._bindings.has(name))
|
if (this._browserContext._bindings.has(name))
|
||||||
throw new Error(`Function "${name}" has been already registered in the browser context`);
|
throw new Error(`Function "${name}" has been already registered in the browser context`);
|
||||||
this._bindings.set(name, binding);
|
this._bindings.set(name, binding);
|
||||||
await this._channel.exposeBinding({ name });
|
await this._channel.exposeBinding({ name });
|
||||||
|
|
@ -499,7 +502,7 @@ export class Page extends ChannelOwner<PageChannel, PageInitializer> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
async pdf(options: types.PDFOptions = {}): Promise<Buffer> {
|
async _pdf(options: types.PDFOptions = {}): Promise<Buffer> {
|
||||||
const transportOptions: PDFOptions = { ...options } as PDFOptions;
|
const transportOptions: PDFOptions = { ...options } as PDFOptions;
|
||||||
if (transportOptions.margin)
|
if (transportOptions.margin)
|
||||||
transportOptions.margin = { ...transportOptions.margin };
|
transportOptions.margin = { ...transportOptions.margin };
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import { ChannelOwner } from './channelOwner';
|
||||||
import { Func1, JSHandle, parseResult, serializeArgument, SmartHandle } from './jsHandle';
|
import { Func1, JSHandle, parseResult, serializeArgument, SmartHandle } from './jsHandle';
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import { BrowserContext } from './browserContext';
|
import { BrowserContext } from './browserContext';
|
||||||
|
import { ChromiumBrowserContext } from './chromiumBrowserContext';
|
||||||
|
|
||||||
export class Worker extends ChannelOwner<WorkerChannel, WorkerInitializer> {
|
export class Worker extends ChannelOwner<WorkerChannel, WorkerInitializer> {
|
||||||
_page: Page | undefined; // Set for web workers.
|
_page: Page | undefined; // Set for web workers.
|
||||||
|
|
@ -36,7 +37,7 @@ export class Worker extends ChannelOwner<WorkerChannel, WorkerInitializer> {
|
||||||
if (this._page)
|
if (this._page)
|
||||||
this._page._workers.delete(this);
|
this._page._workers.delete(this);
|
||||||
if (this._context)
|
if (this._context)
|
||||||
this._context._crServiceWorkers.delete(this);
|
(this._context as ChromiumBrowserContext)._serviceWorkers.delete(this);
|
||||||
this.emit(Events.Worker.Close, this);
|
this.emit(Events.Worker.Close, this);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,25 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, Browser
|
||||||
private _context: BrowserContextBase;
|
private _context: BrowserContextBase;
|
||||||
|
|
||||||
constructor(scope: DispatcherScope, context: BrowserContextBase) {
|
constructor(scope: DispatcherScope, context: BrowserContextBase) {
|
||||||
let crBackgroundPages: PageDispatcher[] = [];
|
super(scope, context, 'context', {}, true);
|
||||||
let crServiceWorkers: WorkerDispatcher[] = [];
|
|
||||||
if (context._browserBase._options.name === 'chromium') {
|
|
||||||
crBackgroundPages = (context as CRBrowserContext).backgroundPages().map(p => new PageDispatcher(scope, p));
|
|
||||||
context.on(ChromiumEvents.CRBrowserContext.BackgroundPage, page => this._dispatchEvent('crBackgroundPage', new PageDispatcher(this._scope, page)));
|
|
||||||
crServiceWorkers = (context as CRBrowserContext).serviceWorkers().map(w => new WorkerDispatcher(scope, w));
|
|
||||||
context.on(ChromiumEvents.CRBrowserContext.ServiceWorker, serviceWorker => this._dispatchEvent('crServiceWorker', new WorkerDispatcher(this._scope, serviceWorker)));
|
|
||||||
}
|
|
||||||
|
|
||||||
super(scope, context, 'context', {
|
|
||||||
pages: context.pages().map(p => new PageDispatcher(scope, p)),
|
|
||||||
crBackgroundPages,
|
|
||||||
crServiceWorkers,
|
|
||||||
}, true);
|
|
||||||
this._context = context;
|
this._context = context;
|
||||||
|
|
||||||
|
for (const page of context.pages())
|
||||||
|
this._dispatchEvent('page', new PageDispatcher(this._scope, page));
|
||||||
context.on(Events.BrowserContext.Page, page => this._dispatchEvent('page', new PageDispatcher(this._scope, page)));
|
context.on(Events.BrowserContext.Page, page => this._dispatchEvent('page', new PageDispatcher(this._scope, page)));
|
||||||
context.on(Events.BrowserContext.Close, () => {
|
context.on(Events.BrowserContext.Close, () => {
|
||||||
this._dispatchEvent('close');
|
this._dispatchEvent('close');
|
||||||
this._dispose();
|
this._dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (context._browserBase._options.name === 'chromium') {
|
||||||
|
for (const page of (context as CRBrowserContext).backgroundPages())
|
||||||
|
this._dispatchEvent('crBackgroundPage', new PageDispatcher(this._scope, page));
|
||||||
|
context.on(ChromiumEvents.CRBrowserContext.BackgroundPage, page => this._dispatchEvent('crBackgroundPage', new PageDispatcher(this._scope, page)));
|
||||||
|
for (const serviceWorker of (context as CRBrowserContext).serviceWorkers())
|
||||||
|
this._dispatchEvent('crServiceWorker', new WorkerDispatcher(this._scope, serviceWorker));
|
||||||
|
context.on(ChromiumEvents.CRBrowserContext.ServiceWorker, serviceWorker => this._dispatchEvent('crServiceWorker', new WorkerDispatcher(this._scope, serviceWorker)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async setDefaultNavigationTimeoutNoReply(params: { timeout: number }) {
|
async setDefaultNavigationTimeoutNoReply(params: { timeout: number }) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||||
super(scope, browserType, 'browserType', {
|
super(scope, browserType, 'browserType', {
|
||||||
executablePath: browserType.executablePath(),
|
executablePath: browserType.executablePath(),
|
||||||
name: browserType.name()
|
name: browserType.name()
|
||||||
}, false, browserType.name());
|
}, true, browserType.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(params: types.LaunchOptions): Promise<BrowserChannel> {
|
async launch(params: types.LaunchOptions): Promise<BrowserChannel> {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ export class PageDispatcher extends Dispatcher<Page, PageInitializer> implements
|
||||||
private _page: Page;
|
private _page: Page;
|
||||||
|
|
||||||
constructor(scope: DispatcherScope, page: Page) {
|
constructor(scope: DispatcherScope, page: Page) {
|
||||||
|
// TODO: theoretically, there could be more than one frame already.
|
||||||
|
// If we split pageCreated and pageReady, there should be no main frame during pageCreated.
|
||||||
super(scope, page, 'page', {
|
super(scope, page, 'page', {
|
||||||
mainFrame: FrameDispatcher.from(scope, page.mainFrame()),
|
mainFrame: FrameDispatcher.from(scope, page.mainFrame()),
|
||||||
viewportSize: page.viewportSize(),
|
viewportSize: page.viewportSize(),
|
||||||
|
|
|
||||||
|
|
@ -22,15 +22,16 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
expect(!!browser._connection).toBeTruthy();
|
expect(!!browser._connection).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scope context handles', async({browser, server}) => {
|
it('should scope context handles', async({browserType, browser, server}) => {
|
||||||
const GOLDEN_PRECONDITION = {
|
const GOLDEN_PRECONDITION = {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browser', objects: [] }
|
||||||
{ _guid: 'webkit' },
|
] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
{ _guid: 'playwright' },
|
{ _guid: 'playwright' },
|
||||||
{ _guid: 'browser', objects: [] },
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
await expectScopeState(browser, GOLDEN_PRECONDITION);
|
await expectScopeState(browser, GOLDEN_PRECONDITION);
|
||||||
|
|
@ -41,18 +42,19 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
await expectScopeState(browser, {
|
await expectScopeState(browser, {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [] },
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browserType', objects: [] },
|
||||||
{ _guid: 'webkit' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'playwright' },
|
{ _guid: 'browser', objects: [
|
||||||
{ _guid: 'browser', objects: [
|
{ _guid: 'context', objects: [
|
||||||
{ _guid: 'context', objects: [
|
{ _guid: 'frame' },
|
||||||
{ _guid: 'frame' },
|
{ _guid: 'page' },
|
||||||
{ _guid: 'page' },
|
{ _guid: 'request' },
|
||||||
{ _guid: 'request' },
|
{ _guid: 'response' },
|
||||||
{ _guid: 'response' },
|
]},
|
||||||
]},
|
] },
|
||||||
] },
|
] },
|
||||||
|
{ _guid: 'playwright' },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -64,11 +66,12 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
const GOLDEN_PRECONDITION = {
|
const GOLDEN_PRECONDITION = {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browser', objects: [] }
|
||||||
{ _guid: 'webkit' },
|
] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
{ _guid: 'playwright' },
|
{ _guid: 'playwright' },
|
||||||
{ _guid: 'browser', objects: [] },
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
await expectScopeState(browserType, GOLDEN_PRECONDITION);
|
await expectScopeState(browserType, GOLDEN_PRECONDITION);
|
||||||
|
|
@ -77,13 +80,14 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
await expectScopeState(browserType, {
|
await expectScopeState(browserType, {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browser', objects: [
|
||||||
{ _guid: 'webkit' },
|
{ _guid: 'cdpSession', objects: [] },
|
||||||
{ _guid: 'playwright' },
|
] },
|
||||||
{ _guid: 'browser', objects: [
|
|
||||||
{ _guid: 'cdpSession', objects: [] },
|
|
||||||
] },
|
] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'playwright' },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -95,11 +99,12 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
const GOLDEN_PRECONDITION = {
|
const GOLDEN_PRECONDITION = {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browser', objects: [] }
|
||||||
{ _guid: 'webkit' },
|
] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
{ _guid: 'playwright' },
|
{ _guid: 'playwright' },
|
||||||
{ _guid: 'browser', objects: [] },
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
await expectScopeState(browserType, GOLDEN_PRECONDITION);
|
await expectScopeState(browserType, GOLDEN_PRECONDITION);
|
||||||
|
|
@ -109,14 +114,15 @@ describe.skip(!CHANNEL)('Channels', function() {
|
||||||
await expectScopeState(browserType, {
|
await expectScopeState(browserType, {
|
||||||
_guid: '',
|
_guid: '',
|
||||||
objects: [
|
objects: [
|
||||||
{ _guid: 'chromium' },
|
{ _guid: 'browserType', objects: [
|
||||||
{ _guid: 'firefox' },
|
{ _guid: 'browser', objects: [
|
||||||
{ _guid: 'webkit' },
|
{ _guid: 'context', objects: [] }
|
||||||
{ _guid: 'playwright' },
|
] },
|
||||||
{ _guid: 'browser', objects: [
|
{ _guid: 'browser', objects: [] },
|
||||||
{ _guid: 'context', objects: [] },
|
|
||||||
] },
|
] },
|
||||||
{ _guid: 'browser', objects: [] },
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'browserType', objects: [] },
|
||||||
|
{ _guid: 'playwright' },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -152,6 +158,8 @@ function trimGuids(object) {
|
||||||
const result = {};
|
const result = {};
|
||||||
for (const key in object)
|
for (const key in object)
|
||||||
result[key] = trimGuids(object[key]);
|
result[key] = trimGuids(object[key]);
|
||||||
|
if (result._guid === 'chromium' || result._guid === 'firefox' || result._guid === 'webkit')
|
||||||
|
result._guid = 'browserType';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (typeof object === 'string')
|
if (typeof object === 'string')
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = require('../utils').testOptions(browserType);
|
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = require('../utils').testOptions(browserType);
|
||||||
|
|
||||||
describe('ChromiumBrowserContext', function() {
|
describe('Service Worker', function() {
|
||||||
it('should create a worker from a service worker', async({browser, page, server, context}) => {
|
it('should create a worker from a service worker', async({browser, page, server, context}) => {
|
||||||
const [worker] = await Promise.all([
|
const [worker] = await Promise.all([
|
||||||
context.waitForEvent('serviceworker'),
|
context.waitForEvent('serviceworker'),
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const {FFOX, CHROMIUM, WEBKIT, CHANNEL} = require('../utils').testOptions(browserType);
|
const {FFOX, CHROMIUM, WEBKIT} = require('./utils').testOptions(browserType);
|
||||||
|
|
||||||
describe('JSCoverage', function() {
|
describe.skip(CHROMIUM)('Page.coverage missing', function() {
|
||||||
it('should work', async function({page, server}) {
|
it('should work', async function({page, server}) {
|
||||||
|
expect(page.coverage).toBe(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.skip(!CHROMIUM)('JSCoverage', function() {
|
||||||
|
it('should work', async function({browserType, page, server}) {
|
||||||
await page.coverage.startJSCoverage();
|
await page.coverage.startJSCoverage();
|
||||||
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
|
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
|
||||||
const coverage = await page.coverage.stopJSCoverage();
|
const coverage = await page.coverage.stopJSCoverage();
|
||||||
|
|
@ -88,8 +94,8 @@ describe('JSCoverage', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('CSSCoverage', function() {
|
describe.skip(!CHROMIUM)('CSSCoverage', function() {
|
||||||
it('should work', async function({page, server}) {
|
it('should work', async function({browserType, page, server}) {
|
||||||
await page.coverage.startCSSCoverage();
|
await page.coverage.startCSSCoverage();
|
||||||
await page.goto(server.PREFIX + '/csscoverage/simple.html');
|
await page.goto(server.PREFIX + '/csscoverage/simple.html');
|
||||||
const coverage = await page.coverage.stopCSSCoverage();
|
const coverage = await page.coverage.stopCSSCoverage();
|
||||||
|
|
@ -374,4 +374,19 @@ describe('launchPersistentContext()', function() {
|
||||||
await close(state);
|
await close(state);
|
||||||
expect(closed).toBe(true);
|
expect(closed).toBe(true);
|
||||||
});
|
});
|
||||||
|
it.skip(!CHROMIUM)('coverage should work', async state => {
|
||||||
|
const { page, server } = await launch(state);
|
||||||
|
await page.coverage.startJSCoverage();
|
||||||
|
await page.goto(server.PREFIX + '/jscoverage/simple.html', { waitUntil: 'load' });
|
||||||
|
const coverage = await page.coverage.stopJSCoverage();
|
||||||
|
expect(coverage.length).toBe(1);
|
||||||
|
expect(coverage[0].url).toContain('/jscoverage/simple.html');
|
||||||
|
expect(coverage[0].functions.find(f => f.functionName === 'foo').ranges[0].count).toEqual(1);
|
||||||
|
await close(state);
|
||||||
|
});
|
||||||
|
it.skip(CHROMIUM)('coverage should be missing', async state => {
|
||||||
|
const { page } = await launch(state);
|
||||||
|
expect(page.coverage).toBe(null);
|
||||||
|
await close(state);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR} = require('../utils').testOptions(browserType);
|
const {FFOX, CHROMIUM, WEBKIT, OUTPUT_DIR} = require('./utils').testOptions(browserType);
|
||||||
|
|
||||||
// Printing to pdf is currently only supported in headless
|
// Printing to pdf is currently only supported in headless chromium.
|
||||||
describe.skip(!HEADLESS)('Page.pdf', function() {
|
describe.skip(!(HEADLESS && CHROMIUM))('Page.pdf', function() {
|
||||||
it('should be able to save file', async({page, server}) => {
|
it('should be able to save file', async({page, server}) => {
|
||||||
const outputFile = path.join(OUTPUT_DIR, 'output.pdf');
|
const outputFile = path.join(OUTPUT_DIR, 'output.pdf');
|
||||||
await page.pdf({path: outputFile});
|
await page.pdf({path: outputFile});
|
||||||
|
|
@ -27,3 +27,9 @@ describe.skip(!HEADLESS)('Page.pdf', function() {
|
||||||
fs.unlinkSync(outputFile);
|
fs.unlinkSync(outputFile);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe.skip(CHROMIUM)('Page.pdf missing', function() {
|
||||||
|
it('should be able to save file', async({page, server}) => {
|
||||||
|
expect(page.pdf).toBe(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -75,6 +75,7 @@ module.exports = {
|
||||||
'./autowaiting.spec.js',
|
'./autowaiting.spec.js',
|
||||||
'./click.spec.js',
|
'./click.spec.js',
|
||||||
'./cookies.spec.js',
|
'./cookies.spec.js',
|
||||||
|
'./coverage.spec.js',
|
||||||
'./dialog.spec.js',
|
'./dialog.spec.js',
|
||||||
'./dispatchevent.spec.js',
|
'./dispatchevent.spec.js',
|
||||||
'./download.spec.js',
|
'./download.spec.js',
|
||||||
|
|
@ -90,6 +91,7 @@ module.exports = {
|
||||||
'./navigation.spec.js',
|
'./navigation.spec.js',
|
||||||
'./network.spec.js',
|
'./network.spec.js',
|
||||||
'./page.spec.js',
|
'./page.spec.js',
|
||||||
|
'./pdf.spec.js',
|
||||||
'./queryselector.spec.js',
|
'./queryselector.spec.js',
|
||||||
'./screenshot.spec.js',
|
'./screenshot.spec.js',
|
||||||
'./waittask.spec.js',
|
'./waittask.spec.js',
|
||||||
|
|
@ -105,8 +107,6 @@ module.exports = {
|
||||||
{
|
{
|
||||||
files: [
|
files: [
|
||||||
'./chromium/chromium.spec.js',
|
'./chromium/chromium.spec.js',
|
||||||
'./chromium/coverage.spec.js',
|
|
||||||
'./chromium/pdf.spec.js',
|
|
||||||
'./chromium/session.spec.js',
|
'./chromium/session.spec.js',
|
||||||
],
|
],
|
||||||
browsers: ['chromium'],
|
browsers: ['chromium'],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue