Skip to content

Commit

Permalink
fix: custom sessions should not emit targetcreated events (#8788)
Browse files Browse the repository at this point in the history
Closes #8787
  • Loading branch information
OrKoN committed Aug 16, 2022
1 parent 65a5ce8 commit 3fad05d
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 14 deletions.
7 changes: 5 additions & 2 deletions src/common/Browser.ts
Expand Up @@ -492,8 +492,11 @@ export class Browser extends EventEmitter {
session,
context,
this.#targetManager,
() => {
return this.#connection.createSession(targetInfo);
(isAutoAttachEmulated: boolean) => {
return this.#connection._createSession(
targetInfo,
isAutoAttachEmulated
);
},
this.#ignoreHTTPSErrors,
this.#defaultViewport ?? null,
Expand Down
10 changes: 8 additions & 2 deletions src/common/ChromeTargetManager.ts
Expand Up @@ -236,7 +236,7 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
// Special case (https://crbug.com/1338156): currently, shared_workers
// don't get auto-attached. This should be removed once the auto-attach
// works.
await this.#connection.createSession(event.targetInfo);
await this.#connection._createSession(event.targetInfo, true);
}
};

Expand Down Expand Up @@ -300,6 +300,10 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
.catch(debugError);
};

if (!this.#connection.isAutoAttached(targetInfo.targetId)) {
return;
}

// Special case for service workers: being attached to service workers will
// prevent them from ever being destroyed. Therefore, we silently detach
// from service workers unless the connection was manually created via
Expand Down Expand Up @@ -364,7 +368,9 @@ export class ChromeTargetManager extends EventEmitter implements TargetManager {
}

this.#targetsIdsForInit.delete(target._targetId);
this.emit(TargetManagerEmittedEvents.TargetAvailable, target);
if (!existingTarget) {
this.emit(TargetManagerEmittedEvents.TargetAvailable, target);
}
this.#finishInitializationIfReady();

// TODO: the browser might be shutting down here. What do we do with the
Expand Down
23 changes: 18 additions & 5 deletions src/common/Connection.ts
Expand Up @@ -229,23 +229,36 @@ export class Connection extends EventEmitter {
}

/**
* @param targetInfo - The target info
* @returns The CDP session that is created
* @internal
*/
async createSession(
targetInfo: Protocol.Target.TargetInfo
async _createSession(
targetInfo: Protocol.Target.TargetInfo,
isAutoAttachEmulated = true
): Promise<CDPSession> {
this.#manuallyAttached.add(targetInfo.targetId);
if (!isAutoAttachEmulated) {
this.#manuallyAttached.add(targetInfo.targetId);
}
const {sessionId} = await this.send('Target.attachToTarget', {
targetId: targetInfo.targetId,
flatten: true,
});
this.#manuallyAttached.delete(targetInfo.targetId);
const session = this.#sessions.get(sessionId);
if (!session) {
throw new Error('CDPSession creation failed.');
}
return session;
}

/**
* @param targetInfo - The target info
* @returns The CDP session that is created
*/
async createSession(
targetInfo: Protocol.Target.TargetInfo
): Promise<CDPSession> {
return await this._createSession(targetInfo, false);
}
}

/**
Expand Down
14 changes: 9 additions & 5 deletions src/common/Target.ts
Expand Up @@ -30,7 +30,7 @@ export class Target {
#browserContext: BrowserContext;
#session?: CDPSession;
#targetInfo: Protocol.Target.TargetInfo;
#sessionFactory: () => Promise<CDPSession>;
#sessionFactory: (isAutoAttachEmulated: boolean) => Promise<CDPSession>;
#ignoreHTTPSErrors: boolean;
#defaultViewport?: Viewport;
#pagePromise?: Promise<Page>;
Expand Down Expand Up @@ -76,7 +76,7 @@ export class Target {
session: CDPSession | undefined,
browserContext: BrowserContext,
targetManager: TargetManager,
sessionFactory: () => Promise<CDPSession>,
sessionFactory: (isAutoAttachEmulated: boolean) => Promise<CDPSession>,
ignoreHTTPSErrors: boolean,
defaultViewport: Viewport | null,
screenshotTaskQueue: TaskQueue,
Expand Down Expand Up @@ -132,7 +132,7 @@ export class Target {
* Creates a Chrome Devtools Protocol session attached to the target.
*/
createCDPSession(): Promise<CDPSession> {
return this.#sessionFactory();
return this.#sessionFactory(false);
}

/**
Expand All @@ -155,7 +155,9 @@ export class Target {
async page(): Promise<Page | null> {
if (this._isPageTargetCallback(this.#targetInfo) && !this.#pagePromise) {
this.#pagePromise = (
this.#session ? Promise.resolve(this.#session) : this.#sessionFactory()
this.#session
? Promise.resolve(this.#session)
: this.#sessionFactory(true)
).then(client => {
return Page._create(
client,
Expand All @@ -182,7 +184,9 @@ export class Target {
if (!this.#workerPromise) {
// TODO(einbinder): Make workers send their console logs.
this.#workerPromise = (
this.#session ? Promise.resolve(this.#session) : this.#sessionFactory()
this.#session
? Promise.resolve(this.#session)
: this.#sessionFactory(false)
).then(client => {
return new WebWorker(
client,
Expand Down
14 changes: 14 additions & 0 deletions test/src/CDPSession.spec.ts
Expand Up @@ -42,6 +42,20 @@ describeChromeOnly('Target.createCDPSession', function () {
});
expect(foo).toBe('bar');
});

it('should not report created targets for custom CDP sessions', async () => {
const {browser} = getTestState();
let called = 0;
browser.browserContexts()[0]!.on('targetcreated', async target => {
called++;
if (called > 1) {
throw new Error('Too many targets created');
}
await target.createCDPSession();
});
await browser.newPage();
});

it('should send events', async () => {
const {page, server} = getTestState();

Expand Down

0 comments on commit 3fad05d

Please sign in to comment.