mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-17 16:21:55 +03:00
chore(targets): create page targets only when attached to them (#1278)
This commit is contained in:
parent
e650628e3d
commit
0fbc7af26d
@ -102,21 +102,19 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
|||||||
return createPageInNewContext(this, options);
|
return createPageInNewContext(this, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onAttachedToTarget(event: Protocol.Target.attachedToTargetPayload) {
|
async _onAttachedToTarget({targetInfo, sessionId, waitingForDebugger}: Protocol.Target.attachedToTargetPayload) {
|
||||||
if (!CRTarget.isPageType(event.targetInfo.type))
|
const session = this._connection.session(sessionId)!;
|
||||||
return;
|
if (!CRTarget.isPageType(targetInfo.type)) {
|
||||||
const target = this._targets.get(event.targetInfo.targetId);
|
assert(targetInfo.type === 'service_worker' || targetInfo.type === 'browser' || targetInfo.type === 'other');
|
||||||
const session = this._connection.session(event.sessionId)!;
|
if (waitingForDebugger) {
|
||||||
await target!.initializePageSession(session).catch(debugError);
|
// Ideally, detaching should resume any target, but there is a bug in the backend.
|
||||||
|
session.send('Runtime.runIfWaitingForDebugger').catch(debugError).then(() => {
|
||||||
|
this._session.send('Target.detachFromTarget', { sessionId }).catch(debugError);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
async _targetCreated({targetInfo}: Protocol.Target.targetCreatedPayload) {
|
}
|
||||||
const {browserContextId} = targetInfo;
|
const { context, target } = this._createTarget(targetInfo, session);
|
||||||
const context = (browserContextId && this._contexts.has(browserContextId)) ? this._contexts.get(browserContextId)! : this._defaultContext;
|
|
||||||
const target = new CRTarget(this, targetInfo, context, () => this._connection.createSession(targetInfo));
|
|
||||||
assert(!this._targets.has(targetInfo.targetId), 'Target should not exist before targetCreated');
|
|
||||||
this._targets.set(targetInfo.targetId, target);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (targetInfo.type) {
|
switch (targetInfo.type) {
|
||||||
case 'page': {
|
case 'page': {
|
||||||
@ -135,11 +133,6 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
|||||||
context.emit(Events.CRBrowserContext.BackgroundPage, event);
|
context.emit(Events.CRBrowserContext.BackgroundPage, event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'service_worker': {
|
|
||||||
const serviceWorker = await target.serviceWorker();
|
|
||||||
context.emit(Events.CRBrowserContext.ServiceWorker, serviceWorker);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do not dispatch the event if initialization failed.
|
// Do not dispatch the event if initialization failed.
|
||||||
@ -147,15 +140,35 @@ export class CRBrowser extends platform.EventEmitter implements Browser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _targetCreated({targetInfo}: Protocol.Target.targetCreatedPayload) {
|
||||||
|
if (targetInfo.type !== 'service_worker')
|
||||||
|
return;
|
||||||
|
const { context, target } = this._createTarget(targetInfo, null);
|
||||||
|
const serviceWorker = await target.serviceWorker();
|
||||||
|
context.emit(Events.CRBrowserContext.ServiceWorker, serviceWorker);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _createTarget(targetInfo: Protocol.Target.TargetInfo, session: CRSession | null) {
|
||||||
|
const {browserContextId} = targetInfo;
|
||||||
|
const context = (browserContextId && this._contexts.has(browserContextId)) ? this._contexts.get(browserContextId)! : this._defaultContext;
|
||||||
|
const target = new CRTarget(this, targetInfo, context, session, () => this._connection.createSession(targetInfo));
|
||||||
|
assert(!this._targets.has(targetInfo.targetId), 'Target should not exist before targetCreated');
|
||||||
|
this._targets.set(targetInfo.targetId, target);
|
||||||
|
return { context, target };
|
||||||
|
}
|
||||||
|
|
||||||
async _targetDestroyed(event: { targetId: string; }) {
|
async _targetDestroyed(event: { targetId: string; }) {
|
||||||
const target = this._targets.get(event.targetId)!;
|
const target = this._targets.get(event.targetId)!;
|
||||||
|
if (!target)
|
||||||
|
return;
|
||||||
this._targets.delete(event.targetId);
|
this._targets.delete(event.targetId);
|
||||||
target._didClose();
|
target._didClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_targetInfoChanged(event: Protocol.Target.targetInfoChangedPayload) {
|
_targetInfoChanged(event: Protocol.Target.targetInfoChangedPayload) {
|
||||||
const target = this._targets.get(event.targetInfo.targetId)!;
|
const target = this._targets.get(event.targetInfo.targetId)!;
|
||||||
assert(target, 'target should exist before targetInfoChanged');
|
if (!target)
|
||||||
|
return;
|
||||||
target._targetInfoChanged(event.targetInfo);
|
target._targetInfoChanged(event.targetInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import { CRBrowser, CRBrowserContext } from './crBrowser';
|
|||||||
import { CRSession, CRSessionEvents } from './crConnection';
|
import { CRSession, CRSessionEvents } from './crConnection';
|
||||||
import { Page, Worker } from '../page';
|
import { Page, Worker } from '../page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { debugError } from '../helper';
|
import { debugError, assert } from '../helper';
|
||||||
import { CRPage } from './crPage';
|
import { CRPage } from './crPage';
|
||||||
import { CRExecutionContext } from './crExecutionContext';
|
import { CRExecutionContext } from './crExecutionContext';
|
||||||
|
|
||||||
@ -48,14 +48,21 @@ export class CRTarget {
|
|||||||
browser: CRBrowser,
|
browser: CRBrowser,
|
||||||
targetInfo: Protocol.Target.TargetInfo,
|
targetInfo: Protocol.Target.TargetInfo,
|
||||||
browserContext: CRBrowserContext,
|
browserContext: CRBrowserContext,
|
||||||
|
session: CRSession | null,
|
||||||
sessionFactory: () => Promise<CRSession>) {
|
sessionFactory: () => Promise<CRSession>) {
|
||||||
this._targetInfo = targetInfo;
|
this._targetInfo = targetInfo;
|
||||||
this._browser = browser;
|
this._browser = browser;
|
||||||
this._browserContext = browserContext;
|
this._browserContext = browserContext;
|
||||||
this._targetId = targetInfo.targetId;
|
this._targetId = targetInfo.targetId;
|
||||||
this.sessionFactory = sessionFactory;
|
this.sessionFactory = sessionFactory;
|
||||||
if (CRTarget.isPageType(targetInfo.type))
|
if (CRTarget.isPageType(targetInfo.type)) {
|
||||||
this._pagePromise = new Promise<Page | Error>(f => this._pagePromiseCallback = f);
|
assert(session, 'Page target must be created with existing session');
|
||||||
|
this._crPage = new CRPage(session, this._browser, this._browserContext);
|
||||||
|
const page = this._crPage.page();
|
||||||
|
(page as any)[targetSymbol] = this;
|
||||||
|
session.once(CRSessionEvents.Disconnected, () => page._didDisconnect());
|
||||||
|
this._pagePromise = this._crPage.initialize().then(() => page).catch(e => e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_didClose() {
|
_didClose() {
|
||||||
@ -63,23 +70,10 @@ export class CRTarget {
|
|||||||
this._crPage.didClose();
|
this._crPage.didClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async initializePageSession(session: CRSession) {
|
|
||||||
this._crPage = new CRPage(session, this._browser, this._browserContext);
|
|
||||||
const page = this._crPage.page();
|
|
||||||
(page as any)[targetSymbol] = this;
|
|
||||||
session.once(CRSessionEvents.Disconnected, () => page._didDisconnect());
|
|
||||||
try {
|
|
||||||
await this._crPage.initialize();
|
|
||||||
this._pagePromiseCallback!(page);
|
|
||||||
} catch (e) {
|
|
||||||
this._pagePromiseCallback!(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async pageOrError(): Promise<Page | Error> {
|
async pageOrError(): Promise<Page | Error> {
|
||||||
if (this._targetInfo.type !== 'page' && this._targetInfo.type !== 'background_page')
|
if (CRTarget.isPageType(this.type()))
|
||||||
throw new Error('Not a page.');
|
|
||||||
return this._pagePromise!;
|
return this._pagePromise!;
|
||||||
|
throw new Error('Not a page.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async serviceWorker(): Promise<Worker | null> {
|
async serviceWorker(): Promise<Worker | null> {
|
||||||
|
Loading…
Reference in New Issue
Block a user