chore: detect browser reuse based on the connection headers (#18230)
This commit is contained in:
parent
7ae447ea0f
commit
5b1e4e08a5
|
|
@ -54,7 +54,7 @@ export class BrowserServerLauncherImpl implements BrowserServerLauncher {
|
||||||
path = options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}`;
|
path = options.wsPath.startsWith('/') ? options.wsPath : `/${options.wsPath}`;
|
||||||
|
|
||||||
// 2. Start the server
|
// 2. Start the server
|
||||||
const server = new PlaywrightServer('use-pre-launched-browser', { path, maxConcurrentConnections: Infinity, maxIncomingConnections: Infinity, enableSocksProxy: false, preLaunchedBrowser: browser });
|
const server = new PlaywrightServer({ path, maxConnections: Infinity, enableSocksProxy: false, preLaunchedBrowser: browser });
|
||||||
const wsEndpoint = await server.listen(options.port);
|
const wsEndpoint = await server.listen(options.port);
|
||||||
|
|
||||||
// 3. Return the BrowserServer interface
|
// 3. Return the BrowserServer interface
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,8 @@ export function runDriver() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runServer(port: number | undefined, path = '/', maxClients = Infinity, enableSocksProxy = true, reuseBrowser = false) {
|
export async function runServer(port: number | undefined, path = '/', maxConnections = Infinity, enableSocksProxy = true, reuseBrowser = false) {
|
||||||
const maxIncomingConnections = maxClients;
|
const server = new PlaywrightServer({ path, maxConnections, enableSocksProxy });
|
||||||
const maxConcurrentConnections = reuseBrowser ? 1 : maxClients;
|
|
||||||
const server = new PlaywrightServer(reuseBrowser ? 'reuse-browser' : 'auto', { path, maxIncomingConnections, maxConcurrentConnections, enableSocksProxy });
|
|
||||||
const wsEndpoint = await server.listen(port);
|
const wsEndpoint = await server.listen(port);
|
||||||
process.on('exit', () => server.close().catch(console.error));
|
process.on('exit', () => server.close().catch(console.error));
|
||||||
console.log('Listening on ' + wsEndpoint); // eslint-disable-line no-console
|
console.log('Listening on ' + wsEndpoint); // eslint-disable-line no-console
|
||||||
|
|
@ -86,7 +84,6 @@ class ProtocolHandler {
|
||||||
this._controller = playwright.debugController;
|
this._controller = playwright.debugController;
|
||||||
this._controller.setAutoCloseAllowed(true);
|
this._controller.setAutoCloseAllowed(true);
|
||||||
this._controller.setTrackHierarcy(true);
|
this._controller.setTrackHierarcy(true);
|
||||||
this._controller.setReuseBrowser(true);
|
|
||||||
this._controller.on(DebugController.Events.BrowsersChanged, browsers => {
|
this._controller.on(DebugController.Events.BrowsersChanged, browsers => {
|
||||||
process.send!({ method: 'browsersChanged', params: { browsers } });
|
process.send!({ method: 'browsersChanged', params: { browsers } });
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ function launchGridBrowserWorker(gridURL: string, agentId: string, workerId: str
|
||||||
const log = debug(`pw:grid:worker:${workerId}`);
|
const log = debug(`pw:grid:worker:${workerId}`);
|
||||||
log('created');
|
log('created');
|
||||||
const ws = new WebSocket(gridURL.replace('http://', 'ws://') + `/registerWorker?agentId=${agentId}&workerId=${workerId}`);
|
const ws = new WebSocket(gridURL.replace('http://', 'ws://') + `/registerWorker?agentId=${agentId}&workerId=${workerId}`);
|
||||||
new PlaywrightConnection(Promise.resolve(), 'auto', ws, false, { enableSocksProxy: true, browserName, launchOptions: {} }, { playwright: null, browser: null }, log, async () => {
|
new PlaywrightConnection(Promise.resolve(), 'launch-browser', ws, { enableSocksProxy: true, browserName, launchOptions: {} }, { playwright: null, browser: null }, log, async () => {
|
||||||
log('exiting process');
|
log('exiting process');
|
||||||
setTimeout(() => process.exit(0), 30000);
|
setTimeout(() => process.exit(0), 30000);
|
||||||
// Meanwhile, try to gracefully close all browsers.
|
// Meanwhile, try to gracefully close all browsers.
|
||||||
|
|
|
||||||
|
|
@ -350,10 +350,6 @@ scheme.DebugControllerSetTrackHierarchyParams = tObject({
|
||||||
enabled: tBoolean,
|
enabled: tBoolean,
|
||||||
});
|
});
|
||||||
scheme.DebugControllerSetTrackHierarchyResult = tOptional(tObject({}));
|
scheme.DebugControllerSetTrackHierarchyResult = tOptional(tObject({}));
|
||||||
scheme.DebugControllerSetReuseBrowserParams = tObject({
|
|
||||||
enabled: tBoolean,
|
|
||||||
});
|
|
||||||
scheme.DebugControllerSetReuseBrowserResult = tOptional(tObject({}));
|
|
||||||
scheme.DebugControllerResetForReuseParams = tOptional(tObject({}));
|
scheme.DebugControllerResetForReuseParams = tOptional(tObject({}));
|
||||||
scheme.DebugControllerResetForReuseResult = tOptional(tObject({}));
|
scheme.DebugControllerResetForReuseResult = tOptional(tObject({}));
|
||||||
scheme.DebugControllerNavigateAllParams = tObject({
|
scheme.DebugControllerNavigateAllParams = tObject({
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,12 @@ import { Browser } from '../server/browser';
|
||||||
import { serverSideCallMetadata } from '../server/instrumentation';
|
import { serverSideCallMetadata } from '../server/instrumentation';
|
||||||
import { gracefullyCloseAll } from '../utils/processLauncher';
|
import { gracefullyCloseAll } from '../utils/processLauncher';
|
||||||
import { SocksProxy } from '../common/socksProxy';
|
import { SocksProxy } from '../common/socksProxy';
|
||||||
import type { Mode } from './playwrightServer';
|
|
||||||
import { assert } from '../utils';
|
import { assert } from '../utils';
|
||||||
import type { LaunchOptions } from '../server/types';
|
import type { LaunchOptions } from '../server/types';
|
||||||
import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher';
|
import { DebugControllerDispatcher } from '../server/dispatchers/debugControllerDispatcher';
|
||||||
|
|
||||||
|
export type ClientType = 'controller' | 'playwright' | 'launch-browser' | 'reuse-browser' | 'pre-launched-browser';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
enableSocksProxy: boolean,
|
enableSocksProxy: boolean,
|
||||||
browserName: string | null,
|
browserName: string | null,
|
||||||
|
|
@ -48,13 +49,13 @@ export class PlaywrightConnection {
|
||||||
private _options: Options;
|
private _options: Options;
|
||||||
private _root: DispatcherScope;
|
private _root: DispatcherScope;
|
||||||
|
|
||||||
constructor(lock: Promise<void>, mode: Mode, ws: WebSocket, isDebugControllerClient: boolean, options: Options, preLaunched: PreLaunched, log: (m: string) => void, onClose: () => void) {
|
constructor(lock: Promise<void>, clientType: ClientType, ws: WebSocket, options: Options, preLaunched: PreLaunched, log: (m: string) => void, onClose: () => void) {
|
||||||
this._ws = ws;
|
this._ws = ws;
|
||||||
this._preLaunched = preLaunched;
|
this._preLaunched = preLaunched;
|
||||||
this._options = options;
|
this._options = options;
|
||||||
if (mode === 'reuse-browser' || mode === 'use-pre-launched-browser')
|
if (clientType === 'reuse-browser' || clientType === 'pre-launched-browser')
|
||||||
assert(preLaunched.playwright);
|
assert(preLaunched.playwright);
|
||||||
if (mode === 'use-pre-launched-browser')
|
if (clientType === 'pre-launched-browser')
|
||||||
assert(preLaunched.browser);
|
assert(preLaunched.browser);
|
||||||
this._onClose = onClose;
|
this._onClose = onClose;
|
||||||
this._debugLog = log;
|
this._debugLog = log;
|
||||||
|
|
@ -73,19 +74,21 @@ export class PlaywrightConnection {
|
||||||
ws.on('close', () => this._onDisconnect());
|
ws.on('close', () => this._onDisconnect());
|
||||||
ws.on('error', error => this._onDisconnect(error));
|
ws.on('error', error => this._onDisconnect(error));
|
||||||
|
|
||||||
if (isDebugControllerClient) {
|
if (clientType === 'controller') {
|
||||||
this._root = this._initDebugControllerMode();
|
this._root = this._initDebugControllerMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._root = new RootDispatcher(this._dispatcherConnection, async scope => {
|
this._root = new RootDispatcher(this._dispatcherConnection, async scope => {
|
||||||
if (mode === 'reuse-browser')
|
if (clientType === 'reuse-browser')
|
||||||
return await this._initReuseBrowsersMode(scope);
|
return await this._initReuseBrowsersMode(scope);
|
||||||
if (mode === 'use-pre-launched-browser')
|
if (clientType === 'pre-launched-browser')
|
||||||
return await this._initPreLaunchedBrowserMode(scope);
|
return await this._initPreLaunchedBrowserMode(scope);
|
||||||
if (!options.browserName)
|
if (clientType === 'launch-browser')
|
||||||
|
return await this._initLaunchBrowserMode(scope);
|
||||||
|
if (clientType === 'playwright')
|
||||||
return await this._initPlaywrightConnectMode(scope);
|
return await this._initPlaywrightConnectMode(scope);
|
||||||
return await this._initLaunchBrowserMode(scope);
|
throw new Error('Unsupported client type: ' + clientType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import type { Browser } from '../server/browser';
|
||||||
import type { Playwright } from '../server/playwright';
|
import type { Playwright } from '../server/playwright';
|
||||||
import { createPlaywright } from '../server/playwright';
|
import { createPlaywright } from '../server/playwright';
|
||||||
import { PlaywrightConnection } from './playwrightConnection';
|
import { PlaywrightConnection } from './playwrightConnection';
|
||||||
import { assert } from '../utils';
|
import type { ClientType } from './playwrightConnection';
|
||||||
import type { LaunchOptions } from '../server/types';
|
import type { LaunchOptions } from '../server/types';
|
||||||
import { ManualPromise } from '../utils/manualPromise';
|
import { ManualPromise } from '../utils/manualPromise';
|
||||||
|
|
||||||
|
|
@ -35,13 +35,9 @@ function newLogger() {
|
||||||
return (message: string) => debugLog(`[id=${id}] ${message}`);
|
return (message: string) => debugLog(`[id=${id}] ${message}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: replace 'reuse-browser' with 'allow-reuse' in 1.27.
|
|
||||||
export type Mode = 'use-pre-launched-browser' | 'reuse-browser' | 'auto';
|
|
||||||
|
|
||||||
type ServerOptions = {
|
type ServerOptions = {
|
||||||
path: string;
|
path: string;
|
||||||
maxIncomingConnections: number;
|
maxConnections: number;
|
||||||
maxConcurrentConnections: number;
|
|
||||||
enableSocksProxy: boolean;
|
enableSocksProxy: boolean;
|
||||||
preLaunchedBrowser?: Browser
|
preLaunchedBrowser?: Browser
|
||||||
};
|
};
|
||||||
|
|
@ -49,16 +45,12 @@ type ServerOptions = {
|
||||||
export class PlaywrightServer {
|
export class PlaywrightServer {
|
||||||
private _preLaunchedPlaywright: Playwright | null = null;
|
private _preLaunchedPlaywright: Playwright | null = null;
|
||||||
private _wsServer: WebSocketServer | undefined;
|
private _wsServer: WebSocketServer | undefined;
|
||||||
private _mode: Mode;
|
|
||||||
private _options: ServerOptions;
|
private _options: ServerOptions;
|
||||||
|
|
||||||
constructor(mode: Mode, options: ServerOptions) {
|
constructor(options: ServerOptions) {
|
||||||
this._mode = mode;
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
if (mode === 'use-pre-launched-browser') {
|
if (options.preLaunchedBrowser)
|
||||||
assert(options.preLaunchedBrowser);
|
|
||||||
this._preLaunchedPlaywright = options.preLaunchedBrowser.options.rootSdkObject as Playwright;
|
this._preLaunchedPlaywright = options.preLaunchedBrowser.options.rootSdkObject as Playwright;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
preLaunchedPlaywright(): Playwright {
|
preLaunchedPlaywright(): Playwright {
|
||||||
|
|
@ -95,13 +87,10 @@ export class PlaywrightServer {
|
||||||
debugLog('Listening at ' + wsEndpoint);
|
debugLog('Listening at ' + wsEndpoint);
|
||||||
|
|
||||||
this._wsServer = new wsServer({ server, path: this._options.path });
|
this._wsServer = new wsServer({ server, path: this._options.path });
|
||||||
const browserSemaphore = new Semaphore(this._options.maxConcurrentConnections);
|
const browserSemaphore = new Semaphore(this._options.maxConnections);
|
||||||
const controllerSemaphore = new Semaphore(1);
|
const controllerSemaphore = new Semaphore(1);
|
||||||
|
const reuseBrowserSemaphore = new Semaphore(1);
|
||||||
this._wsServer.on('connection', (ws, request) => {
|
this._wsServer.on('connection', (ws, request) => {
|
||||||
if (browserSemaphore.requested() >= this._options.maxIncomingConnections) {
|
|
||||||
ws.close(1013, 'Playwright Server is busy');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const url = new URL('http://localhost' + (request.url || ''));
|
const url = new URL('http://localhost' + (request.url || ''));
|
||||||
const browserHeader = request.headers['x-playwright-browser'];
|
const browserHeader = request.headers['x-playwright-browser'];
|
||||||
const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null;
|
const browserName = url.searchParams.get('browser') || (Array.isArray(browserHeader) ? browserHeader[0] : browserHeader) || null;
|
||||||
|
|
@ -119,26 +108,27 @@ export class PlaywrightServer {
|
||||||
const log = newLogger();
|
const log = newLogger();
|
||||||
log(`serving connection: ${request.url}`);
|
log(`serving connection: ${request.url}`);
|
||||||
const isDebugControllerClient = !!request.headers['x-playwright-debug-controller'];
|
const isDebugControllerClient = !!request.headers['x-playwright-debug-controller'];
|
||||||
const semaphore = isDebugControllerClient ? controllerSemaphore : browserSemaphore;
|
const shouldReuseBrowser = !!request.headers['x-playwright-reuse-context'];
|
||||||
|
const semaphore = isDebugControllerClient ? controllerSemaphore : (shouldReuseBrowser ? reuseBrowserSemaphore : browserSemaphore);
|
||||||
|
|
||||||
// If we started in the legacy reuse-browser mode, create this._preLaunchedPlaywright.
|
// If we started in the legacy reuse-browser mode, create this._preLaunchedPlaywright.
|
||||||
// If we get a reuse-controller request, create this._preLaunchedPlaywright.
|
// If we get a reuse-controller request, create this._preLaunchedPlaywright.
|
||||||
if (isDebugControllerClient || (this._mode === 'reuse-browser') && !this._preLaunchedPlaywright)
|
if (isDebugControllerClient || shouldReuseBrowser)
|
||||||
this.preLaunchedPlaywright();
|
this.preLaunchedPlaywright();
|
||||||
|
|
||||||
// If we have a playwright to reuse, consult controller for reuse mode.
|
let clientType: ClientType = 'playwright';
|
||||||
let mode = this._mode;
|
if (isDebugControllerClient)
|
||||||
if (mode === 'auto' && this._preLaunchedPlaywright?.debugController.reuseBrowser())
|
clientType = 'controller';
|
||||||
mode = 'reuse-browser';
|
else if (shouldReuseBrowser)
|
||||||
|
clientType = 'reuse-browser';
|
||||||
if (mode === 'reuse-browser')
|
else if (this._options.preLaunchedBrowser)
|
||||||
semaphore.setMax(1);
|
clientType = 'pre-launched-browser';
|
||||||
else
|
else if (browserName)
|
||||||
semaphore.setMax(this._options.maxConcurrentConnections);
|
clientType = 'launch-browser';
|
||||||
|
|
||||||
const connection = new PlaywrightConnection(
|
const connection = new PlaywrightConnection(
|
||||||
semaphore.aquire(),
|
semaphore.aquire(),
|
||||||
mode, ws, isDebugControllerClient,
|
clientType, ws,
|
||||||
{ enableSocksProxy, browserName, launchOptions },
|
{ enableSocksProxy, browserName, launchOptions },
|
||||||
{ playwright: this._preLaunchedPlaywright, browser: this._options.preLaunchedBrowser || null },
|
{ playwright: this._preLaunchedPlaywright, browser: this._options.preLaunchedBrowser || null },
|
||||||
log, () => semaphore.release());
|
log, () => semaphore.release());
|
||||||
|
|
@ -192,10 +182,6 @@ export class Semaphore {
|
||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
requested() {
|
|
||||||
return this._aquired + this._queue.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
release() {
|
release() {
|
||||||
--this._aquired;
|
--this._aquired;
|
||||||
this._flush();
|
this._flush();
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ export class DebugController extends SdkObject {
|
||||||
dispose() {
|
dispose() {
|
||||||
this.setTrackHierarcy(false);
|
this.setTrackHierarcy(false);
|
||||||
this.setAutoCloseAllowed(false);
|
this.setAutoCloseAllowed(false);
|
||||||
this.setReuseBrowser(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTrackHierarcy(enabled: boolean) {
|
setTrackHierarcy(enabled: boolean) {
|
||||||
|
|
@ -72,14 +71,6 @@ export class DebugController extends SdkObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reuseBrowser(): boolean {
|
|
||||||
return this._reuseBrowser;
|
|
||||||
}
|
|
||||||
|
|
||||||
setReuseBrowser(enabled: boolean) {
|
|
||||||
this._reuseBrowser = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
async resetForReuse() {
|
async resetForReuse() {
|
||||||
const contexts = new Set<BrowserContext>();
|
const contexts = new Set<BrowserContext>();
|
||||||
for (const page of this._playwright.allPages())
|
for (const page of this._playwright.allPages())
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,6 @@ export class DebugControllerDispatcher extends Dispatcher<DebugController, chann
|
||||||
this._object.setTrackHierarcy(params.enabled);
|
this._object.setTrackHierarcy(params.enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setReuseBrowser(params: channels.DebugControllerSetReuseBrowserParams) {
|
|
||||||
this._object.setReuseBrowser(params.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
async resetForReuse() {
|
async resetForReuse() {
|
||||||
await this._object.resetForReuse();
|
await this._object.resetForReuse();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,22 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
|
||||||
headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: 'worker', option: true }],
|
headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: 'worker', option: true }],
|
||||||
channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }],
|
channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }],
|
||||||
launchOptions: [{}, { scope: 'worker', option: true }],
|
launchOptions: [{}, { scope: 'worker', option: true }],
|
||||||
connectOptions: [process.env.PW_TEST_CONNECT_WS_ENDPOINT ? {
|
connectOptions: [({}, use) => {
|
||||||
wsEndpoint: process.env.PW_TEST_CONNECT_WS_ENDPOINT,
|
const wsEndpoint = process.env.PW_TEST_CONNECT_WS_ENDPOINT;
|
||||||
headers: process.env.PW_TEST_CONNECT_HEADERS ? JSON.parse(process.env.PW_TEST_CONNECT_HEADERS) : undefined,
|
if (!wsEndpoint)
|
||||||
} : undefined, { scope: 'worker', option: true }],
|
return use(undefined);
|
||||||
|
let headers = process.env.PW_TEST_CONNECT_HEADERS ? JSON.parse(process.env.PW_TEST_CONNECT_HEADERS) : undefined;
|
||||||
|
if (process.env.PW_TEST_REUSE_CONTEXT) {
|
||||||
|
headers = {
|
||||||
|
...headers,
|
||||||
|
'x-playwright-reuse-context': '1',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return use({
|
||||||
|
wsEndpoint,
|
||||||
|
headers
|
||||||
|
});
|
||||||
|
}, { scope: 'worker', option: true }],
|
||||||
screenshot: ['off', { scope: 'worker', option: true }],
|
screenshot: ['off', { scope: 'worker', option: true }],
|
||||||
video: ['off', { scope: 'worker', option: true }],
|
video: ['off', { scope: 'worker', option: true }],
|
||||||
trace: ['off', { scope: 'worker', option: true }],
|
trace: ['off', { scope: 'worker', option: true }],
|
||||||
|
|
|
||||||
|
|
@ -599,7 +599,6 @@ export interface DebugControllerEventTarget {
|
||||||
export interface DebugControllerChannel extends DebugControllerEventTarget, Channel {
|
export interface DebugControllerChannel extends DebugControllerEventTarget, Channel {
|
||||||
_type_DebugController: boolean;
|
_type_DebugController: boolean;
|
||||||
setTrackHierarchy(params: DebugControllerSetTrackHierarchyParams, metadata?: Metadata): Promise<DebugControllerSetTrackHierarchyResult>;
|
setTrackHierarchy(params: DebugControllerSetTrackHierarchyParams, metadata?: Metadata): Promise<DebugControllerSetTrackHierarchyResult>;
|
||||||
setReuseBrowser(params: DebugControllerSetReuseBrowserParams, metadata?: Metadata): Promise<DebugControllerSetReuseBrowserResult>;
|
|
||||||
resetForReuse(params?: DebugControllerResetForReuseParams, metadata?: Metadata): Promise<DebugControllerResetForReuseResult>;
|
resetForReuse(params?: DebugControllerResetForReuseParams, metadata?: Metadata): Promise<DebugControllerResetForReuseResult>;
|
||||||
navigateAll(params: DebugControllerNavigateAllParams, metadata?: Metadata): Promise<DebugControllerNavigateAllResult>;
|
navigateAll(params: DebugControllerNavigateAllParams, metadata?: Metadata): Promise<DebugControllerNavigateAllResult>;
|
||||||
setRecorderMode(params: DebugControllerSetRecorderModeParams, metadata?: Metadata): Promise<DebugControllerSetRecorderModeResult>;
|
setRecorderMode(params: DebugControllerSetRecorderModeParams, metadata?: Metadata): Promise<DebugControllerSetRecorderModeResult>;
|
||||||
|
|
@ -629,13 +628,6 @@ export type DebugControllerSetTrackHierarchyOptions = {
|
||||||
|
|
||||||
};
|
};
|
||||||
export type DebugControllerSetTrackHierarchyResult = void;
|
export type DebugControllerSetTrackHierarchyResult = void;
|
||||||
export type DebugControllerSetReuseBrowserParams = {
|
|
||||||
enabled: boolean,
|
|
||||||
};
|
|
||||||
export type DebugControllerSetReuseBrowserOptions = {
|
|
||||||
|
|
||||||
};
|
|
||||||
export type DebugControllerSetReuseBrowserResult = void;
|
|
||||||
export type DebugControllerResetForReuseParams = {};
|
export type DebugControllerResetForReuseParams = {};
|
||||||
export type DebugControllerResetForReuseOptions = {};
|
export type DebugControllerResetForReuseOptions = {};
|
||||||
export type DebugControllerResetForReuseResult = void;
|
export type DebugControllerResetForReuseResult = void;
|
||||||
|
|
|
||||||
|
|
@ -664,10 +664,6 @@ DebugController:
|
||||||
parameters:
|
parameters:
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
|
|
||||||
setReuseBrowser:
|
|
||||||
parameters:
|
|
||||||
enabled: boolean
|
|
||||||
|
|
||||||
resetForReuse:
|
resetForReuse:
|
||||||
|
|
||||||
navigateAll:
|
navigateAll:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue