mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-13 17:14:02 +03:00
chore: reparent context objects into the object (#15689)
This commit is contained in:
parent
da2fdc2e2e
commit
a198b6d753
@ -74,7 +74,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
|
|||||||
this._browser = parent;
|
this._browser = parent;
|
||||||
this._isChromium = this._browser?._name === 'chromium';
|
this._isChromium = this._browser?._name === 'chromium';
|
||||||
this.tracing = Tracing.from(initializer.tracing);
|
this.tracing = Tracing.from(initializer.tracing);
|
||||||
this.request = APIRequestContext.from(initializer.APIRequestContext);
|
this.request = APIRequestContext.from(initializer.requestContext);
|
||||||
|
|
||||||
this._channel.on('bindingCall', ({ binding }) => this._onBinding(BindingCall.from(binding)));
|
this._channel.on('bindingCall', ({ binding }) => this._onBinding(BindingCall.from(binding)));
|
||||||
this._channel.on('close', () => this._onClose());
|
this._channel.on('close', () => this._onClose());
|
||||||
|
@ -57,6 +57,12 @@ export abstract class ChannelOwner<T extends channels.Channel = channels.Channel
|
|||||||
this._initializer = initializer;
|
this._initializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_adopt(child: ChannelOwner<any>) {
|
||||||
|
child._parent!._objects.delete(child._guid);
|
||||||
|
this._objects.set(child._guid, child);
|
||||||
|
child._parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
_dispose() {
|
_dispose() {
|
||||||
// Clean up from parent and connection.
|
// Clean up from parent and connection.
|
||||||
if (this._parent)
|
if (this._parent)
|
||||||
|
@ -143,16 +143,24 @@ export class Connection extends EventEmitter {
|
|||||||
this._createRemoteObject(guid, params.type, params.guid, params.initializer);
|
this._createRemoteObject(guid, params.type, params.guid, params.initializer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const object = this._objects.get(guid);
|
||||||
|
if (!object)
|
||||||
|
throw new Error(`Cannot find object to "${method}": ${guid}`);
|
||||||
|
|
||||||
|
if (method === '__adopt__') {
|
||||||
|
const child = this._objects.get(params.guid);
|
||||||
|
if (!child)
|
||||||
|
throw new Error(`Unknown new child: ${params.guid}`);
|
||||||
|
object._adopt(child);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (method === '__dispose__') {
|
if (method === '__dispose__') {
|
||||||
const object = this._objects.get(guid);
|
|
||||||
if (!object)
|
|
||||||
throw new Error(`Cannot find object to dispose: ${guid}`);
|
|
||||||
object._dispose();
|
object._dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const object = this._objects.get(guid);
|
|
||||||
if (!object)
|
|
||||||
throw new Error(`Cannot find object to emit "${method}": ${guid}`);
|
|
||||||
const validator = findValidator(object._type, method, 'Event');
|
const validator = findValidator(object._type, method, 'Event');
|
||||||
(object._channel as any).emit(method, validator(params, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this.isRemote() ? 'fromBase64' : 'buffer' }));
|
(object._channel as any).emit(method, validator(params, '', { tChannelImpl: this._tChannelImplFromWire.bind(this), binary: this.isRemote() ? 'fromBase64' : 'buffer' }));
|
||||||
}
|
}
|
||||||
@ -166,8 +174,10 @@ export class Connection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext) {
|
private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext) {
|
||||||
if (arg && typeof arg === 'object' && typeof arg.guid === 'string' && this._objects.has(arg.guid)) {
|
if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {
|
||||||
const object = this._objects.get(arg.guid)!;
|
const object = this._objects.get(arg.guid)!;
|
||||||
|
if (!object)
|
||||||
|
throw new Error(`Object with guid ${arg.guid} was not bound in the connection`);
|
||||||
if (names !== '*' && !names.includes(object._type))
|
if (names !== '*' && !names.includes(object._type))
|
||||||
throw new ValidationError(`${path}: expected channel ${names.toString()}`);
|
throw new ValidationError(`${path}: expected channel ${names.toString()}`);
|
||||||
return object._channel;
|
return object._channel;
|
||||||
|
@ -1207,7 +1207,7 @@ export interface EventTargetEvents {
|
|||||||
// ----------- BrowserContext -----------
|
// ----------- BrowserContext -----------
|
||||||
export type BrowserContextInitializer = {
|
export type BrowserContextInitializer = {
|
||||||
isChromium: boolean,
|
isChromium: boolean,
|
||||||
APIRequestContext: APIRequestContextChannel,
|
requestContext: APIRequestContextChannel,
|
||||||
tracing: TracingChannel,
|
tracing: TracingChannel,
|
||||||
};
|
};
|
||||||
export interface BrowserContextEventTarget {
|
export interface BrowserContextEventTarget {
|
||||||
|
@ -835,7 +835,7 @@ BrowserContext:
|
|||||||
|
|
||||||
initializer:
|
initializer:
|
||||||
isChromium: boolean
|
isChromium: boolean
|
||||||
APIRequestContext: APIRequestContext
|
requestContext: APIRequestContext
|
||||||
tracing: Tracing
|
tracing: Tracing
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
|
@ -644,7 +644,7 @@ scheme.ElectronApplicationWaitForEventInfoResult = tType('EventTargetWaitForEven
|
|||||||
scheme.AndroidDeviceWaitForEventInfoResult = tType('EventTargetWaitForEventInfoResult');
|
scheme.AndroidDeviceWaitForEventInfoResult = tType('EventTargetWaitForEventInfoResult');
|
||||||
scheme.BrowserContextInitializer = tObject({
|
scheme.BrowserContextInitializer = tObject({
|
||||||
isChromium: tBoolean,
|
isChromium: tBoolean,
|
||||||
APIRequestContext: tChannel(['APIRequestContext']),
|
requestContext: tChannel(['APIRequestContext']),
|
||||||
tracing: tChannel(['Tracing']),
|
tracing: tChannel(['Tracing']),
|
||||||
});
|
});
|
||||||
scheme.BrowserContextBindingCallEvent = tObject({
|
scheme.BrowserContextBindingCallEvent = tObject({
|
||||||
|
@ -39,12 +39,20 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
|||||||
_type_BrowserContext = true;
|
_type_BrowserContext = true;
|
||||||
private _context: BrowserContext;
|
private _context: BrowserContext;
|
||||||
|
|
||||||
constructor(scope: DispatcherScope, context: BrowserContext) {
|
constructor(parentScope: DispatcherScope, context: BrowserContext) {
|
||||||
super(scope, context, 'BrowserContext', {
|
// We will reparent these to the context below.
|
||||||
|
const requestContext = APIRequestContextDispatcher.from(parentScope, context.fetchRequest);
|
||||||
|
const tracing = TracingDispatcher.from(parentScope, context.tracing);
|
||||||
|
|
||||||
|
super(parentScope, context, 'BrowserContext', {
|
||||||
isChromium: context._browser.options.isChromium,
|
isChromium: context._browser.options.isChromium,
|
||||||
APIRequestContext: APIRequestContextDispatcher.from(scope, context.fetchRequest),
|
requestContext,
|
||||||
tracing: TracingDispatcher.from(scope, context.tracing),
|
tracing,
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
this.adopt(requestContext);
|
||||||
|
this.adopt(tracing);
|
||||||
|
|
||||||
this._context = context;
|
this._context = context;
|
||||||
// Note: when launching persistent context, dispatcher is created very late,
|
// Note: when launching persistent context, dispatcher is created very late,
|
||||||
// so we can already have pages, videos and everything else.
|
// so we can already have pages, videos and everything else.
|
||||||
@ -52,7 +60,7 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
|||||||
const onVideo = (artifact: Artifact) => {
|
const onVideo = (artifact: Artifact) => {
|
||||||
// Note: Video must outlive Page and BrowserContext, so that client can saveAs it
|
// Note: Video must outlive Page and BrowserContext, so that client can saveAs it
|
||||||
// after closing the context. We use |scope| for it.
|
// after closing the context. We use |scope| for it.
|
||||||
const artifactDispatcher = new ArtifactDispatcher(scope, artifact);
|
const artifactDispatcher = new ArtifactDispatcher(parentScope, artifact);
|
||||||
this._dispatchEvent('video', { artifact: artifactDispatcher });
|
this._dispatchEvent('video', { artifact: artifactDispatcher });
|
||||||
};
|
};
|
||||||
this.addObjectListener(BrowserContext.Events.VideoStarted, onVideo);
|
this.addObjectListener(BrowserContext.Events.VideoStarted, onVideo);
|
||||||
@ -94,8 +102,8 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
|||||||
page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined())
|
page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined())
|
||||||
}));
|
}));
|
||||||
this.addObjectListener(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => this._dispatchEvent('requestFinished', {
|
this.addObjectListener(BrowserContext.Events.RequestFinished, ({ request, response }: { request: Request, response: Response | null }) => this._dispatchEvent('requestFinished', {
|
||||||
request: RequestDispatcher.from(scope, request),
|
request: RequestDispatcher.from(this._scope, request),
|
||||||
response: ResponseDispatcher.fromNullable(scope, response),
|
response: ResponseDispatcher.fromNullable(this._scope, response),
|
||||||
responseEndTiming: request._responseEndTiming,
|
responseEndTiming: request._responseEndTiming,
|
||||||
page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined()),
|
page: PageDispatcher.fromNullable(this._scope, request.frame()?._page.initializedOrUndefined()),
|
||||||
}));
|
}));
|
||||||
|
@ -88,6 +88,15 @@ export class Dispatcher<Type extends { guid: string }, ChannelType> extends Even
|
|||||||
this._eventListeners.push(eventsHelper.addEventListener(this._object as unknown as EventEmitter, eventName, handler));
|
this._eventListeners.push(eventsHelper.addEventListener(this._object as unknown as EventEmitter, eventName, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adopt(child: Dispatcher<any, any>) {
|
||||||
|
assert(this._isScope);
|
||||||
|
const oldParent = child._parent!;
|
||||||
|
oldParent._dispatchers.delete(child._guid);
|
||||||
|
this._dispatchers.set(child._guid, child);
|
||||||
|
child._parent = this;
|
||||||
|
this._connection.sendAdopt(this, child);
|
||||||
|
}
|
||||||
|
|
||||||
_dispatchEvent<T extends keyof channels.EventsTraits<ChannelType>>(method: T, params?: channels.EventsTraits<ChannelType>[T]) {
|
_dispatchEvent<T extends keyof channels.EventsTraits<ChannelType>>(method: T, params?: channels.EventsTraits<ChannelType>[T]) {
|
||||||
if (this._disposed) {
|
if (this._disposed) {
|
||||||
if (isUnderTest())
|
if (isUnderTest())
|
||||||
@ -100,7 +109,7 @@ export class Dispatcher<Type extends { guid: string }, ChannelType> extends Even
|
|||||||
}
|
}
|
||||||
|
|
||||||
_dispose() {
|
_dispose() {
|
||||||
assert(!this._disposed);
|
assert(!this._disposed, `${this._guid} is disposed more than once`);
|
||||||
this._disposed = true;
|
this._disposed = true;
|
||||||
eventsHelper.removeEventListeners(this._eventListeners);
|
eventsHelper.removeEventListeners(this._eventListeners);
|
||||||
|
|
||||||
@ -171,6 +180,10 @@ export class DispatcherConnection {
|
|||||||
this._sendMessageToClient(parent._guid, type, '__create__', { type, initializer, guid }, sdkObject);
|
this._sendMessageToClient(parent._guid, type, '__create__', { type, initializer, guid }, sdkObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendAdopt(parent: Dispatcher<any, any>, dispatcher: Dispatcher<any, any>) {
|
||||||
|
this._sendMessageToClient(parent._guid, dispatcher._type, '__adopt__', { guid: dispatcher._guid });
|
||||||
|
}
|
||||||
|
|
||||||
sendDispose(dispatcher: Dispatcher<any, any>) {
|
sendDispose(dispatcher: Dispatcher<any, any>) {
|
||||||
this._sendMessageToClient(dispatcher._guid, dispatcher._type, '__dispose__', {});
|
this._sendMessageToClient(dispatcher._guid, dispatcher._type, '__dispose__', {});
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '../../protocol/channels';
|
import type * as channels from '../../protocol/channels';
|
||||||
import { APIRequestContext } from '../fetch';
|
import type { APIRequestContext } from '../fetch';
|
||||||
import type { CallMetadata } from '../instrumentation';
|
import type { CallMetadata } from '../instrumentation';
|
||||||
import type { Request, Response, Route } from '../network';
|
import type { Request, Response, Route } from '../network';
|
||||||
import { WebSocket } from '../network';
|
import { WebSocket } from '../network';
|
||||||
@ -172,14 +172,15 @@ export class APIRequestContextDispatcher extends Dispatcher<APIRequestContext, c
|
|||||||
return request ? APIRequestContextDispatcher.from(scope, request) : undefined;
|
return request ? APIRequestContextDispatcher.from(scope, request) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(scope: DispatcherScope, request: APIRequestContext) {
|
private constructor(parentScope: DispatcherScope, request: APIRequestContext) {
|
||||||
super(scope, request, 'APIRequestContext', {
|
// We will reparent these to the context below.
|
||||||
tracing: TracingDispatcher.from(scope, request.tracing()),
|
const tracing = TracingDispatcher.from(parentScope, request.tracing());
|
||||||
|
|
||||||
|
super(parentScope, request, 'APIRequestContext', {
|
||||||
|
tracing,
|
||||||
}, true);
|
}, true);
|
||||||
request.once(APIRequestContext.Events.Dispose, () => {
|
|
||||||
if (!this._disposed)
|
this.adopt(tracing);
|
||||||
super._dispose();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(params?: channels.APIRequestContextStorageStateParams): Promise<channels.APIRequestContextStorageStateResult> {
|
async storageState(params?: channels.APIRequestContextStorageStateParams): Promise<channels.APIRequestContextStorageStateResult> {
|
||||||
|
@ -42,22 +42,29 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel> imple
|
|||||||
_type_Page = true;
|
_type_Page = true;
|
||||||
private _page: Page;
|
private _page: Page;
|
||||||
|
|
||||||
static fromNullable(scope: DispatcherScope, page: Page | undefined): PageDispatcher | undefined {
|
static fromNullable(parentScope: DispatcherScope, page: Page | undefined): PageDispatcher | undefined {
|
||||||
if (!page)
|
if (!page)
|
||||||
return undefined;
|
return undefined;
|
||||||
const result = existingDispatcher<PageDispatcher>(page);
|
const result = existingDispatcher<PageDispatcher>(page);
|
||||||
return result || new PageDispatcher(scope, page);
|
return result || new PageDispatcher(parentScope, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(scope: DispatcherScope, page: Page) {
|
constructor(parentScope: DispatcherScope, page: Page) {
|
||||||
// TODO: theoretically, there could be more than one frame already.
|
// TODO: theoretically, there could be more than one frame already.
|
||||||
// If we split pageCreated and pageReady, there should be no main frame during pageCreated.
|
// If we split pageCreated and pageReady, there should be no main frame during pageCreated.
|
||||||
super(scope, page, 'Page', {
|
|
||||||
mainFrame: FrameDispatcher.from(scope, page.mainFrame()),
|
// We will reparent it to the page below using adopt.
|
||||||
|
const mainFrame = FrameDispatcher.from(parentScope, page.mainFrame());
|
||||||
|
|
||||||
|
super(parentScope, page, 'Page', {
|
||||||
|
mainFrame,
|
||||||
viewportSize: page.viewportSize() || undefined,
|
viewportSize: page.viewportSize() || undefined,
|
||||||
isClosed: page.isClosed(),
|
isClosed: page.isClosed(),
|
||||||
opener: PageDispatcher.fromNullable(scope, page.opener())
|
opener: PageDispatcher.fromNullable(parentScope, page.opener())
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
this.adopt(mainFrame);
|
||||||
|
|
||||||
this._page = page;
|
this._page = page;
|
||||||
this.addObjectListener(Page.Events.Close, () => {
|
this.addObjectListener(Page.Events.Close, () => {
|
||||||
this._dispatchEvent('close');
|
this._dispatchEvent('close');
|
||||||
@ -67,7 +74,8 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel> imple
|
|||||||
this.addObjectListener(Page.Events.Crash, () => this._dispatchEvent('crash'));
|
this.addObjectListener(Page.Events.Crash, () => this._dispatchEvent('crash'));
|
||||||
this.addObjectListener(Page.Events.Dialog, dialog => this._dispatchEvent('dialog', { dialog: new DialogDispatcher(this._scope, dialog) }));
|
this.addObjectListener(Page.Events.Dialog, dialog => this._dispatchEvent('dialog', { dialog: new DialogDispatcher(this._scope, dialog) }));
|
||||||
this.addObjectListener(Page.Events.Download, (download: Download) => {
|
this.addObjectListener(Page.Events.Download, (download: Download) => {
|
||||||
this._dispatchEvent('download', { url: download.url, suggestedFilename: download.suggestedFilename(), artifact: new ArtifactDispatcher(scope, download.artifact) });
|
// Artifact can outlive the page, so bind to the context scope.
|
||||||
|
this._dispatchEvent('download', { url: download.url, suggestedFilename: download.suggestedFilename(), artifact: new ArtifactDispatcher(parentScope, download.artifact) });
|
||||||
});
|
});
|
||||||
this.addObjectListener(Page.Events.FileChooser, (fileChooser: FileChooser) => this._dispatchEvent('fileChooser', {
|
this.addObjectListener(Page.Events.FileChooser, (fileChooser: FileChooser) => this._dispatchEvent('fileChooser', {
|
||||||
element: ElementHandleDispatcher.from(this._scope, fileChooser.element()),
|
element: ElementHandleDispatcher.from(this._scope, fileChooser.element()),
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as channels from '../../protocol/channels';
|
import type * as channels from '../../protocol/channels';
|
||||||
import { Tracing } from '../trace/recorder/tracing';
|
import type { Tracing } from '../trace/recorder/tracing';
|
||||||
import { ArtifactDispatcher } from './artifactDispatcher';
|
import { ArtifactDispatcher } from './artifactDispatcher';
|
||||||
import type { DispatcherScope } from './dispatcher';
|
import type { DispatcherScope } from './dispatcher';
|
||||||
import { Dispatcher, existingDispatcher } from './dispatcher';
|
import { Dispatcher, existingDispatcher } from './dispatcher';
|
||||||
@ -30,7 +30,6 @@ export class TracingDispatcher extends Dispatcher<Tracing, channels.TracingChann
|
|||||||
|
|
||||||
constructor(scope: DispatcherScope, tracing: Tracing) {
|
constructor(scope: DispatcherScope, tracing: Tracing) {
|
||||||
super(scope, tracing, 'Tracing', {}, true);
|
super(scope, tracing, 'Tracing', {}, true);
|
||||||
this.addObjectListener(Tracing.Events.Dispose, () => this._dispose());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async tracingStart(params: channels.TracingTracingStartParams): Promise<channels.TracingTracingStartResult> {
|
async tracingStart(params: channels.TracingTracingStartParams): Promise<channels.TracingTracingStartResult> {
|
||||||
|
@ -89,7 +89,7 @@ export abstract class APIRequestContext extends SdkObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(parent: SdkObject) {
|
constructor(parent: SdkObject) {
|
||||||
super(parent, 'fetchRequest');
|
super(parent, 'request-context');
|
||||||
APIRequestContext.allInstances.add(this);
|
APIRequestContext.allInstances.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +67,6 @@ type RecordingState = {
|
|||||||
const kScreencastOptions = { width: 800, height: 600, quality: 90 };
|
const kScreencastOptions = { width: 800, height: 600, quality: 90 };
|
||||||
|
|
||||||
export class Tracing extends SdkObject implements InstrumentationListener, SnapshotterDelegate, HarTracerDelegate {
|
export class Tracing extends SdkObject implements InstrumentationListener, SnapshotterDelegate, HarTracerDelegate {
|
||||||
static Events = {
|
|
||||||
Dispose: 'dispose',
|
|
||||||
};
|
|
||||||
|
|
||||||
private _writeChain = Promise.resolve();
|
private _writeChain = Promise.resolve();
|
||||||
private _snapshotter?: Snapshotter;
|
private _snapshotter?: Snapshotter;
|
||||||
private _harTracer: HarTracer;
|
private _harTracer: HarTracer;
|
||||||
@ -85,7 +81,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||||||
private _contextCreatedEvent: trace.ContextCreatedTraceEvent;
|
private _contextCreatedEvent: trace.ContextCreatedTraceEvent;
|
||||||
|
|
||||||
constructor(context: BrowserContext | APIRequestContext, tracesDir: string | undefined) {
|
constructor(context: BrowserContext | APIRequestContext, tracesDir: string | undefined) {
|
||||||
super(context, 'Tracing');
|
super(context, 'tracing');
|
||||||
this._context = context;
|
this._context = context;
|
||||||
this._precreatedTracesDir = tracesDir;
|
this._precreatedTracesDir = tracesDir;
|
||||||
this._harTracer = new HarTracer(context, null, this, {
|
this._harTracer = new HarTracer(context, null, this, {
|
||||||
@ -211,7 +207,6 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||||||
|
|
||||||
async dispose() {
|
async dispose() {
|
||||||
this._snapshotter?.dispose();
|
this._snapshotter?.dispose();
|
||||||
this.emit(Tracing.Events.Dispose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopChunk(params: TracingTracingStopChunkParams): Promise<{ artifact: Artifact | null, sourceEntries: NameValue[] | undefined }> {
|
async stopChunk(params: TracingTracingStopChunkParams): Promise<{ artifact: Artifact | null, sourceEntries: NameValue[] | undefined }> {
|
||||||
|
@ -69,13 +69,14 @@ it('should scope context handles', async ({ browserType, server, expectScopeStat
|
|||||||
{ _guid: 'browser-type', objects: [
|
{ _guid: 'browser-type', objects: [
|
||||||
{ _guid: 'browser', objects: [
|
{ _guid: 'browser', objects: [
|
||||||
{ _guid: 'browser-context', objects: [
|
{ _guid: 'browser-context', objects: [
|
||||||
{ _guid: 'frame', objects: [] },
|
{ _guid: 'page', objects: [
|
||||||
{ _guid: 'page', objects: [] },
|
{ _guid: 'frame', objects: [] },
|
||||||
|
] },
|
||||||
{ _guid: 'request', objects: [] },
|
{ _guid: 'request', objects: [] },
|
||||||
|
{ _guid: 'request-context', objects: [] },
|
||||||
{ _guid: 'response', objects: [] },
|
{ _guid: 'response', objects: [] },
|
||||||
|
{ _guid: 'tracing', objects: [] }
|
||||||
] },
|
] },
|
||||||
{ _guid: 'fetchRequest', objects: [] },
|
|
||||||
{ _guid: 'Tracing', objects: [] }
|
|
||||||
] },
|
] },
|
||||||
] },
|
] },
|
||||||
{ _guid: 'electron', objects: [] },
|
{ _guid: 'electron', objects: [] },
|
||||||
@ -163,9 +164,10 @@ it('should scope browser handles', async ({ browserType, expectScopeState }) =>
|
|||||||
{ _guid: 'browser-type', objects: [
|
{ _guid: 'browser-type', objects: [
|
||||||
{
|
{
|
||||||
_guid: 'browser', objects: [
|
_guid: 'browser', objects: [
|
||||||
{ _guid: 'browser-context', objects: [] },
|
{ _guid: 'browser-context', objects: [
|
||||||
{ _guid: 'fetchRequest', objects: [] },
|
{ _guid: 'request-context', objects: [] },
|
||||||
{ _guid: 'Tracing', objects: [] }
|
{ _guid: 'tracing', objects: [] },
|
||||||
|
] },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user