chore: emit target configuration via CDP session (#10794)

This commit is contained in:
Alex Rudenko 2023-08-29 10:52:47 +02:00 committed by GitHub
parent 0eb5e93890
commit 599c0694ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 126 deletions

View File

@ -16,6 +16,6 @@
export const testChromeBuildId = '113.0.5672.0';
export const testChromiumBuildId = '1083080';
export const testFirefoxBuildId = '118.0a1';
export const testFirefoxBuildId = '119.0a1';
export const testChromeDriverBuildId = '115.0.5763.0';
export const testChromeHeadlessShellBuildId = '118.0.5950.0';

View File

@ -25,7 +25,6 @@ import {CDPSession, CDPSessionEmittedEvents, Connection} from './Connection.js';
import {EventEmitter} from './EventEmitter.js';
import {InitializationStatus, CDPTarget} from './Target.js';
import {
TargetInterceptor,
TargetFactory,
TargetManager,
TargetManagerEmittedEvents,
@ -80,11 +79,6 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
#targetFilterCallback: TargetFilterCallback | undefined;
#targetFactory: TargetFactory;
#targetInterceptors = new WeakMap<
CDPSession | Connection,
TargetInterceptor[]
>();
#attachedToTargetListenersBySession = new WeakMap<
CDPSession | Connection,
(event: Protocol.Target.AttachedToTargetEvent) => Promise<void>
@ -197,28 +191,6 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
return result;
}
addTargetInterceptor(
session: CDPSession | Connection,
interceptor: TargetInterceptor
): void {
const interceptors = this.#targetInterceptors.get(session) || [];
interceptors.push(interceptor);
this.#targetInterceptors.set(session, interceptors);
}
removeTargetInterceptor(
client: CDPSession | Connection,
interceptor: TargetInterceptor
): void {
const interceptors = this.#targetInterceptors.get(client) || [];
this.#targetInterceptors.set(
client,
interceptors.filter(currentInterceptor => {
return currentInterceptor !== interceptor;
})
);
}
#setupAttachmentListeners(session: CDPSession | Connection): void {
const listener = (event: Protocol.Target.AttachedToTargetEvent) => {
return this.#onAttachedToTarget(session, event);
@ -257,7 +229,6 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
#onSessionDetached = (session: CDPSession) => {
this.#removeAttachmentListeners(session);
this.#targetInterceptors.delete(session);
};
#onTargetCreated = async (event: Protocol.Target.TargetCreatedEvent) => {
@ -392,11 +363,11 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
return;
}
const existingTarget = this.#attachedTargetsByTargetId.has(
const isExistingTarget = this.#attachedTargetsByTargetId.has(
targetInfo.targetId
);
const target = existingTarget
const target = isExistingTarget
? this.#attachedTargetsByTargetId.get(targetInfo.targetId)!
: this.#targetFactory(
targetInfo,
@ -411,13 +382,13 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
return;
}
if (!existingTarget) {
if (!isExistingTarget) {
target._initialize();
}
this.#setupAttachmentListeners(session);
if (existingTarget) {
if (isExistingTarget) {
this.#attachedTargetsBySessionId.set(
session.id(),
this.#attachedTargetsByTargetId.get(targetInfo.targetId)!
@ -427,23 +398,10 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
this.#attachedTargetsBySessionId.set(session.id(), target);
}
for (const interceptor of this.#targetInterceptors.get(parentSession) ||
[]) {
if (!(parentSession instanceof Connection)) {
// Sanity check: if parent session is not a connection, it should be
// present in #attachedTargetsBySessionId.
assert(this.#attachedTargetsBySessionId.has(parentSession.id()));
}
interceptor(
target,
parentSession instanceof Connection
? null
: this.#attachedTargetsBySessionId.get(parentSession.id())!
);
}
parentSession.emit(CDPSessionEmittedEvents.Ready, session);
this.#targetsIdsForInit.delete(target._targetId);
if (!existingTarget && isTargetExposed(target)) {
if (!isExistingTarget && isTargetExposed(target)) {
this.emit(TargetManagerEmittedEvents.TargetAvailable, target);
}
this.#finishInitializationIfReady();

View File

@ -431,6 +431,11 @@ export interface CDPSessionOnMessageObject {
export const CDPSessionEmittedEvents = {
Disconnected: Symbol('CDPSession.Disconnected'),
Swapped: Symbol('CDPSession.Swapped'),
/**
* Emitted when the session is ready to be configured during the auto-attach
* process. Right after the event is handled, the session will be resumed.
*/
Ready: Symbol('CDPSession.Ready'),
} as const;
/**

View File

@ -20,12 +20,11 @@ import {TargetFilterCallback} from '../api/Browser.js';
import {assert} from '../util/assert.js';
import {Deferred} from '../util/Deferred.js';
import {CDPSession, Connection} from './Connection.js';
import {CDPSession, CDPSessionEmittedEvents, Connection} from './Connection.js';
import {EventEmitter} from './EventEmitter.js';
import {CDPTarget} from './Target.js';
import {
TargetFactory,
TargetInterceptor,
TargetManagerEmittedEvents,
TargetManager,
} from './TargetManager.js';
@ -79,11 +78,6 @@ export class FirefoxTargetManager
#targetFilterCallback: TargetFilterCallback | undefined;
#targetFactory: TargetFactory;
#targetInterceptors = new WeakMap<
CDPSession | Connection,
TargetInterceptor[]
>();
#attachedToTargetListenersBySession = new WeakMap<
CDPSession | Connection,
(event: Protocol.Target.AttachedToTargetEvent) => Promise<void>
@ -108,28 +102,6 @@ export class FirefoxTargetManager
this.setupAttachmentListeners(this.#connection);
}
addTargetInterceptor(
client: CDPSession | Connection,
interceptor: TargetInterceptor
): void {
const interceptors = this.#targetInterceptors.get(client) || [];
interceptors.push(interceptor);
this.#targetInterceptors.set(client, interceptors);
}
removeTargetInterceptor(
client: CDPSession | Connection,
interceptor: TargetInterceptor
): void {
const interceptors = this.#targetInterceptors.get(client) || [];
this.#targetInterceptors.set(
client,
interceptors.filter(currentInterceptor => {
return currentInterceptor !== interceptor;
})
);
}
setupAttachmentListeners(session: CDPSession | Connection): void {
const listener = (event: Protocol.Target.AttachedToTargetEvent) => {
return this.#onAttachedToTarget(session, event);
@ -141,7 +113,6 @@ export class FirefoxTargetManager
#onSessionDetached = (session: CDPSession) => {
this.removeSessionListeners(session);
this.#targetInterceptors.delete(session);
this.#availableTargetsBySessionId.delete(session.id());
};
@ -236,17 +207,7 @@ export class FirefoxTargetManager
this.#availableTargetsByTargetId.get(targetInfo.targetId)!
);
for (const hook of this.#targetInterceptors.get(parentSession) || []) {
if (!(parentSession instanceof Connection)) {
assert(this.#availableTargetsBySessionId.has(parentSession.id()));
}
await hook(
target,
parentSession instanceof Connection
? null
: this.#availableTargetsBySessionId.get(parentSession.id())!
);
}
parentSession.emit(CDPSessionEmittedEvents.Ready, session);
};
#finishInitializationIfReady(targetId: string): void {

View File

@ -332,9 +332,7 @@ export class CDPPage extends Page {
}
#setupEventListeners() {
this.#target
._targetManager()
.addTargetInterceptor(this.#client, this.#onAttachedToTarget);
this.#client.on(CDPSessionEmittedEvents.Ready, this.#onAttachedToTarget);
this.#target
._targetManager()
@ -355,9 +353,10 @@ export class CDPPage extends Page {
this.#target._isClosedDeferred
.valueOrThrow()
.then(() => {
this.#target
._targetManager()
.removeTargetInterceptor(this.#client, this.#onAttachedToTarget);
this.#client.off(
CDPSessionEmittedEvents.Ready,
this.#onAttachedToTarget
);
this.#target
._targetManager()
@ -382,28 +381,19 @@ export class CDPPage extends Page {
this.emit(PageEmittedEvents.WorkerDestroyed, worker);
};
#onAttachedToTarget = (createdTarget: CDPTarget) => {
this.#frameManager.onAttachedToTarget(createdTarget);
if (createdTarget._getTargetInfo().type === 'worker') {
const session = createdTarget._session();
assert(session);
#onAttachedToTarget = (session: CDPSessionImpl) => {
this.#frameManager.onAttachedToTarget(session._target());
if (session._target()._getTargetInfo().type === 'worker') {
const worker = new WebWorker(
session,
createdTarget.url(),
session._target().url(),
this.#addConsoleMessage.bind(this),
this.#handleException.bind(this)
);
this.#workers.set(session.id(), worker);
this.emit(PageEmittedEvents.WorkerCreated, worker);
}
if (createdTarget._session()) {
this.#target
._targetManager()
.addTargetInterceptor(
createdTarget._session()!,
this.#onAttachedToTarget
);
}
session.on(CDPSessionEmittedEvents.Ready, this.#onAttachedToTarget);
};
async #initialize(): Promise<void> {

View File

@ -29,14 +29,6 @@ export type TargetFactory = (
parentSession?: CDPSession
) => CDPTarget;
/**
* @internal
*/
export type TargetInterceptor = (
createdTarget: CDPTarget,
parentTarget: CDPTarget | null
) => void;
/**
* TargetManager encapsulates all interactions with CDP targets and is
* responsible for coordinating the configuration of targets with the rest of
@ -52,14 +44,6 @@ export interface TargetManager extends EventEmitter {
getAvailableTargets(): Map<string, CDPTarget>;
initialize(): Promise<void>;
dispose(): void;
addTargetInterceptor(
session: CDPSession,
interceptor: TargetInterceptor
): void;
removeTargetInterceptor(
session: CDPSession,
interceptor: TargetInterceptor
): void;
}
/**