refactor: consolidate all events in Events.js (#3772)
This will allow us to break all dependency cycles that were forcing us to put many things in a single file (e.g. ExecutionContext and ElementHandle).
This commit is contained in:
parent
71edfc779b
commit
4e9e3bc614
@ -18,7 +18,7 @@ const { helper, assert } = require('./helper');
|
|||||||
const {Target} = require('./Target');
|
const {Target} = require('./Target');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const {TaskQueue} = require('./TaskQueue');
|
const {TaskQueue} = require('./TaskQueue');
|
||||||
const {Connection} = require('./Connection');
|
const {Events} = require('./Events');
|
||||||
|
|
||||||
class Browser extends EventEmitter {
|
class Browser extends EventEmitter {
|
||||||
/**
|
/**
|
||||||
@ -46,7 +46,7 @@ class Browser extends EventEmitter {
|
|||||||
|
|
||||||
/** @type {Map<string, Target>} */
|
/** @type {Map<string, Target>} */
|
||||||
this._targets = new Map();
|
this._targets = new Map();
|
||||||
this._connection.on(Connection.Events.Disconnected, () => this.emit(Browser.Events.Disconnected));
|
this._connection.on(Events.Connection.Disconnected, () => this.emit(Events.Browser.Disconnected));
|
||||||
this._connection.on('Target.targetCreated', this._targetCreated.bind(this));
|
this._connection.on('Target.targetCreated', this._targetCreated.bind(this));
|
||||||
this._connection.on('Target.targetDestroyed', this._targetDestroyed.bind(this));
|
this._connection.on('Target.targetDestroyed', this._targetDestroyed.bind(this));
|
||||||
this._connection.on('Target.targetInfoChanged', this._targetInfoChanged.bind(this));
|
this._connection.on('Target.targetInfoChanged', this._targetInfoChanged.bind(this));
|
||||||
@ -118,8 +118,8 @@ class Browser extends EventEmitter {
|
|||||||
this._targets.set(event.targetInfo.targetId, target);
|
this._targets.set(event.targetInfo.targetId, target);
|
||||||
|
|
||||||
if (await target._initializedPromise) {
|
if (await target._initializedPromise) {
|
||||||
this.emit(Browser.Events.TargetCreated, target);
|
this.emit(Events.Browser.TargetCreated, target);
|
||||||
context.emit(BrowserContext.Events.TargetCreated, target);
|
context.emit(Events.BrowserContext.TargetCreated, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,8 +132,8 @@ class Browser extends EventEmitter {
|
|||||||
this._targets.delete(event.targetId);
|
this._targets.delete(event.targetId);
|
||||||
target._closedCallback();
|
target._closedCallback();
|
||||||
if (await target._initializedPromise) {
|
if (await target._initializedPromise) {
|
||||||
this.emit(Browser.Events.TargetDestroyed, target);
|
this.emit(Events.Browser.TargetDestroyed, target);
|
||||||
target.browserContext().emit(BrowserContext.Events.TargetDestroyed, target);
|
target.browserContext().emit(Events.BrowserContext.TargetDestroyed, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +147,8 @@ class Browser extends EventEmitter {
|
|||||||
const wasInitialized = target._isInitialized;
|
const wasInitialized = target._isInitialized;
|
||||||
target._targetInfoChanged(event.targetInfo);
|
target._targetInfoChanged(event.targetInfo);
|
||||||
if (wasInitialized && previousURL !== target.url()) {
|
if (wasInitialized && previousURL !== target.url()) {
|
||||||
this.emit(Browser.Events.TargetChanged, target);
|
this.emit(Events.Browser.TargetChanged, target);
|
||||||
target.browserContext().emit(BrowserContext.Events.TargetChanged, target);
|
target.browserContext().emit(Events.BrowserContext.TargetChanged, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,15 +206,15 @@ class Browser extends EventEmitter {
|
|||||||
return existingTarget;
|
return existingTarget;
|
||||||
let resolve;
|
let resolve;
|
||||||
const targetPromise = new Promise(x => resolve = x);
|
const targetPromise = new Promise(x => resolve = x);
|
||||||
this.on(Browser.Events.TargetCreated, check);
|
this.on(Events.Browser.TargetCreated, check);
|
||||||
this.on(Browser.Events.TargetChanged, check);
|
this.on(Events.Browser.TargetChanged, check);
|
||||||
try {
|
try {
|
||||||
if (!timeout)
|
if (!timeout)
|
||||||
return await targetPromise;
|
return await targetPromise;
|
||||||
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
|
return await helper.waitWithTimeout(targetPromise, 'target', timeout);
|
||||||
} finally {
|
} finally {
|
||||||
this.removeListener(Browser.Events.TargetCreated, check);
|
this.removeListener(Events.Browser.TargetCreated, check);
|
||||||
this.removeListener(Browser.Events.TargetChanged, check);
|
this.removeListener(Events.Browser.TargetChanged, check);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -268,14 +268,6 @@ class Browser extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @enum {string} */
|
|
||||||
Browser.Events = {
|
|
||||||
TargetCreated: 'targetcreated',
|
|
||||||
TargetDestroyed: 'targetdestroyed',
|
|
||||||
TargetChanged: 'targetchanged',
|
|
||||||
Disconnected: 'disconnected'
|
|
||||||
};
|
|
||||||
|
|
||||||
class BrowserContext extends EventEmitter {
|
class BrowserContext extends EventEmitter {
|
||||||
/**
|
/**
|
||||||
* @param {!Puppeteer.Connection} connection
|
* @param {!Puppeteer.Connection} connection
|
||||||
@ -381,13 +373,6 @@ class BrowserContext extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @enum {string} */
|
|
||||||
BrowserContext.Events = {
|
|
||||||
TargetCreated: 'targetcreated',
|
|
||||||
TargetDestroyed: 'targetdestroyed',
|
|
||||||
TargetChanged: 'targetchanged',
|
|
||||||
};
|
|
||||||
|
|
||||||
helper.tracePublicAPI(BrowserContext);
|
helper.tracePublicAPI(BrowserContext);
|
||||||
helper.tracePublicAPI(Browser);
|
helper.tracePublicAPI(Browser);
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const {helper, assert} = require('./helper');
|
const {helper, assert} = require('./helper');
|
||||||
|
const {Events} = require('./Events');
|
||||||
const debugProtocol = require('debug')('puppeteer:protocol');
|
const debugProtocol = require('debug')('puppeteer:protocol');
|
||||||
const debugSession = require('debug')('puppeteer:session');
|
const debugSession = require('debug')('puppeteer:session');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
@ -120,7 +121,7 @@ class Connection extends EventEmitter {
|
|||||||
for (const session of this._sessions.values())
|
for (const session of this._sessions.values())
|
||||||
session._onClosed();
|
session._onClosed();
|
||||||
this._sessions.clear();
|
this._sessions.clear();
|
||||||
this.emit(Connection.Events.Disconnected);
|
this.emit(Events.Connection.Disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
@ -140,10 +141,6 @@ class Connection extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection.Events = {
|
|
||||||
Disconnected: Symbol('Connection.Events.Disconnected'),
|
|
||||||
};
|
|
||||||
|
|
||||||
class CDPSession extends EventEmitter {
|
class CDPSession extends EventEmitter {
|
||||||
/**
|
/**
|
||||||
* @param {!Connection|!CDPSession} connection
|
* @param {!Connection|!CDPSession} connection
|
||||||
@ -228,7 +225,7 @@ class CDPSession extends EventEmitter {
|
|||||||
callback.reject(rewriteError(callback.error, `Protocol error (${callback.method}): Target closed.`));
|
callback.reject(rewriteError(callback.error, `Protocol error (${callback.method}): Target closed.`));
|
||||||
this._callbacks.clear();
|
this._callbacks.clear();
|
||||||
this._connection = null;
|
this._connection = null;
|
||||||
this.emit(CDPSession.Events.Disconnected);
|
this.emit(Events.CDPSession.Disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,10 +239,6 @@ class CDPSession extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CDPSession.Events = {
|
|
||||||
Disconnected: Symbol('CDPSession.Events.Disconnected'),
|
|
||||||
};
|
|
||||||
|
|
||||||
helper.tracePublicAPI(CDPSession);
|
helper.tracePublicAPI(CDPSession);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
80
lib/Events.js
Normal file
80
lib/Events.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Events = {
|
||||||
|
Page: {
|
||||||
|
Close: 'close',
|
||||||
|
Console: 'console',
|
||||||
|
Dialog: 'dialog',
|
||||||
|
DOMContentLoaded: 'domcontentloaded',
|
||||||
|
Error: 'error',
|
||||||
|
// Can't use just 'error' due to node.js special treatment of error events.
|
||||||
|
// @see https://nodejs.org/api/events.html#events_error_events
|
||||||
|
PageError: 'pageerror',
|
||||||
|
Request: 'request',
|
||||||
|
Response: 'response',
|
||||||
|
RequestFailed: 'requestfailed',
|
||||||
|
RequestFinished: 'requestfinished',
|
||||||
|
FrameAttached: 'frameattached',
|
||||||
|
FrameDetached: 'framedetached',
|
||||||
|
FrameNavigated: 'framenavigated',
|
||||||
|
Load: 'load',
|
||||||
|
Metrics: 'metrics',
|
||||||
|
Popup: 'popup',
|
||||||
|
WorkerCreated: 'workercreated',
|
||||||
|
WorkerDestroyed: 'workerdestroyed',
|
||||||
|
},
|
||||||
|
|
||||||
|
Browser: {
|
||||||
|
TargetCreated: 'targetcreated',
|
||||||
|
TargetDestroyed: 'targetdestroyed',
|
||||||
|
TargetChanged: 'targetchanged',
|
||||||
|
Disconnected: 'disconnected'
|
||||||
|
},
|
||||||
|
|
||||||
|
BrowserContext: {
|
||||||
|
TargetCreated: 'targetcreated',
|
||||||
|
TargetDestroyed: 'targetdestroyed',
|
||||||
|
TargetChanged: 'targetchanged',
|
||||||
|
},
|
||||||
|
|
||||||
|
NetworkManager: {
|
||||||
|
Request: Symbol('Events.NetworkManager.Request'),
|
||||||
|
Response: Symbol('Events.NetworkManager.Response'),
|
||||||
|
RequestFailed: Symbol('Events.NetworkManager.RequestFailed'),
|
||||||
|
RequestFinished: Symbol('Events.NetworkManager.RequestFinished'),
|
||||||
|
},
|
||||||
|
|
||||||
|
FrameManager: {
|
||||||
|
FrameAttached: Symbol('Events.FrameManager.FrameAttached'),
|
||||||
|
FrameNavigated: Symbol('Events.FrameManager.FrameNavigated'),
|
||||||
|
FrameDetached: Symbol('Events.FrameManager.FrameDetached'),
|
||||||
|
LifecycleEvent: Symbol('Events.FrameManager.LifecycleEvent'),
|
||||||
|
FrameNavigatedWithinDocument: Symbol('Events.FrameManager.FrameNavigatedWithinDocument'),
|
||||||
|
ExecutionContextCreated: Symbol('Events.FrameManager.ExecutionContextCreated'),
|
||||||
|
ExecutionContextDestroyed: Symbol('Events.FrameManager.ExecutionContextDestroyed'),
|
||||||
|
},
|
||||||
|
|
||||||
|
Connection: {
|
||||||
|
Disconnected: Symbol('Events.Connection.Disconnected'),
|
||||||
|
},
|
||||||
|
|
||||||
|
CDPSession: {
|
||||||
|
Disconnected: Symbol('Events.CDPSession.Disconnected'),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { Events };
|
@ -17,10 +17,9 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const {helper, assert} = require('./helper');
|
const {helper, assert} = require('./helper');
|
||||||
|
const {Events} = require('./Events');
|
||||||
const {ExecutionContext} = require('./ExecutionContext');
|
const {ExecutionContext} = require('./ExecutionContext');
|
||||||
const {TimeoutError} = require('./Errors');
|
const {TimeoutError} = require('./Errors');
|
||||||
const {NetworkManager} = require('./NetworkManager');
|
|
||||||
const {CDPSession} = require('./Connection');
|
|
||||||
|
|
||||||
const readFileAsync = helper.promisify(fs.readFile);
|
const readFileAsync = helper.promisify(fs.readFile);
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ class FrameManager extends EventEmitter {
|
|||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
frame._onLifecycleEvent(event.loaderId, event.name);
|
frame._onLifecycleEvent(event.loaderId, event.name);
|
||||||
this.emit(FrameManager.Events.LifecycleEvent, frame);
|
this.emit(Events.FrameManager.LifecycleEvent, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,7 +152,7 @@ class FrameManager extends EventEmitter {
|
|||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
frame._onLoadingStopped();
|
frame._onLoadingStopped();
|
||||||
this.emit(FrameManager.Events.LifecycleEvent, frame);
|
this.emit(Events.FrameManager.LifecycleEvent, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,7 +209,7 @@ class FrameManager extends EventEmitter {
|
|||||||
const parentFrame = this._frames.get(parentFrameId);
|
const parentFrame = this._frames.get(parentFrameId);
|
||||||
const frame = new Frame(this, this._client, parentFrame, frameId);
|
const frame = new Frame(this, this._client, parentFrame, frameId);
|
||||||
this._frames.set(frame._id, frame);
|
this._frames.set(frame._id, frame);
|
||||||
this.emit(FrameManager.Events.FrameAttached, frame);
|
this.emit(Events.FrameManager.FrameAttached, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,7 +243,7 @@ class FrameManager extends EventEmitter {
|
|||||||
// Update frame payload.
|
// Update frame payload.
|
||||||
frame._navigated(framePayload);
|
frame._navigated(framePayload);
|
||||||
|
|
||||||
this.emit(FrameManager.Events.FrameNavigated, frame);
|
this.emit(Events.FrameManager.FrameNavigated, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,8 +255,8 @@ class FrameManager extends EventEmitter {
|
|||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
frame._navigatedWithinDocument(url);
|
frame._navigatedWithinDocument(url);
|
||||||
this.emit(FrameManager.Events.FrameNavigatedWithinDocument, frame);
|
this.emit(Events.FrameManager.FrameNavigatedWithinDocument, frame);
|
||||||
this.emit(FrameManager.Events.FrameNavigated, frame);
|
this.emit(Events.FrameManager.FrameNavigated, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -317,21 +316,10 @@ class FrameManager extends EventEmitter {
|
|||||||
this._removeFramesRecursively(child);
|
this._removeFramesRecursively(child);
|
||||||
frame._detach();
|
frame._detach();
|
||||||
this._frames.delete(frame._id);
|
this._frames.delete(frame._id);
|
||||||
this.emit(FrameManager.Events.FrameDetached, frame);
|
this.emit(Events.FrameManager.FrameDetached, frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @enum {string} */
|
|
||||||
FrameManager.Events = {
|
|
||||||
FrameAttached: 'frameattached',
|
|
||||||
FrameNavigated: 'framenavigated',
|
|
||||||
FrameDetached: 'framedetached',
|
|
||||||
LifecycleEvent: 'lifecycleevent',
|
|
||||||
FrameNavigatedWithinDocument: 'framenavigatedwithindocument',
|
|
||||||
ExecutionContextCreated: 'executioncontextcreated',
|
|
||||||
ExecutionContextDestroyed: 'executioncontextdestroyed',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @unrestricted
|
* @unrestricted
|
||||||
*/
|
*/
|
||||||
@ -1180,11 +1168,11 @@ class LifecycleWatcher {
|
|||||||
/** @type {?Puppeteer.Request} */
|
/** @type {?Puppeteer.Request} */
|
||||||
this._navigationRequest = null;
|
this._navigationRequest = null;
|
||||||
this._eventListeners = [
|
this._eventListeners = [
|
||||||
helper.addEventListener(frameManager._client, CDPSession.Events.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))),
|
helper.addEventListener(frameManager._client, Events.CDPSession.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))),
|
||||||
helper.addEventListener(this._frameManager, FrameManager.Events.LifecycleEvent, this._checkLifecycleComplete.bind(this)),
|
helper.addEventListener(this._frameManager, Events.FrameManager.LifecycleEvent, this._checkLifecycleComplete.bind(this)),
|
||||||
helper.addEventListener(this._frameManager, FrameManager.Events.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)),
|
helper.addEventListener(this._frameManager, Events.FrameManager.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)),
|
||||||
helper.addEventListener(this._frameManager, FrameManager.Events.FrameDetached, this._onFrameDetached.bind(this)),
|
helper.addEventListener(this._frameManager, Events.FrameManager.FrameDetached, this._onFrameDetached.bind(this)),
|
||||||
helper.addEventListener(this._networkManager, NetworkManager.Events.Request, this._onRequest.bind(this)),
|
helper.addEventListener(this._networkManager, Events.NetworkManager.Request, this._onRequest.bind(this)),
|
||||||
];
|
];
|
||||||
|
|
||||||
this._sameDocumentNavigationPromise = new Promise(fulfill => {
|
this._sameDocumentNavigationPromise = new Promise(fulfill => {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const {helper, assert, debugError} = require('./helper');
|
const {helper, assert, debugError} = require('./helper');
|
||||||
|
const {Events} = require('./Events');
|
||||||
const Multimap = require('./Multimap');
|
const Multimap = require('./Multimap');
|
||||||
|
|
||||||
class NetworkManager extends EventEmitter {
|
class NetworkManager extends EventEmitter {
|
||||||
@ -206,7 +207,7 @@ class NetworkManager extends EventEmitter {
|
|||||||
const frame = event.frameId && this._frameManager ? this._frameManager.frame(event.frameId) : null;
|
const frame = event.frameId && this._frameManager ? this._frameManager.frame(event.frameId) : null;
|
||||||
const request = new Request(this._client, frame, interceptionId, this._userRequestInterceptionEnabled, event, redirectChain);
|
const request = new Request(this._client, frame, interceptionId, this._userRequestInterceptionEnabled, event, redirectChain);
|
||||||
this._requestIdToRequest.set(event.requestId, request);
|
this._requestIdToRequest.set(event.requestId, request);
|
||||||
this.emit(NetworkManager.Events.Request, request);
|
this.emit(Events.NetworkManager.Request, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -230,8 +231,8 @@ class NetworkManager extends EventEmitter {
|
|||||||
response._bodyLoadedPromiseFulfill.call(null, new Error('Response body is unavailable for redirect responses'));
|
response._bodyLoadedPromiseFulfill.call(null, new Error('Response body is unavailable for redirect responses'));
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
this._attemptedAuthentications.delete(request._interceptionId);
|
this._attemptedAuthentications.delete(request._interceptionId);
|
||||||
this.emit(NetworkManager.Events.Response, response);
|
this.emit(Events.NetworkManager.Response, response);
|
||||||
this.emit(NetworkManager.Events.RequestFinished, request);
|
this.emit(Events.NetworkManager.RequestFinished, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,7 +245,7 @@ class NetworkManager extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
const response = new Response(this._client, request, event.response);
|
const response = new Response(this._client, request, event.response);
|
||||||
request._response = response;
|
request._response = response;
|
||||||
this.emit(NetworkManager.Events.Response, response);
|
this.emit(Events.NetworkManager.Response, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -263,7 +264,7 @@ class NetworkManager extends EventEmitter {
|
|||||||
request.response()._bodyLoadedPromiseFulfill.call(null);
|
request.response()._bodyLoadedPromiseFulfill.call(null);
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
this._attemptedAuthentications.delete(request._interceptionId);
|
this._attemptedAuthentications.delete(request._interceptionId);
|
||||||
this.emit(NetworkManager.Events.RequestFinished, request);
|
this.emit(Events.NetworkManager.RequestFinished, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,7 +282,7 @@ class NetworkManager extends EventEmitter {
|
|||||||
response._bodyLoadedPromiseFulfill.call(null);
|
response._bodyLoadedPromiseFulfill.call(null);
|
||||||
this._requestIdToRequest.delete(request._requestId);
|
this._requestIdToRequest.delete(request._requestId);
|
||||||
this._attemptedAuthentications.delete(request._interceptionId);
|
this._attemptedAuthentications.delete(request._interceptionId);
|
||||||
this.emit(NetworkManager.Events.RequestFailed, request);
|
this.emit(Events.NetworkManager.RequestFailed, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,13 +733,6 @@ class SecurityDetails {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkManager.Events = {
|
|
||||||
Request: 'request',
|
|
||||||
Response: 'response',
|
|
||||||
RequestFailed: 'requestfailed',
|
|
||||||
RequestFinished: 'requestfinished',
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusTexts = {
|
const statusTexts = {
|
||||||
'100': 'Continue',
|
'100': 'Continue',
|
||||||
'101': 'Switching Protocols',
|
'101': 'Switching Protocols',
|
||||||
|
65
lib/Page.js
65
lib/Page.js
@ -17,6 +17,7 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const mime = require('mime');
|
const mime = require('mime');
|
||||||
|
const {Events} = require('./Events');
|
||||||
const {NetworkManager} = require('./NetworkManager');
|
const {NetworkManager} = require('./NetworkManager');
|
||||||
const {Dialog} = require('./Dialog');
|
const {Dialog} = require('./Dialog');
|
||||||
const {EmulationManager} = require('./EmulationManager');
|
const {EmulationManager} = require('./EmulationManager');
|
||||||
@ -108,28 +109,28 @@ class Page extends EventEmitter {
|
|||||||
const session = client._createSession(event.targetInfo.type, event.sessionId);
|
const session = client._createSession(event.targetInfo.type, event.sessionId);
|
||||||
const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
const worker = new Worker(session, event.targetInfo.url, this._addConsoleMessage.bind(this), this._handleException.bind(this));
|
||||||
this._workers.set(event.sessionId, worker);
|
this._workers.set(event.sessionId, worker);
|
||||||
this.emit(Page.Events.WorkerCreated, worker);
|
this.emit(Events.Page.WorkerCreated, worker);
|
||||||
|
|
||||||
});
|
});
|
||||||
client.on('Target.detachedFromTarget', event => {
|
client.on('Target.detachedFromTarget', event => {
|
||||||
const worker = this._workers.get(event.sessionId);
|
const worker = this._workers.get(event.sessionId);
|
||||||
if (!worker)
|
if (!worker)
|
||||||
return;
|
return;
|
||||||
this.emit(Page.Events.WorkerDestroyed, worker);
|
this.emit(Events.Page.WorkerDestroyed, worker);
|
||||||
this._workers.delete(event.sessionId);
|
this._workers.delete(event.sessionId);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._frameManager.on(FrameManager.Events.FrameAttached, event => this.emit(Page.Events.FrameAttached, event));
|
this._frameManager.on(Events.FrameManager.FrameAttached, event => this.emit(Events.Page.FrameAttached, event));
|
||||||
this._frameManager.on(FrameManager.Events.FrameDetached, event => this.emit(Page.Events.FrameDetached, event));
|
this._frameManager.on(Events.FrameManager.FrameDetached, event => this.emit(Events.Page.FrameDetached, event));
|
||||||
this._frameManager.on(FrameManager.Events.FrameNavigated, event => this.emit(Page.Events.FrameNavigated, event));
|
this._frameManager.on(Events.FrameManager.FrameNavigated, event => this.emit(Events.Page.FrameNavigated, event));
|
||||||
|
|
||||||
this._networkManager.on(NetworkManager.Events.Request, event => this.emit(Page.Events.Request, event));
|
this._networkManager.on(Events.NetworkManager.Request, event => this.emit(Events.Page.Request, event));
|
||||||
this._networkManager.on(NetworkManager.Events.Response, event => this.emit(Page.Events.Response, event));
|
this._networkManager.on(Events.NetworkManager.Response, event => this.emit(Events.Page.Response, event));
|
||||||
this._networkManager.on(NetworkManager.Events.RequestFailed, event => this.emit(Page.Events.RequestFailed, event));
|
this._networkManager.on(Events.NetworkManager.RequestFailed, event => this.emit(Events.Page.RequestFailed, event));
|
||||||
this._networkManager.on(NetworkManager.Events.RequestFinished, event => this.emit(Page.Events.RequestFinished, event));
|
this._networkManager.on(Events.NetworkManager.RequestFinished, event => this.emit(Events.Page.RequestFinished, event));
|
||||||
|
|
||||||
client.on('Page.domContentEventFired', event => this.emit(Page.Events.DOMContentLoaded));
|
client.on('Page.domContentEventFired', event => this.emit(Events.Page.DOMContentLoaded));
|
||||||
client.on('Page.loadEventFired', event => this.emit(Page.Events.Load));
|
client.on('Page.loadEventFired', event => this.emit(Events.Page.Load));
|
||||||
client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||||
client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
|
client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
|
||||||
client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
|
client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
|
||||||
@ -139,7 +140,7 @@ class Page extends EventEmitter {
|
|||||||
client.on('Performance.metrics', event => this._emitMetrics(event));
|
client.on('Performance.metrics', event => this._emitMetrics(event));
|
||||||
client.on('Log.entryAdded', event => this._onLogEntryAdded(event));
|
client.on('Log.entryAdded', event => this._onLogEntryAdded(event));
|
||||||
this._target._isClosedPromise.then(() => {
|
this._target._isClosedPromise.then(() => {
|
||||||
this.emit(Page.Events.Close);
|
this.emit(Events.Page.Close);
|
||||||
this._closed = true;
|
this._closed = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -191,7 +192,7 @@ class Page extends EventEmitter {
|
|||||||
if (args)
|
if (args)
|
||||||
args.map(arg => helper.releaseObject(this._client, arg));
|
args.map(arg => helper.releaseObject(this._client, arg));
|
||||||
if (source !== 'worker')
|
if (source !== 'worker')
|
||||||
this.emit(Page.Events.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
|
this.emit(Events.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -475,7 +476,7 @@ class Page extends EventEmitter {
|
|||||||
* @param {!Protocol.Performance.metricsPayload} event
|
* @param {!Protocol.Performance.metricsPayload} event
|
||||||
*/
|
*/
|
||||||
_emitMetrics(event) {
|
_emitMetrics(event) {
|
||||||
this.emit(Page.Events.Metrics, {
|
this.emit(Events.Page.Metrics, {
|
||||||
title: event.title,
|
title: event.title,
|
||||||
metrics: this._buildMetricsObject(event.metrics)
|
metrics: this._buildMetricsObject(event.metrics)
|
||||||
});
|
});
|
||||||
@ -501,7 +502,7 @@ class Page extends EventEmitter {
|
|||||||
const message = helper.getExceptionMessage(exceptionDetails);
|
const message = helper.getExceptionMessage(exceptionDetails);
|
||||||
const err = new Error(message);
|
const err = new Error(message);
|
||||||
err.stack = ''; // Don't report clientside error with a node stack attached
|
err.stack = ''; // Don't report clientside error with a node stack attached
|
||||||
this.emit(Page.Events.PageError, err);
|
this.emit(Events.Page.PageError, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -570,7 +571,7 @@ class Page extends EventEmitter {
|
|||||||
* @param {Protocol.Runtime.StackTrace=} stackTrace
|
* @param {Protocol.Runtime.StackTrace=} stackTrace
|
||||||
*/
|
*/
|
||||||
_addConsoleMessage(type, args, stackTrace) {
|
_addConsoleMessage(type, args, stackTrace) {
|
||||||
if (!this.listenerCount(Page.Events.Console)) {
|
if (!this.listenerCount(Events.Page.Console)) {
|
||||||
args.forEach(arg => arg.dispose());
|
args.forEach(arg => arg.dispose());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -588,7 +589,7 @@ class Page extends EventEmitter {
|
|||||||
columnNumber: stackTrace.callFrames[0].columnNumber,
|
columnNumber: stackTrace.callFrames[0].columnNumber,
|
||||||
} : {};
|
} : {};
|
||||||
const message = new ConsoleMessage(type, textTokens.join(' '), args, location);
|
const message = new ConsoleMessage(type, textTokens.join(' '), args, location);
|
||||||
this.emit(Page.Events.Console, message);
|
this.emit(Events.Page.Console, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDialog(event) {
|
_onDialog(event) {
|
||||||
@ -603,7 +604,7 @@ class Page extends EventEmitter {
|
|||||||
dialogType = Dialog.Type.BeforeUnload;
|
dialogType = Dialog.Type.BeforeUnload;
|
||||||
assert(dialogType, 'Unknown javascript dialog type: ' + event.type);
|
assert(dialogType, 'Unknown javascript dialog type: ' + event.type);
|
||||||
const dialog = new Dialog(this._client, dialogType, event.message, event.defaultPrompt);
|
const dialog = new Dialog(this._client, dialogType, event.message, event.defaultPrompt);
|
||||||
this.emit(Page.Events.Dialog, dialog);
|
this.emit(Events.Page.Dialog, dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -666,7 +667,7 @@ class Page extends EventEmitter {
|
|||||||
const {
|
const {
|
||||||
timeout = 30000
|
timeout = 30000
|
||||||
} = options;
|
} = options;
|
||||||
return helper.waitForEvent(this._networkManager, NetworkManager.Events.Request, request => {
|
return helper.waitForEvent(this._networkManager, Events.NetworkManager.Request, request => {
|
||||||
if (helper.isString(urlOrPredicate))
|
if (helper.isString(urlOrPredicate))
|
||||||
return (urlOrPredicate === request.url());
|
return (urlOrPredicate === request.url());
|
||||||
if (typeof urlOrPredicate === 'function')
|
if (typeof urlOrPredicate === 'function')
|
||||||
@ -684,7 +685,7 @@ class Page extends EventEmitter {
|
|||||||
const {
|
const {
|
||||||
timeout = 30000
|
timeout = 30000
|
||||||
} = options;
|
} = options;
|
||||||
return helper.waitForEvent(this._networkManager, NetworkManager.Events.Response, response => {
|
return helper.waitForEvent(this._networkManager, Events.NetworkManager.Response, response => {
|
||||||
if (helper.isString(urlOrPredicate))
|
if (helper.isString(urlOrPredicate))
|
||||||
return (urlOrPredicate === response.url());
|
return (urlOrPredicate === response.url());
|
||||||
if (typeof urlOrPredicate === 'function')
|
if (typeof urlOrPredicate === 'function')
|
||||||
@ -1182,30 +1183,6 @@ function convertPrintParameterToInches(parameter) {
|
|||||||
return pixels / 96;
|
return pixels / 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.Events = {
|
|
||||||
Close: 'close',
|
|
||||||
Console: 'console',
|
|
||||||
Dialog: 'dialog',
|
|
||||||
DOMContentLoaded: 'domcontentloaded',
|
|
||||||
Error: 'error',
|
|
||||||
// Can't use just 'error' due to node.js special treatment of error events.
|
|
||||||
// @see https://nodejs.org/api/events.html#events_error_events
|
|
||||||
PageError: 'pageerror',
|
|
||||||
Request: 'request',
|
|
||||||
Response: 'response',
|
|
||||||
RequestFailed: 'requestfailed',
|
|
||||||
RequestFinished: 'requestfinished',
|
|
||||||
FrameAttached: 'frameattached',
|
|
||||||
FrameDetached: 'framedetached',
|
|
||||||
FrameNavigated: 'framenavigated',
|
|
||||||
Load: 'load',
|
|
||||||
Metrics: 'metrics',
|
|
||||||
Popup: 'popup',
|
|
||||||
WorkerCreated: 'workercreated',
|
|
||||||
WorkerDestroyed: 'workerdestroyed',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} Network.Cookie
|
* @typedef {Object} Network.Cookie
|
||||||
* @property {string} name
|
* @property {string} name
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
const {Events} = require('./Events');
|
||||||
const {Page} = require('./Page');
|
const {Page} = require('./Page');
|
||||||
const {helper} = require('./helper');
|
const {helper} = require('./helper');
|
||||||
|
|
||||||
@ -27,10 +28,10 @@ class Target {
|
|||||||
if (!opener || !opener._pagePromise || this.type() !== 'page')
|
if (!opener || !opener._pagePromise || this.type() !== 'page')
|
||||||
return true;
|
return true;
|
||||||
const openerPage = await opener._pagePromise;
|
const openerPage = await opener._pagePromise;
|
||||||
if (!openerPage.listenerCount(Page.Events.Popup))
|
if (!openerPage.listenerCount(Events.Page.Popup))
|
||||||
return true;
|
return true;
|
||||||
const popupPage = await this.page();
|
const popupPage = await this.page();
|
||||||
openerPage.emit(Page.Events.Popup, popupPage);
|
openerPage.emit(Events.Page.Popup, popupPage);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
|
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
|
||||||
|
@ -220,7 +220,7 @@ class Helper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!NodeJS.EventEmitter} emitter
|
* @param {!NodeJS.EventEmitter} emitter
|
||||||
* @param {string} eventName
|
* @param {(string|symbol)} eventName
|
||||||
* @param {function} predicate
|
* @param {function} predicate
|
||||||
* @return {!Promise}
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +7,15 @@ module.exports = checkSources;
|
|||||||
* @param {!Array<!import('../Source')>} sources
|
* @param {!Array<!import('../Source')>} sources
|
||||||
*/
|
*/
|
||||||
function checkSources(sources) {
|
function checkSources(sources) {
|
||||||
|
// special treatment for Events.js
|
||||||
|
const classEvents = new Map();
|
||||||
|
const eventsSource = sources.find(source => source.name() === 'Events.js');
|
||||||
|
if (eventsSource) {
|
||||||
|
const {Events} = require(eventsSource.filePath());
|
||||||
|
for (const [className, events] of Object.entries(Events))
|
||||||
|
classEvents.set(className, Array.from(Object.values(events)).filter(e => typeof e === 'string').map(e => Documentation.Member.createEvent(e)));
|
||||||
|
}
|
||||||
|
|
||||||
const excludeClasses = new Set([]);
|
const excludeClasses = new Set([]);
|
||||||
const program = ts.createProgram({
|
const program = ts.createProgram({
|
||||||
options: {
|
options: {
|
||||||
@ -24,6 +33,7 @@ function checkSources(sources) {
|
|||||||
sourceFiles.filter(x => !x.fileName.includes('node_modules')).map(x => visit(x));
|
sourceFiles.filter(x => !x.fileName.includes('node_modules')).map(x => visit(x));
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const documentation = new Documentation(recreateClassesWithInheritance(classes, inheritance));
|
const documentation = new Documentation(recreateClassesWithInheritance(classes, inheritance));
|
||||||
|
|
||||||
return {errors, documentation};
|
return {errors, documentation};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,17 +168,7 @@ function checkSources(sources) {
|
|||||||
*/
|
*/
|
||||||
function serializeClass(className, symbol, node) {
|
function serializeClass(className, symbol, node) {
|
||||||
/** @type {!Array<!Documentation.Member>} */
|
/** @type {!Array<!Documentation.Member>} */
|
||||||
const members = [];
|
const members = classEvents.get(className) || [];
|
||||||
|
|
||||||
const type = checker.getTypeOfSymbolAtLocation(symbol, node);
|
|
||||||
const events = type.getProperty('Events');
|
|
||||||
if (events) {
|
|
||||||
const eventType = checker.getTypeAtLocation(events.valueDeclaration);
|
|
||||||
for (const property of eventType.getProperties()) {
|
|
||||||
if (property.valueDeclaration.initializer.text)
|
|
||||||
members.push(Documentation.Member.createEvent(property.valueDeclaration.initializer.text));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [name, member] of symbol.members || []) {
|
for (const [name, member] of symbol.members || []) {
|
||||||
if (name.startsWith('_'))
|
if (name.startsWith('_'))
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
const Events = {
|
||||||
|
Foo: {
|
||||||
|
a: 'a',
|
||||||
|
b: 'b',
|
||||||
|
c: 'c',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module.exports = {Events};
|
@ -10,8 +10,3 @@ class Foo {
|
|||||||
ccc() {}
|
ccc() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo.Events = {
|
|
||||||
a: 'a',
|
|
||||||
b: 'b',
|
|
||||||
c: 'c'
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
const Events = {
|
||||||
|
Foo: {
|
||||||
|
Start: 'start',
|
||||||
|
Finish: 'finish',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {Events};
|
@ -1,7 +1,3 @@
|
|||||||
class Foo {
|
class Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo.Events = {
|
|
||||||
Start: 'start',
|
|
||||||
Finish: 'finish',
|
|
||||||
};
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
const Events = {
|
||||||
|
A: {
|
||||||
|
AnEvent: 'anevent'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module.exports = { Events };
|
@ -11,7 +11,3 @@ class A {
|
|||||||
async method(foo, bar) {
|
async method(foo, bar) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
A.Events = {
|
|
||||||
AnEvent: 'anevent'
|
|
||||||
};
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
const Events = {
|
||||||
|
B: {
|
||||||
|
// Event with the same name as a super class method.
|
||||||
|
foo: 'foo',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {Events};
|
@ -13,8 +13,3 @@ class B extends A {
|
|||||||
bar(override) {
|
bar(override) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
B.Events = {
|
|
||||||
// Event with the same name as a super class method.
|
|
||||||
foo: 'foo'
|
|
||||||
};
|
|
||||||
|
Loading…
Reference in New Issue
Block a user