chore: move devices from Playwright to LocalUtils (#27437)

Also, do not create `LocalUtils` for remote connections. This avoids
sending device on every remote connect.
This commit is contained in:
Dmitry Gozman 2023-10-04 16:48:54 -07:00 committed by GitHub
parent b584a86a8b
commit 045e8aa368
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 93 deletions

View File

@ -16,9 +16,25 @@
import type * as channels from '@protocol/channels';
import { ChannelOwner } from './channelOwner';
import type { Size } from './types';
type DeviceDescriptor = {
userAgent: string,
viewport: Size,
deviceScaleFactor: number,
isMobile: boolean,
hasTouch: boolean,
defaultBrowserType: 'chromium' | 'firefox' | 'webkit'
};
type Devices = { [name: string]: DeviceDescriptor };
export class LocalUtils extends ChannelOwner<channels.LocalUtilsChannel> {
readonly devices: Devices;
constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.LocalUtilsInitializer) {
super(parent, type, guid, initializer);
this.devices = {};
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
}
}

View File

@ -22,17 +22,6 @@ import { ChannelOwner } from './channelOwner';
import { Electron } from './electron';
import { APIRequest } from './fetch';
import { Selectors, SelectorsOwner } from './selectors';
import type { Size } from './types';
type DeviceDescriptor = {
userAgent: string,
viewport: Size,
deviceScaleFactor: number,
isMobile: boolean,
hasTouch: boolean,
defaultBrowserType: 'chromium' | 'firefox' | 'webkit'
};
type Devices = { [name: string]: DeviceDescriptor };
export class Playwright extends ChannelOwner<channels.PlaywrightChannel> {
readonly _android: Android;
@ -40,7 +29,7 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel> {
readonly chromium: BrowserType;
readonly firefox: BrowserType;
readonly webkit: BrowserType;
readonly devices: Devices;
readonly devices: any;
selectors: Selectors;
readonly request: APIRequest;
readonly errors: { TimeoutError: typeof TimeoutError };
@ -56,9 +45,7 @@ export class Playwright extends ChannelOwner<channels.PlaywrightChannel> {
this.webkit._playwright = this;
this._android = Android.from(initializer.android);
this._electron = Electron.from(initializer.electron);
this.devices = {};
for (const { name, descriptor } of initializer.deviceDescriptors)
this.devices[name] = descriptor;
this.devices = this._connection.localUtils()?.devices ?? {};
this.selectors = new Selectors();
this.errors = { TimeoutError };

View File

@ -217,7 +217,26 @@ scheme.APIResponse = tObject({
headers: tArray(tType('NameValue')),
});
scheme.LifecycleEvent = tEnum(['load', 'domcontentloaded', 'networkidle', 'commit']);
scheme.LocalUtilsInitializer = tOptional(tObject({}));
scheme.LocalUtilsInitializer = tObject({
deviceDescriptors: tArray(tObject({
name: tString,
descriptor: tObject({
userAgent: tString,
viewport: tObject({
width: tNumber,
height: tNumber,
}),
screen: tOptional(tObject({
width: tNumber,
height: tNumber,
})),
deviceScaleFactor: tNumber,
isMobile: tBoolean,
hasTouch: tBoolean,
defaultBrowserType: tEnum(['chromium', 'firefox', 'webkit']),
}),
})),
});
scheme.LocalUtilsZipParams = tObject({
zipFile: tString,
entries: tArray(tType('NameValue')),
@ -298,25 +317,7 @@ scheme.PlaywrightInitializer = tObject({
webkit: tChannel(['BrowserType']),
android: tChannel(['Android']),
electron: tChannel(['Electron']),
utils: tChannel(['LocalUtils']),
deviceDescriptors: tArray(tObject({
name: tString,
descriptor: tObject({
userAgent: tString,
viewport: tObject({
width: tNumber,
height: tNumber,
}),
screen: tOptional(tObject({
width: tNumber,
height: tNumber,
})),
deviceScaleFactor: tNumber,
isMobile: tBoolean,
hasTouch: tBoolean,
defaultBrowserType: tEnum(['chromium', 'firefox', 'webkit']),
}),
})),
utils: tOptional(tChannel(['LocalUtils'])),
selectors: tChannel(['Selectors']),
preLaunchedBrowser: tOptional(tChannel(['Browser'])),
preConnectedAndroidDevice: tOptional(tChannel(['AndroidDevice'])),

View File

@ -26,7 +26,7 @@ import { Dispatcher } from './dispatcher';
import { yazl, yauzl } from '../../zipBundle';
import { ZipFile } from '../../utils/zipFile';
import type * as har from '@trace/har';
import type { HeadersArray } from '../types';
import type { HeadersArray, Devices } from '../types';
import { JsonPipeDispatcher } from '../dispatchers/jsonPipeDispatcher';
import { WebSocketTransport } from '../transport';
import { SocksInterceptor } from '../socksInterceptor';
@ -53,7 +53,12 @@ export class LocalUtilsDispatcher extends Dispatcher<{ guid: string }, channels.
constructor(scope: RootDispatcher, playwright: Playwright) {
const localUtils = new SdkObject(playwright, 'localUtils', 'localUtils');
super(scope, localUtils, 'LocalUtils', {});
const descriptors = require('../deviceDescriptors') as Devices;
const deviceDescriptors = Object.entries(descriptors)
.map(([name, descriptor]) => ({ name, descriptor }));
super(scope, localUtils, 'LocalUtils', {
deviceDescriptors,
});
this._type_LocalUtils = true;
}

View File

@ -20,7 +20,6 @@ import { GlobalAPIRequestContext } from '../fetch';
import type { Playwright } from '../playwright';
import type { SocksSocketClosedPayload, SocksSocketDataPayload, SocksSocketRequestedPayload } from '../../common/socksProxy';
import { SocksProxy } from '../../common/socksProxy';
import type * as types from '../types';
import { AndroidDispatcher } from './androidDispatcher';
import { BrowserTypeDispatcher } from './browserTypeDispatcher';
import type { RootDispatcher } from './dispatcher';
@ -40,9 +39,6 @@ export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.Playwr
private _browserDispatcher: ConnectedBrowserDispatcher | undefined;
constructor(scope: RootDispatcher, playwright: Playwright, socksProxy?: SocksProxy, preLaunchedBrowser?: Browser, prelaunchedAndroidDevice?: AndroidDevice) {
const descriptors = require('../deviceDescriptors') as types.Devices;
const deviceDescriptors = Object.entries(descriptors)
.map(([name, descriptor]) => ({ name, descriptor }));
const browserDispatcher = preLaunchedBrowser ? new ConnectedBrowserDispatcher(scope, preLaunchedBrowser) : undefined;
const android = new AndroidDispatcher(scope, playwright.android);
const prelaunchedAndroidDeviceDispatcher = prelaunchedAndroidDevice ? new AndroidDeviceDispatcher(android, prelaunchedAndroidDevice) : undefined;
@ -52,8 +48,7 @@ export class PlaywrightDispatcher extends Dispatcher<Playwright, channels.Playwr
webkit: new BrowserTypeDispatcher(scope, playwright.webkit),
android,
electron: new ElectronDispatcher(scope, playwright.electron),
utils: new LocalUtilsDispatcher(scope, playwright),
deviceDescriptors,
utils: playwright.options.isServer ? undefined : new LocalUtilsDispatcher(scope, playwright),
selectors: new SelectorsDispatcher(scope, browserDispatcher?.selectors || playwright.selectors),
preLaunchedBrowser: browserDispatcher,
preConnectedAndroidDevice: prelaunchedAndroidDeviceDispatcher,

View File

@ -389,7 +389,26 @@ export type APIResponse = {
export type LifecycleEvent = 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
// ----------- LocalUtils -----------
export type LocalUtilsInitializer = {};
export type LocalUtilsInitializer = {
deviceDescriptors: {
name: string,
descriptor: {
userAgent: string,
viewport: {
width: number,
height: number,
},
screen?: {
width: number,
height: number,
},
deviceScaleFactor: number,
isMobile: boolean,
hasTouch: boolean,
defaultBrowserType: 'chromium' | 'firefox' | 'webkit',
},
}[],
};
export interface LocalUtilsEventTarget {
}
export interface LocalUtilsChannel extends LocalUtilsEventTarget, Channel {
@ -534,25 +553,7 @@ export type PlaywrightInitializer = {
webkit: BrowserTypeChannel,
android: AndroidChannel,
electron: ElectronChannel,
utils: LocalUtilsChannel,
deviceDescriptors: {
name: string,
descriptor: {
userAgent: string,
viewport: {
width: number,
height: number,
},
screen?: {
width: number,
height: number,
},
deviceScaleFactor: number,
isMobile: boolean,
hasTouch: boolean,
defaultBrowserType: 'chromium' | 'firefox' | 'webkit',
},
}[],
utils?: LocalUtilsChannel,
selectors: SelectorsChannel,
preLaunchedBrowser?: BrowserChannel,
preConnectedAndroidDevice?: AndroidDeviceChannel,

View File

@ -501,6 +501,37 @@ ContextOptions:
LocalUtils:
type: interface
initializer:
deviceDescriptors:
type: array
items:
type: object
properties:
name: string
descriptor:
type: object
properties:
userAgent: string
viewport:
type: object
properties:
width: number
height: number
screen:
type: object?
properties:
width: number
height: number
deviceScaleFactor: number
isMobile: boolean
hasTouch: boolean
defaultBrowserType:
type: enum
literals:
- chromium
- firefox
- webkit
commands:
zip:
@ -614,36 +645,7 @@ Playwright:
webkit: BrowserType
android: Android
electron: Electron
utils: LocalUtils
deviceDescriptors:
type: array
items:
type: object
properties:
name: string
descriptor:
type: object
properties:
userAgent: string
viewport:
type: object
properties:
width: number
height: number
screen:
type: object?
properties:
width: number
height: number
deviceScaleFactor: number
isMobile: boolean
hasTouch: boolean
defaultBrowserType:
type: enum
literals:
- chromium
- firefox
- webkit
utils: LocalUtils?
selectors: Selectors
# Only present when connecting remotely via BrowserType.connect() method.
preLaunchedBrowser: Browser?