mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 05:37:20 +03:00
chore: remove connection / session redundancy (#51)
This commit is contained in:
parent
7783400156
commit
c26166203e
@ -47,15 +47,13 @@ export class Browser extends EventEmitter {
|
||||
defaultViewport: Viewport | null,
|
||||
process: childProcess.ChildProcess | null,
|
||||
closeCallback?: (() => Promise<void>)) {
|
||||
const session = await connection.createBrowserSession();
|
||||
const browser = new Browser(connection, session, contextIds, ignoreHTTPSErrors, defaultViewport, process, closeCallback);
|
||||
await session.send('Target.setDiscoverTargets', {discover: true});
|
||||
const browser = new Browser(connection, contextIds, ignoreHTTPSErrors, defaultViewport, process, closeCallback);
|
||||
await connection.rootSession.send('Target.setDiscoverTargets', { discover: true });
|
||||
return browser;
|
||||
}
|
||||
|
||||
constructor(
|
||||
connection: Connection,
|
||||
client: CDPSession,
|
||||
contextIds: string[],
|
||||
ignoreHTTPSErrors: boolean,
|
||||
defaultViewport: Viewport | null,
|
||||
@ -63,7 +61,7 @@ export class Browser extends EventEmitter {
|
||||
closeCallback?: (() => Promise<void>)) {
|
||||
super();
|
||||
this._connection = connection;
|
||||
this._client = client;
|
||||
this._client = connection.rootSession;
|
||||
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||
this._defaultViewport = defaultViewport;
|
||||
this._process = process;
|
||||
@ -151,13 +149,17 @@ export class Browser extends EventEmitter {
|
||||
}
|
||||
|
||||
async _createPageInContext(contextId: string | null): Promise<Page> {
|
||||
const {targetId} = await this._connection.send('Target.createTarget', {url: 'about:blank', browserContextId: contextId || undefined});
|
||||
const { targetId } = await this._client.send('Target.createTarget', { url: 'about:blank', browserContextId: contextId || undefined });
|
||||
const target = await this._targets.get(targetId);
|
||||
assert(await target._initializedPromise, 'Failed to create target for page');
|
||||
const page = await target.page();
|
||||
return page;
|
||||
}
|
||||
|
||||
async _closeTarget(target: Target) {
|
||||
await this._client.send('Target.closeTarget', { targetId: target._targetId });
|
||||
}
|
||||
|
||||
targets(): Target[] {
|
||||
return Array.from(this._targets.values()).filter(target => target._isInitialized);
|
||||
}
|
||||
@ -222,6 +224,6 @@ export class Browser extends EventEmitter {
|
||||
}
|
||||
|
||||
_getVersion(): Promise<any> {
|
||||
return this._connection.send('Browser.getVersion');
|
||||
return this._client.send('Browser.getVersion');
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,11 @@ export const ConnectionEvents = {
|
||||
export class Connection extends EventEmitter {
|
||||
private _url: string;
|
||||
private _lastId = 0;
|
||||
private _callbacks = new Map<number, {resolve:(o: any) => void, reject: (e: Error) => void, error: Error, method: string}>();
|
||||
private _delay: number;
|
||||
private _transport: ConnectionTransport;
|
||||
private _sessions = new Map<string, CDPSession>();
|
||||
readonly rootSession: CDPSession;
|
||||
_closed = false;
|
||||
on: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
addListener: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
off: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
removeListener: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
once: <T extends keyof Protocol.Events | symbol>(event: T, listener: (payload: T extends symbol ? any : Protocol.Events[T extends keyof Protocol.Events ? T : never]) => void) => this;
|
||||
|
||||
constructor(url: string, transport: ConnectionTransport, delay: number | undefined = 0) {
|
||||
super();
|
||||
@ -49,6 +44,8 @@ export class Connection extends EventEmitter {
|
||||
this._transport = transport;
|
||||
this._transport.onmessage = this._onMessage.bind(this);
|
||||
this._transport.onclose = this._onClose.bind(this);
|
||||
this.rootSession = new CDPSession(this, 'browser', '');
|
||||
this._sessions.set('', this.rootSession);
|
||||
}
|
||||
|
||||
static fromSession(session: CDPSession): Connection {
|
||||
@ -63,21 +60,14 @@ export class Connection extends EventEmitter {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
send<T extends keyof Protocol.CommandParameters>(
|
||||
method: T,
|
||||
params?: Protocol.CommandParameters[T]
|
||||
): Promise<Protocol.CommandReturnValues[T]> {
|
||||
const id = this._rawSend({method, params});
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new Error(), method});
|
||||
});
|
||||
}
|
||||
|
||||
_rawSend(message: any): number {
|
||||
_rawSend(sessionId: string, message: any): number {
|
||||
const id = ++this._lastId;
|
||||
message = JSON.stringify(Object.assign({}, message, {id}));
|
||||
debugProtocol('SEND ► ' + message);
|
||||
this._transport.send(message);
|
||||
message.id = id;
|
||||
if (sessionId)
|
||||
message.sessionId = sessionId;
|
||||
const data = JSON.stringify(message);
|
||||
debugProtocol('SEND ► ' + data);
|
||||
this._transport.send(data);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -97,23 +87,9 @@ export class Connection extends EventEmitter {
|
||||
this._sessions.delete(object.params.sessionId);
|
||||
}
|
||||
}
|
||||
if (object.sessionId) {
|
||||
const session = this._sessions.get(object.sessionId);
|
||||
if (session)
|
||||
session._onMessage(object);
|
||||
} else if (object.id) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
// Callbacks could be all rejected if someone has called `.dispose()`.
|
||||
if (callback) {
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error)
|
||||
callback.reject(createProtocolError(callback.error, callback.method, object));
|
||||
else
|
||||
callback.resolve(object.result);
|
||||
}
|
||||
} else {
|
||||
this.emit(object.method, object.params);
|
||||
}
|
||||
const session = this._sessions.get(object.sessionId || '');
|
||||
if (session)
|
||||
session._onMessage(object);
|
||||
}
|
||||
|
||||
_onClose() {
|
||||
@ -122,9 +98,6 @@ export class Connection extends EventEmitter {
|
||||
this._closed = true;
|
||||
this._transport.onmessage = null;
|
||||
this._transport.onclose = null;
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(rewriteError(callback.error, `Protocol error (${callback.method}): Target closed.`));
|
||||
this._callbacks.clear();
|
||||
for (const session of this._sessions.values())
|
||||
session._onClosed();
|
||||
this._sessions.clear();
|
||||
@ -137,15 +110,13 @@ export class Connection extends EventEmitter {
|
||||
}
|
||||
|
||||
async createSession(targetInfo: Protocol.Target.TargetInfo): Promise<CDPSession> {
|
||||
const {sessionId} = await this.send('Target.attachToTarget', {targetId: targetInfo.targetId, flatten: true});
|
||||
const { sessionId } = await this.rootSession.send('Target.attachToTarget', { targetId: targetInfo.targetId, flatten: true });
|
||||
return this._sessions.get(sessionId);
|
||||
}
|
||||
|
||||
async createBrowserSession(): Promise<CDPSession> {
|
||||
const { sessionId } = await this.send('Target.attachToBrowserTarget');
|
||||
const session = new CDPSession(this, 'browser', sessionId);
|
||||
this._sessions.set(sessionId, session);
|
||||
return session;
|
||||
const { sessionId } = await this.rootSession.send('Target.attachToBrowserTarget');
|
||||
return this._sessions.get(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +148,7 @@ export class CDPSession extends EventEmitter {
|
||||
): Promise<Protocol.CommandReturnValues[T]> {
|
||||
if (!this._connection)
|
||||
return Promise.reject(new Error(`Protocol error (${method}): Session closed. Most likely the ${this._targetType} has been closed.`));
|
||||
const id = this._connection._rawSend({sessionId: this._sessionId, method, params});
|
||||
const id = this._connection._rawSend(this._sessionId, { method, params });
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new Error(), method});
|
||||
});
|
||||
@ -200,7 +171,7 @@ export class CDPSession extends EventEmitter {
|
||||
async detach() {
|
||||
if (!this._connection)
|
||||
throw new Error(`Session already detached. Most likely the ${this._targetType} has been closed.`);
|
||||
await this._connection.send('Target.detachFromTarget', {sessionId: this._sessionId});
|
||||
await this._connection.rootSession.send('Target.detachFromTarget', { sessionId: this._sessionId });
|
||||
}
|
||||
|
||||
_onClosed() {
|
||||
|
@ -188,7 +188,7 @@ export class Launcher {
|
||||
killChrome();
|
||||
} else if (connection) {
|
||||
// Attempt to close chrome gracefully
|
||||
connection.send('Browser.close').catch(error => {
|
||||
connection.rootSession.send('Browser.close').catch(error => {
|
||||
debugError(error);
|
||||
killChrome();
|
||||
});
|
||||
@ -273,7 +273,7 @@ export class Launcher {
|
||||
connection = new Connection(connectionURL, connectionTransport, slowMo);
|
||||
}
|
||||
|
||||
const {browserContextIds} = await connection.send('Target.getBrowserContexts');
|
||||
const { browserContextIds } = await connection.rootSession.send('Target.getBrowserContexts');
|
||||
return Browser.create(connection, browserContextIds, ignoreHTTPSErrors, defaultViewport, null, () => connection.send('Browser.close').catch(debugError));
|
||||
}
|
||||
|
||||
|
@ -678,7 +678,7 @@ export class Page extends EventEmitter {
|
||||
if (runBeforeUnload) {
|
||||
await this._client.send('Page.close');
|
||||
} else {
|
||||
await this._client._connection.send('Target.closeTarget', { targetId: this._target._targetId });
|
||||
await this.browser()._closeTarget(this._target);
|
||||
await this._target._isClosedPromise;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user