chore: align more server-side options with rpc protocol (#3506)
This touches: - noDefaultViewport; - ignoreAllDefaultArgs; - env; - validateXYZ logic that was copying objects - we do not need that anymore; - shuffles some converters closer to their usage.
This commit is contained in:
parent
7a77faf194
commit
9790ea5b5d
|
|
@ -40,12 +40,10 @@ export type BrowserOptions = {
|
||||||
proxy?: ProxySettings,
|
proxy?: ProxySettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BrowserContextOptions = types.BrowserContextOptions;
|
|
||||||
|
|
||||||
export interface Browser extends EventEmitter {
|
export interface Browser extends EventEmitter {
|
||||||
newContext(options?: BrowserContextOptions): Promise<BrowserContext>;
|
newContext(options?: types.BrowserContextOptions): Promise<BrowserContext>;
|
||||||
contexts(): BrowserContext[];
|
contexts(): BrowserContext[];
|
||||||
newPage(options?: BrowserContextOptions): Promise<Page>;
|
newPage(options?: types.BrowserContextOptions): Promise<Page>;
|
||||||
isConnected(): boolean;
|
isConnected(): boolean;
|
||||||
close(): Promise<void>;
|
close(): Promise<void>;
|
||||||
version(): string;
|
version(): string;
|
||||||
|
|
@ -62,12 +60,12 @@ export abstract class BrowserBase extends EventEmitter implements Browser {
|
||||||
this._options = options;
|
this._options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract newContext(options?: BrowserContextOptions): Promise<BrowserContext>;
|
abstract newContext(options?: types.BrowserContextOptions): Promise<BrowserContext>;
|
||||||
abstract contexts(): BrowserContext[];
|
abstract contexts(): BrowserContext[];
|
||||||
abstract isConnected(): boolean;
|
abstract isConnected(): boolean;
|
||||||
abstract version(): string;
|
abstract version(): string;
|
||||||
|
|
||||||
async newPage(options?: BrowserContextOptions): Promise<Page> {
|
async newPage(options?: types.BrowserContextOptions): Promise<Page> {
|
||||||
const context = await this.newContext(options);
|
const context = await this.newContext(options);
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
page._ownedContext = context;
|
page._ownedContext = context;
|
||||||
|
|
|
||||||
|
|
@ -228,47 +228,23 @@ export function assertBrowserContextIsNotOwned(context: BrowserContextBase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateBrowserContextOptions(options: types.BrowserContextOptions): types.BrowserContextOptions {
|
export function validateBrowserContextOptions(options: types.BrowserContextOptions) {
|
||||||
// Copy all fields manually to strip any extra junk.
|
if (options.noDefaultViewport && options.deviceScaleFactor !== undefined)
|
||||||
// Especially useful when we share context and launch options for launchPersistent.
|
|
||||||
const result: types.BrowserContextOptions = {
|
|
||||||
ignoreHTTPSErrors: options.ignoreHTTPSErrors,
|
|
||||||
bypassCSP: options.bypassCSP,
|
|
||||||
locale: options.locale,
|
|
||||||
timezoneId: options.timezoneId,
|
|
||||||
offline: options.offline,
|
|
||||||
colorScheme: options.colorScheme,
|
|
||||||
acceptDownloads: options.acceptDownloads,
|
|
||||||
viewport: options.viewport,
|
|
||||||
javaScriptEnabled: options.javaScriptEnabled,
|
|
||||||
userAgent: options.userAgent,
|
|
||||||
geolocation: options.geolocation,
|
|
||||||
permissions: options.permissions,
|
|
||||||
extraHTTPHeaders: options.extraHTTPHeaders,
|
|
||||||
httpCredentials: options.httpCredentials,
|
|
||||||
deviceScaleFactor: options.deviceScaleFactor,
|
|
||||||
isMobile: options.isMobile,
|
|
||||||
hasTouch: options.hasTouch,
|
|
||||||
};
|
|
||||||
if (result.viewport === null && result.deviceScaleFactor !== undefined)
|
|
||||||
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
||||||
if (result.viewport === null && result.isMobile !== undefined)
|
if (options.noDefaultViewport && options.isMobile !== undefined)
|
||||||
throw new Error(`"isMobile" option is not supported with null "viewport"`);
|
throw new Error(`"isMobile" option is not supported with null "viewport"`);
|
||||||
if (!result.viewport && result.viewport !== null)
|
if (!options.viewport && !options.noDefaultViewport)
|
||||||
result.viewport = { width: 1280, height: 720 };
|
options.viewport = { width: 1280, height: 720 };
|
||||||
if (result.viewport)
|
verifyGeolocation(options.geolocation);
|
||||||
result.viewport = { ...result.viewport };
|
if (options.extraHTTPHeaders)
|
||||||
if (result.geolocation)
|
options.extraHTTPHeaders = network.verifyHeaders(options.extraHTTPHeaders);
|
||||||
result.geolocation = verifyGeolocation(result.geolocation);
|
|
||||||
if (result.extraHTTPHeaders)
|
|
||||||
result.extraHTTPHeaders = network.verifyHeaders(result.extraHTTPHeaders);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyGeolocation(geolocation: types.Geolocation): types.Geolocation {
|
export function verifyGeolocation(geolocation?: types.Geolocation) {
|
||||||
const result = { ...geolocation };
|
if (!geolocation)
|
||||||
result.accuracy = result.accuracy || 0;
|
return;
|
||||||
const { longitude, latitude, accuracy } = result;
|
geolocation.accuracy = geolocation.accuracy || 0;
|
||||||
|
const { longitude, latitude, accuracy } = geolocation;
|
||||||
if (!helper.isNumber(longitude))
|
if (!helper.isNumber(longitude))
|
||||||
throw new Error(`geolocation.longitude: expected number, got ${typeof longitude}`);
|
throw new Error(`geolocation.longitude: expected number, got ${typeof longitude}`);
|
||||||
if (longitude < -180 || longitude > 180)
|
if (longitude < -180 || longitude > 180)
|
||||||
|
|
@ -281,7 +257,6 @@ export function verifyGeolocation(geolocation: types.Geolocation): types.Geoloca
|
||||||
throw new Error(`geolocation.accuracy: expected number, got ${typeof accuracy}`);
|
throw new Error(`geolocation.accuracy: expected number, got ${typeof accuracy}`);
|
||||||
if (accuracy < 0)
|
if (accuracy < 0)
|
||||||
throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);
|
throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyProxySettings(proxy: types.ProxySettings): types.ProxySettings {
|
export function verifyProxySettings(proxy: types.ProxySettings): types.ProxySettings {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserBase, BrowserOptions, BrowserContextOptions } from '../browser';
|
import { BrowserBase, BrowserOptions } from '../browser';
|
||||||
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
||||||
import { Events as CommonEvents } from '../events';
|
import { Events as CommonEvents } from '../events';
|
||||||
import { assert } from '../helper';
|
import { assert } from '../helper';
|
||||||
|
|
@ -99,8 +99,8 @@ export class CRBrowser extends BrowserBase {
|
||||||
this._session.on('Target.detachedFromTarget', this._onDetachedFromTarget.bind(this));
|
this._session.on('Target.detachedFromTarget', this._onDetachedFromTarget.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async newContext(options: BrowserContextOptions = {}): Promise<BrowserContext> {
|
async newContext(options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||||
options = validateBrowserContextOptions(options);
|
validateBrowserContextOptions(options);
|
||||||
const { browserContextId } = await this._session.send('Target.createBrowserContext', { disposeOnDetach: true });
|
const { browserContextId } = await this._session.send('Target.createBrowserContext', { disposeOnDetach: true });
|
||||||
const context = new CRBrowserContext(this, browserContextId, options);
|
const context = new CRBrowserContext(this, browserContextId, options);
|
||||||
await context._initialize();
|
await context._initialize();
|
||||||
|
|
@ -381,8 +381,7 @@ export class CRBrowserContext extends BrowserContextBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
||||||
if (geolocation)
|
verifyGeolocation(geolocation);
|
||||||
geolocation = verifyGeolocation(geolocation);
|
|
||||||
this._options.geolocation = geolocation;
|
this._options.geolocation = geolocation;
|
||||||
for (const page of this.pages())
|
for (const page of this.pages())
|
||||||
await (page._delegate as CRPage).updateGeolocation();
|
await (page._delegate as CRPage).updateGeolocation();
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ export class CRPage implements PageDelegate {
|
||||||
this._mainFrameSession = new FrameSession(this, client, targetId, null);
|
this._mainFrameSession = new FrameSession(this, client, targetId, null);
|
||||||
this._sessions.set(targetId, this._mainFrameSession);
|
this._sessions.set(targetId, this._mainFrameSession);
|
||||||
client.once(CRSessionEvents.Disconnected, () => this._page._didDisconnect());
|
client.once(CRSessionEvents.Disconnected, () => this._page._didDisconnect());
|
||||||
if (opener && browserContext._options.viewport !== null) {
|
if (opener && !browserContext._options.noDefaultViewport) {
|
||||||
const features = opener._nextWindowOpenPopupFeatures.shift() || [];
|
const features = opener._nextWindowOpenPopupFeatures.shift() || [];
|
||||||
const viewportSize = helper.getViewportSizeFromWindowFeatures(features);
|
const viewportSize = helper.getViewportSizeFromWindowFeatures(features);
|
||||||
if (viewportSize)
|
if (viewportSize)
|
||||||
|
|
@ -371,7 +371,7 @@ class FrameSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _initialize(hasUIWindow: boolean) {
|
async _initialize(hasUIWindow: boolean) {
|
||||||
if (hasUIWindow && this._crPage._browserContext._options.viewport !== null) {
|
if (hasUIWindow && !this._crPage._browserContext._options.noDefaultViewport) {
|
||||||
const { windowId } = await this._client.send('Browser.getWindowForTarget');
|
const { windowId } = await this._client.send('Browser.getWindowForTarget');
|
||||||
this._windowId = windowId;
|
this._windowId = windowId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,19 +105,3 @@ export function headersArrayToObject(headers: types.HeadersArray): types.Headers
|
||||||
result[name] = value;
|
result[name] = value;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function envObjectToArray(env: types.Env): types.EnvArray {
|
|
||||||
const result: types.EnvArray = [];
|
|
||||||
for (const name in env) {
|
|
||||||
if (!Object.is(env[name], undefined))
|
|
||||||
result.push({ name, value: String(env[name]) });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function envArrayToObject(env: types.EnvArray): types.Env {
|
|
||||||
const result: types.Env = {};
|
|
||||||
for (const { name, value } of env)
|
|
||||||
result[name] = value;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserBase, BrowserOptions, BrowserContextOptions } from '../browser';
|
import { BrowserBase, BrowserOptions } from '../browser';
|
||||||
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
import { assert, helper, RegisteredListener } from '../helper';
|
import { assert, helper, RegisteredListener } from '../helper';
|
||||||
|
|
@ -91,8 +91,8 @@ export class FFBrowser extends BrowserBase {
|
||||||
return !this._connection._closed;
|
return !this._connection._closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
async newContext(options: BrowserContextOptions = {}): Promise<BrowserContext> {
|
async newContext(options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||||
options = validateBrowserContextOptions(options);
|
validateBrowserContextOptions(options);
|
||||||
if (options.isMobile)
|
if (options.isMobile)
|
||||||
throw new Error('options.isMobile is not supported in Firefox');
|
throw new Error('options.isMobile is not supported in Firefox');
|
||||||
const { browserContextId } = await this._connection.send('Browser.createBrowserContext', { removeOnDetach: true });
|
const { browserContextId } = await this._connection.send('Browser.createBrowserContext', { removeOnDetach: true });
|
||||||
|
|
@ -289,8 +289,7 @@ export class FFBrowserContext extends BrowserContextBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
||||||
if (geolocation)
|
verifyGeolocation(geolocation);
|
||||||
geolocation = verifyGeolocation(geolocation);
|
|
||||||
this._options.geolocation = geolocation;
|
this._options.geolocation = geolocation;
|
||||||
await this._browser._connection.send('Browser.setGeolocationOverride', { browserContextId: this._browserContextId || undefined, geolocation: geolocation || null });
|
await this._browser._connection.send('Browser.setGeolocationOverride', { browserContextId: this._browserContextId || undefined, geolocation: geolocation || null });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ export class Page extends EventEmitter {
|
||||||
this._crashedPromise = new Promise(f => this._crashedCallback = f);
|
this._crashedPromise = new Promise(f => this._crashedCallback = f);
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
this._state = {
|
this._state = {
|
||||||
viewportSize: browserContext._options.viewport ? { ...browserContext._options.viewport } : null,
|
viewportSize: browserContext._options.viewport || null,
|
||||||
mediaType: null,
|
mediaType: null,
|
||||||
colorScheme: null,
|
colorScheme: null,
|
||||||
extraHTTPHeaders: null,
|
extraHTTPHeaders: null,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import { BrowserDispatcher } from './server/browserDispatcher';
|
||||||
import { BrowserContextDispatcher } from './server/browserContextDispatcher';
|
import { BrowserContextDispatcher } from './server/browserContextDispatcher';
|
||||||
import { BrowserNewContextParams, BrowserContextChannel } from './channels';
|
import { BrowserNewContextParams, BrowserContextChannel } from './channels';
|
||||||
import { BrowserServerLauncher, BrowserServer } from './client/browserType';
|
import { BrowserServerLauncher, BrowserServer } from './client/browserType';
|
||||||
|
import { envObjectToArray } from './client/clientHelper';
|
||||||
|
|
||||||
export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
||||||
private _browserType: BrowserTypeBase;
|
private _browserType: BrowserTypeBase;
|
||||||
|
|
@ -36,7 +37,12 @@ export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchServer(options: LaunchServerOptions = {}): Promise<BrowserServerImpl> {
|
async launchServer(options: LaunchServerOptions = {}): Promise<BrowserServerImpl> {
|
||||||
const browser = await this._browserType.launch(options);
|
const browser = await this._browserType.launch({
|
||||||
|
...options,
|
||||||
|
ignoreDefaultArgs: Array.isArray(options.ignoreDefaultArgs) ? options.ignoreDefaultArgs : undefined,
|
||||||
|
ignoreAllDefaultArgs: !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs),
|
||||||
|
env: options.env ? envObjectToArray(options.env) : undefined,
|
||||||
|
});
|
||||||
return new BrowserServerImpl(this._browserType, browser as BrowserBase, options.port);
|
return new BrowserServerImpl(this._browserType, browser as BrowserBase, options.port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { BrowserTypeChannel, BrowserTypeInitializer, BrowserTypeLaunchParams, Br
|
||||||
import { Browser } from './browser';
|
import { Browser } from './browser';
|
||||||
import { BrowserContext } from './browserContext';
|
import { BrowserContext } from './browserContext';
|
||||||
import { ChannelOwner } from './channelOwner';
|
import { ChannelOwner } from './channelOwner';
|
||||||
import { headersObjectToArray, envObjectToArray } from '../../converters';
|
import { headersObjectToArray } from '../../converters';
|
||||||
import { assert, helper } from '../../helper';
|
import { assert, helper } from '../../helper';
|
||||||
import { LaunchOptions, LaunchServerOptions, ConnectOptions, LaunchPersistentContextOptions } from './types';
|
import { LaunchOptions, LaunchServerOptions, ConnectOptions, LaunchPersistentContextOptions } from './types';
|
||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
|
|
@ -27,6 +27,7 @@ import { serializeError } from '../serializers';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { TimeoutSettings } from '../../timeoutSettings';
|
import { TimeoutSettings } from '../../timeoutSettings';
|
||||||
import { ChildProcess } from 'child_process';
|
import { ChildProcess } from 'child_process';
|
||||||
|
import { envObjectToArray } from './clientHelper';
|
||||||
|
|
||||||
export interface BrowserServerLauncher {
|
export interface BrowserServerLauncher {
|
||||||
launchServer(options?: LaunchServerOptions): Promise<BrowserServer>;
|
launchServer(options?: LaunchServerOptions): Promise<BrowserServer>;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { isUnderTest as commonIsUnderTest } from '../../helper';
|
import { isUnderTest as commonIsUnderTest } from '../../helper';
|
||||||
|
import * as types from './types';
|
||||||
|
|
||||||
const deprecatedHits = new Set();
|
const deprecatedHits = new Set();
|
||||||
export function deprecate(methodName: string, message: string) {
|
export function deprecate(methodName: string, message: string) {
|
||||||
|
|
@ -28,3 +29,12 @@ export function deprecate(methodName: string, message: string) {
|
||||||
export function isUnderTest() {
|
export function isUnderTest() {
|
||||||
return commonIsUnderTest();
|
return commonIsUnderTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function envObjectToArray(env: types.Env): { name: string, value: string }[] {
|
||||||
|
const result: { name: string, value: string }[] = [];
|
||||||
|
for (const name in env) {
|
||||||
|
if (!Object.is(env[name], undefined))
|
||||||
|
result.push({ name, value: String(env[name]) });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import { serializeArgument, FuncOn, parseResult, SmartHandle, JSHandle } from '.
|
||||||
import { TimeoutSettings } from '../../timeoutSettings';
|
import { TimeoutSettings } from '../../timeoutSettings';
|
||||||
import { Waiter } from './waiter';
|
import { Waiter } from './waiter';
|
||||||
import { Events } from './events';
|
import { Events } from './events';
|
||||||
import { envObjectToArray } from '../../converters';
|
|
||||||
import { WaitForEventOptions, Env, LoggerSink } from './types';
|
import { WaitForEventOptions, Env, LoggerSink } from './types';
|
||||||
|
import { envObjectToArray } from './clientHelper';
|
||||||
|
|
||||||
type ElectronOptions = Omit<ElectronLaunchOptions, 'env'> & {
|
type ElectronOptions = Omit<ElectronLaunchOptions, 'env'> & {
|
||||||
env?: Env,
|
env?: Env,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ export class BrowserDispatcher extends Dispatcher<Browser, BrowserInitializer> i
|
||||||
async newContext(params: BrowserNewContextParams): Promise<{ context: BrowserContextChannel }> {
|
async newContext(params: BrowserNewContextParams): Promise<{ context: BrowserContextChannel }> {
|
||||||
const options = {
|
const options = {
|
||||||
...params,
|
...params,
|
||||||
viewport: params.viewport || (params.noDefaultViewport ? null : undefined),
|
|
||||||
extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders) : undefined,
|
extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders) : undefined,
|
||||||
};
|
};
|
||||||
return { context: new BrowserContextDispatcher(this._scope, await this._object.newContext(options) as BrowserContextBase) };
|
return { context: new BrowserContextDispatcher(this._scope, await this._object.newContext(options) as BrowserContextBase) };
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import { BrowserChannel, BrowserTypeChannel, BrowserContextChannel, BrowserTypeI
|
||||||
import { Dispatcher, DispatcherScope } from './dispatcher';
|
import { Dispatcher, DispatcherScope } from './dispatcher';
|
||||||
import { BrowserContextBase } from '../../browserContext';
|
import { BrowserContextBase } from '../../browserContext';
|
||||||
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
import { BrowserContextDispatcher } from './browserContextDispatcher';
|
||||||
import { headersArrayToObject, envArrayToObject } from '../../converters';
|
import { headersArrayToObject } from '../../converters';
|
||||||
|
|
||||||
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeInitializer> implements BrowserTypeChannel {
|
export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeInitializer> implements BrowserTypeChannel {
|
||||||
constructor(scope: DispatcherScope, browserType: BrowserTypeBase) {
|
constructor(scope: DispatcherScope, browserType: BrowserTypeBase) {
|
||||||
|
|
@ -32,21 +32,13 @@ export class BrowserTypeDispatcher extends Dispatcher<BrowserType, BrowserTypeIn
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(params: BrowserTypeLaunchParams): Promise<{ browser: BrowserChannel }> {
|
async launch(params: BrowserTypeLaunchParams): Promise<{ browser: BrowserChannel }> {
|
||||||
const options = {
|
const browser = await this._object.launch(params);
|
||||||
...params,
|
|
||||||
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
|
||||||
env: params.env ? envArrayToObject(params.env) : undefined,
|
|
||||||
};
|
|
||||||
const browser = await this._object.launch(options);
|
|
||||||
return { browser: new BrowserDispatcher(this._scope, browser as BrowserBase) };
|
return { browser: new BrowserDispatcher(this._scope, browser as BrowserBase) };
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchPersistentContext(params: BrowserTypeLaunchPersistentContextParams): Promise<{ context: BrowserContextChannel }> {
|
async launchPersistentContext(params: BrowserTypeLaunchPersistentContextParams): Promise<{ context: BrowserContextChannel }> {
|
||||||
const options = {
|
const options = {
|
||||||
...params,
|
...params,
|
||||||
viewport: params.viewport || (params.noDefaultViewport ? null : undefined),
|
|
||||||
ignoreDefaultArgs: params.ignoreAllDefaultArgs ? true : params.ignoreDefaultArgs,
|
|
||||||
env: params.env ? envArrayToObject(params.env) : undefined,
|
|
||||||
extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders) : undefined,
|
extraHTTPHeaders: params.extraHTTPHeaders ? headersArrayToObject(params.extraHTTPHeaders) : undefined,
|
||||||
};
|
};
|
||||||
const browserContext = await this._object.launchPersistentContext(params.userDataDir, options);
|
const browserContext = await this._object.launchPersistentContext(params.userDataDir, options);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import { BrowserContextBase } from '../../browserContext';
|
||||||
import { PageDispatcher } from './pageDispatcher';
|
import { PageDispatcher } from './pageDispatcher';
|
||||||
import { parseArgument, serializeResult } from './jsHandleDispatcher';
|
import { parseArgument, serializeResult } from './jsHandleDispatcher';
|
||||||
import { createHandle } from './elementHandlerDispatcher';
|
import { createHandle } from './elementHandlerDispatcher';
|
||||||
import { envArrayToObject } from '../../converters';
|
|
||||||
|
|
||||||
export class ElectronDispatcher extends Dispatcher<Electron, ElectronInitializer> implements ElectronChannel {
|
export class ElectronDispatcher extends Dispatcher<Electron, ElectronInitializer> implements ElectronChannel {
|
||||||
constructor(scope: DispatcherScope, electron: Electron) {
|
constructor(scope: DispatcherScope, electron: Electron) {
|
||||||
|
|
@ -30,11 +29,7 @@ export class ElectronDispatcher extends Dispatcher<Electron, ElectronInitializer
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(params: ElectronLaunchParams): Promise<{ electronApplication: ElectronApplicationChannel }> {
|
async launch(params: ElectronLaunchParams): Promise<{ electronApplication: ElectronApplicationChannel }> {
|
||||||
const options = {
|
const electronApplication = await this._object.launch(params.executablePath, params);
|
||||||
...params,
|
|
||||||
env: params.env ? envArrayToObject(params.env) : undefined,
|
|
||||||
};
|
|
||||||
const electronApplication = await this._object.launch(params.executablePath, options);
|
|
||||||
return { electronApplication: new ElectronApplicationDispatcher(this._scope, electronApplication) };
|
return { electronApplication: new ElectronApplicationDispatcher(this._scope, electronApplication) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,24 +23,18 @@ import * as browserPaths from '../install/browserPaths';
|
||||||
import { ConnectionTransport, WebSocketTransport } from '../transport';
|
import { ConnectionTransport, WebSocketTransport } from '../transport';
|
||||||
import { BrowserBase, BrowserOptions, Browser, BrowserProcess } from '../browser';
|
import { BrowserBase, BrowserOptions, Browser, BrowserProcess } from '../browser';
|
||||||
import { assert, helper } from '../helper';
|
import { assert, helper } from '../helper';
|
||||||
import { launchProcess, Env, waitForLine } from './processLauncher';
|
import { launchProcess, Env, waitForLine, envArrayToObject } from './processLauncher';
|
||||||
import { PipeTransport } from './pipeTransport';
|
import { PipeTransport } from './pipeTransport';
|
||||||
import { Progress, runAbortableTask } from '../progress';
|
import { Progress, runAbortableTask } from '../progress';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { TimeoutSettings } from '../timeoutSettings';
|
import { TimeoutSettings } from '../timeoutSettings';
|
||||||
import { validateHostRequirements } from './validateDependencies';
|
import { validateHostRequirements } from './validateDependencies';
|
||||||
|
|
||||||
type FirefoxPrefsOptions = { firefoxUserPrefs?: { [key: string]: string | number | boolean } };
|
|
||||||
|
|
||||||
export type LaunchNonPersistentOptions = types.LaunchOptions & FirefoxPrefsOptions;
|
|
||||||
type LaunchPersistentOptions = types.LaunchOptions & types.BrowserContextOptions;
|
|
||||||
type LaunchServerOptions = types.LaunchServerOptions & FirefoxPrefsOptions;
|
|
||||||
|
|
||||||
export interface BrowserType {
|
export interface BrowserType {
|
||||||
executablePath(): string;
|
executablePath(): string;
|
||||||
name(): string;
|
name(): string;
|
||||||
launch(options?: LaunchNonPersistentOptions): Promise<Browser>;
|
launch(options?: types.LaunchOptions): Promise<Browser>;
|
||||||
launchPersistentContext(userDataDir: string, options?: LaunchPersistentOptions): Promise<BrowserContext>;
|
launchPersistentContext(userDataDir: string, options?: types.LaunchPersistentOptions): Promise<BrowserContext>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mkdirAsync = util.promisify(fs.mkdir);
|
const mkdirAsync = util.promisify(fs.mkdir);
|
||||||
|
|
@ -76,7 +70,7 @@ export abstract class BrowserTypeBase implements BrowserType {
|
||||||
return this._name;
|
return this._name;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launch(options: LaunchNonPersistentOptions = {}): Promise<Browser> {
|
async launch(options: types.LaunchOptions = {}): Promise<Browser> {
|
||||||
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
assert(!(options as any).userDataDir, 'userDataDir option is not supported in `browserType.launch`. Use `browserType.launchPersistentContext` instead');
|
||||||
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
||||||
options = validateLaunchOptions(options);
|
options = validateLaunchOptions(options);
|
||||||
|
|
@ -84,10 +78,11 @@ export abstract class BrowserTypeBase implements BrowserType {
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchPersistentContext(userDataDir: string, options: LaunchPersistentOptions = {}): Promise<BrowserContext> {
|
async launchPersistentContext(userDataDir: string, options: types.LaunchPersistentOptions = {}): Promise<BrowserContext> {
|
||||||
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
assert(!(options as any).port, 'Cannot specify a port without launching as a server.');
|
||||||
options = validateLaunchOptions(options);
|
options = validateLaunchOptions(options);
|
||||||
const persistent = validateBrowserContextOptions(options);
|
const persistent: types.BrowserContextOptions = options;
|
||||||
|
validateBrowserContextOptions(persistent);
|
||||||
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, persistent, userDataDir), TimeoutSettings.timeout(options), 'browser').catch(e => { throw this._rewriteStartupError(e); });
|
const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, persistent, userDataDir), TimeoutSettings.timeout(options), 'browser').catch(e => { throw this._rewriteStartupError(e); });
|
||||||
return browser._defaultContext!;
|
return browser._defaultContext!;
|
||||||
}
|
}
|
||||||
|
|
@ -109,23 +104,24 @@ export abstract class BrowserTypeBase implements BrowserType {
|
||||||
copyTestHooks(options, browserOptions);
|
copyTestHooks(options, browserOptions);
|
||||||
const browser = await this._connectToTransport(transport, browserOptions);
|
const browser = await this._connectToTransport(transport, browserOptions);
|
||||||
// We assume no control when using custom arguments, and do not prepare the default context in that case.
|
// We assume no control when using custom arguments, and do not prepare the default context in that case.
|
||||||
const hasCustomArguments = !!options.ignoreDefaultArgs && !Array.isArray(options.ignoreDefaultArgs);
|
if (persistent && !options.ignoreAllDefaultArgs)
|
||||||
if (persistent && !hasCustomArguments)
|
|
||||||
await browser._defaultContext!._loadDefaultContext(progress);
|
await browser._defaultContext!._loadDefaultContext(progress);
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _launchProcess(progress: Progress, options: LaunchServerOptions, isPersistent: boolean, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, downloadsPath: string, transport: ConnectionTransport }> {
|
private async _launchProcess(progress: Progress, options: types.LaunchOptions, isPersistent: boolean, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, downloadsPath: string, transport: ConnectionTransport }> {
|
||||||
const {
|
const {
|
||||||
ignoreDefaultArgs = false,
|
ignoreDefaultArgs,
|
||||||
|
ignoreAllDefaultArgs,
|
||||||
args = [],
|
args = [],
|
||||||
executablePath = null,
|
executablePath = null,
|
||||||
env = process.env,
|
|
||||||
handleSIGINT = true,
|
handleSIGINT = true,
|
||||||
handleSIGTERM = true,
|
handleSIGTERM = true,
|
||||||
handleSIGHUP = true,
|
handleSIGHUP = true,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
const env = options.env ? envArrayToObject(options.env) : process.env;
|
||||||
|
|
||||||
const tempDirectories = [];
|
const tempDirectories = [];
|
||||||
let downloadsPath: string;
|
let downloadsPath: string;
|
||||||
if (options.downloadsPath) {
|
if (options.downloadsPath) {
|
||||||
|
|
@ -142,12 +138,12 @@ export abstract class BrowserTypeBase implements BrowserType {
|
||||||
}
|
}
|
||||||
|
|
||||||
const browserArguments = [];
|
const browserArguments = [];
|
||||||
if (!ignoreDefaultArgs)
|
if (ignoreAllDefaultArgs)
|
||||||
browserArguments.push(...this._defaultArgs(options, isPersistent, userDataDir));
|
browserArguments.push(...args);
|
||||||
else if (Array.isArray(ignoreDefaultArgs))
|
else if (ignoreDefaultArgs)
|
||||||
browserArguments.push(...this._defaultArgs(options, isPersistent, userDataDir).filter(arg => ignoreDefaultArgs.indexOf(arg) === -1));
|
browserArguments.push(...this._defaultArgs(options, isPersistent, userDataDir).filter(arg => ignoreDefaultArgs.indexOf(arg) === -1));
|
||||||
else
|
else
|
||||||
browserArguments.push(...args);
|
browserArguments.push(...this._defaultArgs(options, isPersistent, userDataDir));
|
||||||
|
|
||||||
const executable = executablePath || this.executablePath();
|
const executable = executablePath || this.executablePath();
|
||||||
if (!executable)
|
if (!executable)
|
||||||
|
|
@ -211,7 +207,7 @@ export abstract class BrowserTypeBase implements BrowserType {
|
||||||
return { browserProcess, downloadsPath, transport };
|
return { browserProcess, downloadsPath, transport };
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract _defaultArgs(options: types.LaunchOptionsBase, isPersistent: boolean, userDataDir: string): string[];
|
abstract _defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[];
|
||||||
abstract _connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise<BrowserBase>;
|
abstract _connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise<BrowserBase>;
|
||||||
abstract _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env;
|
abstract _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env;
|
||||||
abstract _amendArguments(browserArguments: string[]): string[];
|
abstract _amendArguments(browserArguments: string[]): string[];
|
||||||
|
|
@ -226,7 +222,7 @@ function copyTestHooks(from: object, to: object) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateLaunchOptions<Options extends types.LaunchOptionsBase>(options: Options): Options {
|
function validateLaunchOptions<Options extends types.LaunchOptions>(options: Options): Options {
|
||||||
const { devtools = false, headless = !helper.isDebugMode() && !devtools } = options;
|
const { devtools = false, headless = !helper.isDebugMode() && !devtools } = options;
|
||||||
return { ...options, devtools, headless };
|
return { ...options, devtools, headless };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { ConnectionTransport, ProtocolRequest } from '../transport';
|
||||||
import { BrowserDescriptor } from '../install/browserPaths';
|
import { BrowserDescriptor } from '../install/browserPaths';
|
||||||
import { CRDevTools } from '../chromium/crDevTools';
|
import { CRDevTools } from '../chromium/crDevTools';
|
||||||
import { BrowserOptions } from '../browser';
|
import { BrowserOptions } from '../browser';
|
||||||
import { LaunchOptionsBase } from '../types';
|
import * as types from '../types';
|
||||||
|
|
||||||
export class Chromium extends BrowserTypeBase {
|
export class Chromium extends BrowserTypeBase {
|
||||||
private _devtools: CRDevTools | undefined;
|
private _devtools: CRDevTools | undefined;
|
||||||
|
|
@ -101,7 +101,7 @@ export class Chromium extends BrowserTypeBase {
|
||||||
transport.send(message);
|
transport.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaultArgs(options: LaunchOptionsBase, isPersistent: boolean, userDataDir: string): string[] {
|
_defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] {
|
||||||
const { args = [], proxy } = options;
|
const { args = [], proxy } = options;
|
||||||
const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir'));
|
const userDataDirArg = args.find(arg => arg.startsWith('--user-data-dir'));
|
||||||
if (userDataDirArg)
|
if (userDataDirArg)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import { Page } from '../page';
|
||||||
import { TimeoutSettings } from '../timeoutSettings';
|
import { TimeoutSettings } from '../timeoutSettings';
|
||||||
import { WebSocketTransport } from '../transport';
|
import { WebSocketTransport } from '../transport';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { launchProcess, waitForLine } from './processLauncher';
|
import { launchProcess, waitForLine, envArrayToObject } from './processLauncher';
|
||||||
import { BrowserContext } from '../browserContext';
|
import { BrowserContext } from '../browserContext';
|
||||||
import type {BrowserWindow} from 'electron';
|
import type {BrowserWindow} from 'electron';
|
||||||
import { runAbortableTask, ProgressController } from '../progress';
|
import { runAbortableTask, ProgressController } from '../progress';
|
||||||
|
|
@ -35,7 +35,7 @@ import { BrowserProcess } from '../browser';
|
||||||
export type ElectronLaunchOptionsBase = {
|
export type ElectronLaunchOptionsBase = {
|
||||||
args?: string[],
|
args?: string[],
|
||||||
cwd?: string,
|
cwd?: string,
|
||||||
env?: types.Env,
|
env?: types.EnvArray,
|
||||||
handleSIGINT?: boolean,
|
handleSIGINT?: boolean,
|
||||||
handleSIGTERM?: boolean,
|
handleSIGTERM?: boolean,
|
||||||
handleSIGHUP?: boolean,
|
handleSIGHUP?: boolean,
|
||||||
|
|
@ -145,7 +145,6 @@ export class Electron {
|
||||||
async launch(executablePath: string, options: ElectronLaunchOptionsBase = {}): Promise<ElectronApplication> {
|
async launch(executablePath: string, options: ElectronLaunchOptionsBase = {}): Promise<ElectronApplication> {
|
||||||
const {
|
const {
|
||||||
args = [],
|
args = [],
|
||||||
env = process.env,
|
|
||||||
handleSIGINT = true,
|
handleSIGINT = true,
|
||||||
handleSIGTERM = true,
|
handleSIGTERM = true,
|
||||||
handleSIGHUP = true,
|
handleSIGHUP = true,
|
||||||
|
|
@ -156,7 +155,7 @@ export class Electron {
|
||||||
const { launchedProcess, gracefullyClose, kill } = await launchProcess({
|
const { launchedProcess, gracefullyClose, kill } = await launchProcess({
|
||||||
executablePath,
|
executablePath,
|
||||||
args: electronArguments,
|
args: electronArguments,
|
||||||
env,
|
env: options.env ? envArrayToObject(options.env) : process.env,
|
||||||
handleSIGINT,
|
handleSIGINT,
|
||||||
handleSIGTERM,
|
handleSIGTERM,
|
||||||
handleSIGHUP,
|
handleSIGHUP,
|
||||||
|
|
@ -180,7 +179,7 @@ export class Electron {
|
||||||
close: gracefullyClose,
|
close: gracefullyClose,
|
||||||
kill
|
kill
|
||||||
};
|
};
|
||||||
const browser = await CRBrowser.connect(chromeTransport, { name: 'electron', headful: true, persistent: { viewport: null }, browserProcess });
|
const browser = await CRBrowser.connect(chromeTransport, { name: 'electron', headful: true, persistent: { noDefaultViewport: true }, browserProcess });
|
||||||
app = new ElectronApplication(browser, nodeConnection);
|
app = new ElectronApplication(browser, nodeConnection);
|
||||||
await app._init();
|
await app._init();
|
||||||
return app;
|
return app;
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@ import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { FFBrowser } from '../firefox/ffBrowser';
|
import { FFBrowser } from '../firefox/ffBrowser';
|
||||||
import { kBrowserCloseMessageId } from '../firefox/ffConnection';
|
import { kBrowserCloseMessageId } from '../firefox/ffConnection';
|
||||||
import { BrowserTypeBase, LaunchNonPersistentOptions } from './browserType';
|
import { BrowserTypeBase } from './browserType';
|
||||||
import { Env } from './processLauncher';
|
import { Env } from './processLauncher';
|
||||||
import { ConnectionTransport } from '../transport';
|
import { ConnectionTransport } from '../transport';
|
||||||
import { BrowserOptions } from '../browser';
|
import { BrowserOptions } from '../browser';
|
||||||
import { BrowserDescriptor } from '../install/browserPaths';
|
import { BrowserDescriptor } from '../install/browserPaths';
|
||||||
|
import * as types from '../types';
|
||||||
|
|
||||||
export class Firefox extends BrowserTypeBase {
|
export class Firefox extends BrowserTypeBase {
|
||||||
constructor(packagePath: string, browser: BrowserDescriptor) {
|
constructor(packagePath: string, browser: BrowserDescriptor) {
|
||||||
|
|
@ -57,7 +58,7 @@ export class Firefox extends BrowserTypeBase {
|
||||||
transport.send(message);
|
transport.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaultArgs(options: LaunchNonPersistentOptions, isPersistent: boolean, userDataDir: string): string[] {
|
_defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] {
|
||||||
const { args = [], devtools, headless } = options;
|
const { args = [], devtools, headless } = options;
|
||||||
if (devtools)
|
if (devtools)
|
||||||
console.warn('devtools parameter is not supported as a launch argument in Firefox. You can launch the devtools window manually.');
|
console.warn('devtools parameter is not supported as a launch argument in Firefox. You can launch the devtools window manually.');
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import * as removeFolder from 'rimraf';
|
||||||
import * as stream from 'stream';
|
import * as stream from 'stream';
|
||||||
import { helper, isUnderTest } from '../helper';
|
import { helper, isUnderTest } from '../helper';
|
||||||
import { Progress } from '../progress';
|
import { Progress } from '../progress';
|
||||||
|
import * as types from '../types';
|
||||||
|
|
||||||
export type Env = {[key: string]: string | number | boolean | undefined};
|
export type Env = {[key: string]: string | number | boolean | undefined};
|
||||||
|
|
||||||
|
|
@ -204,3 +205,10 @@ export function waitForLine(progress: Progress, process: childProcess.ChildProce
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function envArrayToObject(env: types.EnvArray): Env {
|
||||||
|
const result: Env = {};
|
||||||
|
for (const { name, value } of env)
|
||||||
|
result[name] = value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { BrowserTypeBase } from './browserType';
|
||||||
import { ConnectionTransport } from '../transport';
|
import { ConnectionTransport } from '../transport';
|
||||||
import { BrowserOptions } from '../browser';
|
import { BrowserOptions } from '../browser';
|
||||||
import { BrowserDescriptor } from '../install/browserPaths';
|
import { BrowserDescriptor } from '../install/browserPaths';
|
||||||
import { LaunchOptionsBase } from '../types';
|
import * as types from '../types';
|
||||||
|
|
||||||
export class WebKit extends BrowserTypeBase {
|
export class WebKit extends BrowserTypeBase {
|
||||||
constructor(packagePath: string, browser: BrowserDescriptor) {
|
constructor(packagePath: string, browser: BrowserDescriptor) {
|
||||||
|
|
@ -50,7 +50,7 @@ export class WebKit extends BrowserTypeBase {
|
||||||
transport.send({method: 'Playwright.close', params: {}, id: kBrowserCloseMessageId});
|
transport.send({method: 'Playwright.close', params: {}, id: kBrowserCloseMessageId});
|
||||||
}
|
}
|
||||||
|
|
||||||
_defaultArgs(options: LaunchOptionsBase, isPersistent: boolean, userDataDir: string): string[] {
|
_defaultArgs(options: types.LaunchOptions, isPersistent: boolean, userDataDir: string): string[] {
|
||||||
const { args = [], proxy, devtools, headless } = options;
|
const { args = [], proxy, devtools, headless } = options;
|
||||||
if (devtools)
|
if (devtools)
|
||||||
console.warn('devtools parameter as a launch argument in WebKit is not supported. Also starting Web Inspector manually will terminate the execution in WebKit.');
|
console.warn('devtools parameter as a launch argument in WebKit is not supported. Also starting Web Inspector manually will terminate the execution in WebKit.');
|
||||||
|
|
|
||||||
19
src/types.ts
19
src/types.ts
|
|
@ -265,7 +265,8 @@ export type SetNetworkCookieParam = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BrowserContextOptions = {
|
export type BrowserContextOptions = {
|
||||||
viewport?: Size | null,
|
viewport?: Size,
|
||||||
|
noDefaultViewport?: boolean,
|
||||||
ignoreHTTPSErrors?: boolean,
|
ignoreHTTPSErrors?: boolean,
|
||||||
javaScriptEnabled?: boolean,
|
javaScriptEnabled?: boolean,
|
||||||
bypassCSP?: boolean,
|
bypassCSP?: boolean,
|
||||||
|
|
@ -284,27 +285,29 @@ export type BrowserContextOptions = {
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Env = {[key: string]: string | number | boolean | undefined};
|
|
||||||
export type EnvArray = { name: string, value: string }[];
|
export type EnvArray = { name: string, value: string }[];
|
||||||
|
|
||||||
export type LaunchOptionsBase = {
|
type LaunchOptionsBase = {
|
||||||
executablePath?: string,
|
executablePath?: string,
|
||||||
args?: string[],
|
args?: string[],
|
||||||
ignoreDefaultArgs?: boolean | string[],
|
ignoreDefaultArgs?: string[],
|
||||||
|
ignoreAllDefaultArgs?: boolean,
|
||||||
handleSIGINT?: boolean,
|
handleSIGINT?: boolean,
|
||||||
handleSIGTERM?: boolean,
|
handleSIGTERM?: boolean,
|
||||||
handleSIGHUP?: boolean,
|
handleSIGHUP?: boolean,
|
||||||
timeout?: number,
|
timeout?: number,
|
||||||
env?: Env,
|
env?: EnvArray,
|
||||||
headless?: boolean,
|
headless?: boolean,
|
||||||
devtools?: boolean,
|
devtools?: boolean,
|
||||||
proxy?: ProxySettings,
|
proxy?: ProxySettings,
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
|
slowMo?: number,
|
||||||
};
|
};
|
||||||
|
export type LaunchOptions = LaunchOptionsBase & {
|
||||||
export type LaunchOptions = LaunchOptionsBase & { slowMo?: number };
|
firefoxUserPrefs?: { [key: string]: string | number | boolean },
|
||||||
export type LaunchServerOptions = LaunchOptionsBase & { port?: number };
|
};
|
||||||
|
export type LaunchPersistentOptions = LaunchOptionsBase & BrowserContextOptions;
|
||||||
|
|
||||||
export type SerializedAXNode = {
|
export type SerializedAXNode = {
|
||||||
role: string,
|
role: string,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { BrowserBase, BrowserOptions, BrowserContextOptions } from '../browser';
|
import { BrowserBase, BrowserOptions } from '../browser';
|
||||||
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
import { assertBrowserContextIsNotOwned, BrowserContext, BrowserContextBase, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
|
||||||
import { Events } from '../events';
|
import { Events } from '../events';
|
||||||
import { helper, RegisteredListener, assert } from '../helper';
|
import { helper, RegisteredListener, assert } from '../helper';
|
||||||
|
|
@ -72,8 +72,8 @@ export class WKBrowser extends BrowserBase {
|
||||||
this._didClose();
|
this._didClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async newContext(options: BrowserContextOptions = {}): Promise<BrowserContext> {
|
async newContext(options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
||||||
options = validateBrowserContextOptions(options);
|
validateBrowserContextOptions(options);
|
||||||
const { browserContextId } = await this._browserSession.send('Playwright.createContext');
|
const { browserContextId } = await this._browserSession.send('Playwright.createContext');
|
||||||
options.userAgent = options.userAgent || DEFAULT_USER_AGENT;
|
options.userAgent = options.userAgent || DEFAULT_USER_AGENT;
|
||||||
const context = new WKBrowserContext(this, browserContextId, options);
|
const context = new WKBrowserContext(this, browserContextId, options);
|
||||||
|
|
@ -287,8 +287,7 @@ export class WKBrowserContext extends BrowserContextBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
|
||||||
if (geolocation)
|
verifyGeolocation(geolocation);
|
||||||
geolocation = verifyGeolocation(geolocation);
|
|
||||||
this._options.geolocation = geolocation;
|
this._options.geolocation = geolocation;
|
||||||
const payload: any = geolocation ? { ...geolocation, timestamp: Date.now() } : undefined;
|
const payload: any = geolocation ? { ...geolocation, timestamp: Date.now() } : undefined;
|
||||||
await this._browser._browserSession.send('Playwright.setGeolocationOverride', { browserContextId: this._browserContextId, geolocation: payload });
|
await this._browser._browserSession.send('Playwright.setGeolocationOverride', { browserContextId: this._browserContextId, geolocation: payload });
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ export class WKPage implements PageDelegate {
|
||||||
this._firstNonInitialNavigationCommittedFulfill = f;
|
this._firstNonInitialNavigationCommittedFulfill = f;
|
||||||
this._firstNonInitialNavigationCommittedReject = r;
|
this._firstNonInitialNavigationCommittedReject = r;
|
||||||
});
|
});
|
||||||
if (opener && browserContext._options.viewport !== null && opener._nextWindowOpenPopupFeatures) {
|
if (opener && !browserContext._options.noDefaultViewport && opener._nextWindowOpenPopupFeatures) {
|
||||||
const viewportSize = helper.getViewportSizeFromWindowFeatures(opener._nextWindowOpenPopupFeatures);
|
const viewportSize = helper.getViewportSizeFromWindowFeatures(opener._nextWindowOpenPopupFeatures);
|
||||||
opener._nextWindowOpenPopupFeatures = undefined;
|
opener._nextWindowOpenPopupFeatures = undefined;
|
||||||
if (viewportSize)
|
if (viewportSize)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue