chore: migrate src/Connection
to TypeScript (#5694)
* chore: migrate `src/Connection` to TypeScript This commit migrates `src/Connection` to TypeScript. It also changes its exports to be ESM because TypeScript's support for exporting values to use as types via CommonJS is poor (by design) and so rather than battle that it made more sense to migrate the file to ESM. The good news is that TypeScript is still outputting to `lib/` as CommonJS, so the fact that we author in ESM is actually not a breaking change at all. So going forwards we will: * migrate TS files to use ESM for importing and exporting * continue to output to `lib/` as CommonJS * continue to use CommonJS requires when in a `src/*.js` file I'd also like to split `Connection.ts` into two; I think the `CDPSession` class belongs in its own file, but I will do that in another PR to avoid this one becoming bigger than it already is. I also turned off `@typescript-eslint/no-use-before-define` as I don't think it was adding value and Puppeteer's codebase seems to have a style of declaring helper functions at the bottom which is fine by me. Finally, I updated the DocLint tool so it knows of expected method mismatches. It was either that or come up with a smart way to support TypeScript generics in DocLint and given we don't want to use DocLint that much longer that didn't feel worth it. * Fix params being required
This commit is contained in:
parent
376d234ed1
commit
a614bc45aa
@ -112,7 +112,8 @@ module.exports = {
|
||||
"@typescript-eslint/no-unused-vars": 2,
|
||||
"semi": 0,
|
||||
"@typescript-eslint/semi": 2,
|
||||
"@typescript-eslint/no-empty-function": 0
|
||||
"@typescript-eslint/no-empty-function": 0,
|
||||
"@typescript-eslint/no-use-before-define": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
/**
|
||||
* @typedef {Object} SerializedAXNode
|
||||
* @property {string} role
|
||||
@ -53,7 +57,7 @@
|
||||
|
||||
class Accessibility {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
|
@ -19,10 +19,13 @@ const {Target} = require('./Target');
|
||||
const EventEmitter = require('events');
|
||||
const {TaskQueue} = require('./TaskQueue');
|
||||
const {Events} = require('./Events');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {Connection} = require('./Connection');
|
||||
|
||||
class Browser extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.Connection} connection
|
||||
* @param {!Connection} connection
|
||||
* @param {!Array<string>} contextIds
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {?Puppeteer.Viewport} defaultViewport
|
||||
@ -36,7 +39,7 @@ class Browser extends EventEmitter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Puppeteer.Connection} connection
|
||||
* @param {!Connection} connection
|
||||
* @param {!Array<string>} contextIds
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {?Puppeteer.Viewport} defaultViewport
|
||||
@ -277,7 +280,7 @@ class Browser extends EventEmitter {
|
||||
|
||||
class BrowserContext extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.Connection} connection
|
||||
* @param {!Connection} connection
|
||||
* @param {!Browser} browser
|
||||
* @param {?string} contextId
|
||||
*/
|
||||
|
@ -13,38 +13,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const {assert} = require('./helper');
|
||||
const {Events} = require('./Events');
|
||||
const debugProtocol = require('debug')('puppeteer:protocol');
|
||||
const EventEmitter = require('events');
|
||||
import helper = require('./helper');
|
||||
const {assert} = helper;
|
||||
|
||||
import EventsModule = require('./Events');
|
||||
const {Events} = EventsModule;
|
||||
|
||||
import debug = require('debug');
|
||||
const debugProtocol = debug('puppeteer:protocol');
|
||||
|
||||
import EventEmitter = require('events');
|
||||
|
||||
interface ConnectionCallback {
|
||||
resolve: Function;
|
||||
reject: Function;
|
||||
error: Error;
|
||||
method: string;
|
||||
|
||||
}
|
||||
|
||||
export class Connection extends EventEmitter {
|
||||
_url: string;
|
||||
_transport: Puppeteer.ConnectionTransport;
|
||||
_delay: number;
|
||||
_lastId = 0;
|
||||
_sessions: Map<string, CDPSession> = new Map();
|
||||
_closed = false;
|
||||
|
||||
_callbacks: Map<number, ConnectionCallback> = new Map();
|
||||
|
||||
class Connection extends EventEmitter {
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {!Puppeteer.ConnectionTransport} transport
|
||||
* @param {number=} delay
|
||||
*/
|
||||
constructor(url, transport, delay = 0) {
|
||||
constructor(url: string, transport: Puppeteer.ConnectionTransport, delay = 0) {
|
||||
super();
|
||||
this._url = url;
|
||||
this._lastId = 0;
|
||||
/** @type {!Map<number, {resolve: function, reject: function, error: !Error, method: string}>}*/
|
||||
this._callbacks = new Map();
|
||||
this._delay = delay;
|
||||
|
||||
this._transport = transport;
|
||||
this._transport.onmessage = this._onMessage.bind(this);
|
||||
this._transport.onclose = this._onClose.bind(this);
|
||||
/** @type {!Map<string, !CDPSession>}*/
|
||||
this._sessions = new Map();
|
||||
this._closed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!CDPSession} session
|
||||
* @return {!Connection}
|
||||
*/
|
||||
static fromSession(session) {
|
||||
static fromSession(session: CDPSession): Connection {
|
||||
return session._connection;
|
||||
}
|
||||
|
||||
@ -52,34 +65,22 @@ class Connection extends EventEmitter {
|
||||
* @param {string} sessionId
|
||||
* @return {?CDPSession}
|
||||
*/
|
||||
session(sessionId) {
|
||||
session(sessionId: string): CDPSession | null {
|
||||
return this._sessions.get(sessionId) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
url() {
|
||||
url(): string {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} method
|
||||
* @param {!Object=} params
|
||||
* @return {!Promise<?Object>}
|
||||
*/
|
||||
send(method, params = {}) {
|
||||
send<ReturnType extends {}>(method: string, params = {}): Promise<ReturnType> {
|
||||
const id = this._rawSend({method, params});
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new Error(), method});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} message
|
||||
* @return {number}
|
||||
*/
|
||||
_rawSend(message) {
|
||||
_rawSend(message: {}): number {
|
||||
const id = ++this._lastId;
|
||||
message = JSON.stringify(Object.assign({}, message, {id}));
|
||||
debugProtocol('SEND ► ' + message);
|
||||
@ -87,10 +88,7 @@ class Connection extends EventEmitter {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
*/
|
||||
async _onMessage(message) {
|
||||
async _onMessage(message: string): Promise<void> {
|
||||
if (this._delay)
|
||||
await new Promise(f => setTimeout(f, this._delay));
|
||||
debugProtocol('◀ RECV ' + message);
|
||||
@ -125,7 +123,7 @@ class Connection extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
_onClose() {
|
||||
_onClose(): void {
|
||||
if (this._closed)
|
||||
return;
|
||||
this._closed = true;
|
||||
@ -140,7 +138,7 @@ class Connection extends EventEmitter {
|
||||
this.emit(Events.Connection.Disconnected);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
dispose(): void {
|
||||
this._onClose();
|
||||
this._transport.close();
|
||||
}
|
||||
@ -149,45 +147,53 @@ class Connection extends EventEmitter {
|
||||
* @param {Protocol.Target.TargetInfo} targetInfo
|
||||
* @return {!Promise<!CDPSession>}
|
||||
*/
|
||||
async createSession(targetInfo) {
|
||||
const {sessionId} = await this.send('Target.attachToTarget', {targetId: targetInfo.targetId, flatten: true});
|
||||
async createSession(targetInfo: Protocol.Target.TargetInfo): Promise<CDPSession> {
|
||||
const {sessionId} = await this.send<Protocol.Target.attachedToTargetPayload>('Target.attachToTarget', {targetId: targetInfo.targetId, flatten: true});
|
||||
return this._sessions.get(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
class CDPSession extends EventEmitter {
|
||||
/**
|
||||
* @param {!Connection} connection
|
||||
* @param {string} targetType
|
||||
* @param {string} sessionId
|
||||
*/
|
||||
constructor(connection, targetType, sessionId) {
|
||||
interface CDPSessionOnMessageObject {
|
||||
id?: number;
|
||||
method: string;
|
||||
params: {};
|
||||
error: {message: string; data: any};
|
||||
result?: any;
|
||||
|
||||
}
|
||||
export class CDPSession extends EventEmitter {
|
||||
_connection: Connection;
|
||||
_sessionId: string;
|
||||
_targetType: string;
|
||||
_callbacks: Map<number, ConnectionCallback> = new Map();
|
||||
|
||||
constructor(connection: Connection, targetType: string, sessionId: string) {
|
||||
super();
|
||||
/** @type {!Map<number, {resolve: function, reject: function, error: !Error, method: string}>}*/
|
||||
this._callbacks = new Map();
|
||||
this._connection = connection;
|
||||
this._targetType = targetType;
|
||||
this._sessionId = sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} method
|
||||
* @param {!Object=} params
|
||||
* @return {!Promise<?Object>}
|
||||
*/
|
||||
send(method, params = {}) {
|
||||
send<T extends keyof Protocol.CommandParameters>(method: T, params?: Protocol.CommandParameters[T]): 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({
|
||||
sessionId: this._sessionId,
|
||||
method,
|
||||
/* TODO(jacktfranklin@): once this Firefox bug is solved
|
||||
* we no longer need the `|| {}` check
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1631570
|
||||
*/
|
||||
params: params || {}
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, {resolve, reject, error: new Error(), method});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{id?: number, method: string, params: Object, error: {message: string, data: any}, result?: *}} object
|
||||
*/
|
||||
_onMessage(object) {
|
||||
_onMessage(object: CDPSessionOnMessageObject): void {
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
@ -201,13 +207,13 @@ class CDPSession extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
async detach() {
|
||||
async detach(): Promise<void> {
|
||||
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});
|
||||
}
|
||||
|
||||
_onClosed() {
|
||||
_onClosed(): void {
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(rewriteError(callback.error, `Protocol error (${callback.method}): Target closed.`));
|
||||
this._callbacks.clear();
|
||||
@ -222,7 +228,7 @@ class CDPSession extends EventEmitter {
|
||||
* @param {{error: {message: string, data: any}}} object
|
||||
* @return {!Error}
|
||||
*/
|
||||
function createProtocolError(error, method, object) {
|
||||
function createProtocolError(error: Error, method: string, object: { error: { message: string; data: any}}): Error {
|
||||
let message = `Protocol error (${method}): ${object.error.message}`;
|
||||
if ('data' in object.error)
|
||||
message += ` ${object.error.data}`;
|
||||
@ -234,9 +240,7 @@ function createProtocolError(error, method, object) {
|
||||
* @param {string} message
|
||||
* @return {!Error}
|
||||
*/
|
||||
function rewriteError(error, message) {
|
||||
function rewriteError(error: Error, message: string): Error {
|
||||
error.message = message;
|
||||
return error;
|
||||
}
|
||||
|
||||
module.exports = {Connection, CDPSession};
|
@ -15,6 +15,9 @@
|
||||
*/
|
||||
|
||||
const {helper, debugError, assert} = require('./helper');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
const {EVALUATION_SCRIPT_URL} = require('./ExecutionContext');
|
||||
|
||||
@ -27,7 +30,7 @@ const {EVALUATION_SCRIPT_URL} = require('./ExecutionContext');
|
||||
|
||||
class Coverage {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._jsCoverage = new JSCoverage(client);
|
||||
@ -67,7 +70,7 @@ module.exports = {Coverage};
|
||||
|
||||
class JSCoverage {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
@ -166,7 +169,7 @@ class JSCoverage {
|
||||
|
||||
class CSSCoverage {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import helpers = require('./helper');
|
||||
import {CDPSession} from './Connection';
|
||||
|
||||
const {assert} = helpers;
|
||||
|
||||
@ -28,13 +29,13 @@ enum DialogType {
|
||||
class Dialog {
|
||||
static Type = DialogType;
|
||||
|
||||
private _client: Puppeteer.CDPSession;
|
||||
private _client: CDPSession;
|
||||
private _type: DialogType;
|
||||
private _message: string;
|
||||
private _defaultValue: string;
|
||||
private _handled = false;
|
||||
|
||||
constructor(client: Puppeteer.CDPSession, type: DialogType, message: string, defaultValue = '') {
|
||||
constructor(client: CDPSession, type: DialogType, message: string, defaultValue = '') {
|
||||
this._client = client;
|
||||
this._type = type;
|
||||
this._message = message;
|
||||
|
@ -14,9 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
class EmulationManager {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
|
@ -16,13 +16,16 @@
|
||||
|
||||
const {helper, assert} = require('./helper');
|
||||
const {createJSHandle, JSHandle} = require('./JSHandle');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
const EVALUATION_SCRIPT_URL = '__puppeteer_evaluation_script__';
|
||||
const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
|
||||
|
||||
class ExecutionContext {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Protocol.Runtime.ExecutionContextDescription} contextPayload
|
||||
* @param {?Puppeteer.DOMWorld} world
|
||||
*/
|
||||
|
@ -24,12 +24,15 @@ const {NetworkManager} = require('./NetworkManager');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {TimeoutSettings} = require('./TimeoutSettings');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
||||
|
||||
class FrameManager extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Puppeteer.Page} page
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {!TimeoutSettings} timeoutSettings
|
||||
@ -112,7 +115,7 @@ class FrameManager extends EventEmitter {
|
||||
return watcher.navigationResponse();
|
||||
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {string} url
|
||||
* @param {string} referrer
|
||||
* @param {string} frameId
|
||||
@ -376,7 +379,7 @@ class FrameManager extends EventEmitter {
|
||||
class Frame {
|
||||
/**
|
||||
* @param {!FrameManager} frameManager
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {?Frame} parentFrame
|
||||
* @param {string} frameId
|
||||
*/
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
const {assert} = require('./helper');
|
||||
const keyDefinitions = require('./USKeyboardLayout');
|
||||
// CDPSession is used only as a typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
/**
|
||||
* @typedef {Object} KeyDescription
|
||||
@ -28,7 +31,7 @@ const keyDefinitions = require('./USKeyboardLayout');
|
||||
|
||||
class Keyboard {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
@ -183,7 +186,7 @@ class Keyboard {
|
||||
|
||||
class Mouse {
|
||||
/**
|
||||
* @param {Puppeteer.CDPSession} client
|
||||
* @param {CDPSession} client
|
||||
* @param {!Keyboard} keyboard
|
||||
*/
|
||||
constructor(client, keyboard) {
|
||||
@ -274,7 +277,7 @@ class Mouse {
|
||||
|
||||
class Touchscreen {
|
||||
/**
|
||||
* @param {Puppeteer.CDPSession} client
|
||||
* @param {CDPSession} client
|
||||
* @param {Keyboard} keyboard
|
||||
*/
|
||||
constructor(client, keyboard) {
|
||||
|
@ -15,6 +15,9 @@
|
||||
*/
|
||||
|
||||
const {helper, assert, debugError} = require('./helper');
|
||||
// CDPSession is used only as a typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
function createJSHandle(context, remoteObject) {
|
||||
const frame = context.frame();
|
||||
@ -28,7 +31,7 @@ function createJSHandle(context, remoteObject) {
|
||||
class JSHandle {
|
||||
/**
|
||||
* @param {!Puppeteer.ExecutionContext} context
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Protocol.Runtime.RemoteObject} remoteObject
|
||||
*/
|
||||
constructor(context, client, remoteObject) {
|
||||
@ -142,7 +145,7 @@ class JSHandle {
|
||||
class ElementHandle extends JSHandle {
|
||||
/**
|
||||
* @param {!Puppeteer.ExecutionContext} context
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Protocol.Runtime.RemoteObject} remoteObject
|
||||
* @param {!Puppeteer.Page} page
|
||||
* @param {!Puppeteer.FrameManager} frameManager
|
||||
|
@ -16,10 +16,13 @@
|
||||
const EventEmitter = require('events');
|
||||
const {helper, assert, debugError} = require('./helper');
|
||||
const {Events} = require('./Events');
|
||||
// CDPSession is used only as a typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
class NetworkManager extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Puppeteer.FrameManager} frameManager
|
||||
*/
|
||||
constructor(client, ignoreHTTPSErrors, frameManager) {
|
||||
@ -312,7 +315,7 @@ class NetworkManager extends EventEmitter {
|
||||
|
||||
class Request {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {?Puppeteer.Frame} frame
|
||||
* @param {string} interceptionId
|
||||
* @param {boolean} allowInterception
|
||||
@ -524,7 +527,7 @@ const errorReasons = {
|
||||
|
||||
class Response {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Request} request
|
||||
* @param {!Protocol.Network.Response} responsePayload
|
||||
*/
|
||||
|
10
src/Page.js
10
src/Page.js
@ -18,7 +18,9 @@ const fs = require('fs');
|
||||
const EventEmitter = require('events');
|
||||
const mime = require('mime');
|
||||
const {Events} = require('./Events');
|
||||
const {Connection} = require('./Connection');
|
||||
// CDPSession is used only as a typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {Connection, CDPSession} = require('./Connection');
|
||||
const {Dialog} = require('./Dialog');
|
||||
const {EmulationManager} = require('./EmulationManager');
|
||||
const {FrameManager} = require('./FrameManager');
|
||||
@ -39,7 +41,7 @@ const writeFileAsync = helper.promisify(fs.writeFile);
|
||||
|
||||
class Page extends EventEmitter {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Puppeteer.Target} target
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {?Puppeteer.Viewport} defaultViewport
|
||||
@ -55,7 +57,7 @@ class Page extends EventEmitter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
* @param {!Puppeteer.Target} target
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {!TaskQueue} screenshotTaskQueue
|
||||
@ -1361,7 +1363,7 @@ class ConsoleMessage {
|
||||
|
||||
class FileChooser {
|
||||
/**
|
||||
* @param {Puppeteer.CDPSession} client
|
||||
* @param {CDPSession} client
|
||||
* @param {Puppeteer.ElementHandle} element
|
||||
* @param {!Protocol.Page.fileChooserOpenedPayload} event
|
||||
*/
|
||||
|
@ -17,6 +17,9 @@
|
||||
const {Events} = require('./Events');
|
||||
const {Page} = require('./Page');
|
||||
const {Worker: PuppeteerWorker} = require('./Worker');
|
||||
// CDPSession is used only as a typedef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
// This import is used as a TypeDef, but ESLint's rule doesn't
|
||||
// understand that unfortunately.
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
@ -26,7 +29,7 @@ class Target {
|
||||
/**
|
||||
* @param {!Protocol.Target.TargetInfo} targetInfo
|
||||
* @param {!Puppeteer.BrowserContext} browserContext
|
||||
* @param {!function():!Promise<!Puppeteer.CDPSession>} sessionFactory
|
||||
* @param {!function():!Promise<!CDPSession>} sessionFactory
|
||||
* @param {boolean} ignoreHTTPSErrors
|
||||
* @param {?Puppeteer.Viewport} defaultViewport
|
||||
* @param {!TaskQueue} screenshotTaskQueue
|
||||
@ -63,7 +66,7 @@ class Target {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<!Puppeteer.CDPSession>}
|
||||
* @return {!Promise<!CDPSession>}
|
||||
*/
|
||||
createCDPSession() {
|
||||
return this._sessionFactory();
|
||||
|
@ -14,10 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
const {helper, assert} = require('./helper');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
class Tracing {
|
||||
/**
|
||||
* @param {!Puppeteer.CDPSession} client
|
||||
* @param {!CDPSession} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this._client = client;
|
||||
|
@ -17,10 +17,13 @@ const EventEmitter = require('events');
|
||||
const {debugError} = require('./helper');
|
||||
const {ExecutionContext} = require('./ExecutionContext');
|
||||
const {JSHandle} = require('./JSHandle');
|
||||
// Used as a TypeDef
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const {CDPSession} = require('./Connection');
|
||||
|
||||
class Worker extends EventEmitter {
|
||||
/**
|
||||
* @param {Puppeteer.CDPSession} client
|
||||
* @param {CDPSession} client
|
||||
* @param {string} url
|
||||
* @param {function(string, !Array<!JSHandle>, Protocol.Runtime.StackTrace=):void} consoleAPICalled
|
||||
* @param {function(!Protocol.Runtime.ExceptionDetails):void} exceptionThrown
|
||||
|
6
src/externs.d.ts
vendored
6
src/externs.d.ts
vendored
@ -1,4 +1,3 @@
|
||||
import { Connection as RealConnection, CDPSession as RealCDPSession } from './Connection.js';
|
||||
import { Browser as RealBrowser, BrowserContext as RealBrowserContext} from './Browser.js';
|
||||
import {Target as RealTarget} from './Target.js';
|
||||
import {Page as RealPage} from './Page.js';
|
||||
@ -11,11 +10,6 @@ import { NetworkManager as RealNetworkManager, Request as RealRequest, Response
|
||||
import * as child_process from 'child_process';
|
||||
declare global {
|
||||
module Puppeteer {
|
||||
export class Connection extends RealConnection {}
|
||||
export class CDPSession extends RealCDPSession {
|
||||
on<T extends keyof Protocol.Events>(event: T, listener: (arg: Protocol.Events[T]) => void): this;
|
||||
send<T extends keyof Protocol.CommandParameters>(message: T, parameters?: Protocol.CommandParameters[T]): Promise<Protocol.CommandReturnValues[T]>;
|
||||
}
|
||||
export class Mouse extends RealMouse {}
|
||||
export class Keyboard extends RealKeyboard {}
|
||||
export class Touchscreen extends RealTouchscreen {}
|
||||
|
@ -19,6 +19,7 @@ import debug = require('debug');
|
||||
const debugError = debug('puppeteer:error');
|
||||
import fs = require('fs');
|
||||
import promisify = require('./promisify');
|
||||
import {CDPSession} from './Connection';
|
||||
|
||||
const {TimeoutError} = Errors;
|
||||
|
||||
@ -71,7 +72,7 @@ function valueFromRemoteObject(remoteObject: Protocol.Runtime.RemoteObject): unk
|
||||
return remoteObject.value;
|
||||
}
|
||||
|
||||
async function releaseObject(client: Puppeteer.CDPSession, remoteObject: Protocol.Runtime.RemoteObject): Promise<void> {
|
||||
async function releaseObject(client: CDPSession, remoteObject: Protocol.Runtime.RemoteObject): Promise<void> {
|
||||
if (!remoteObject.objectId)
|
||||
return;
|
||||
await client.send('Runtime.releaseObject', {objectId: remoteObject.objectId}).catch(error => {
|
||||
@ -185,7 +186,7 @@ async function waitWithTimeout<T extends any>(promise: Promise<T>, taskName: str
|
||||
}
|
||||
}
|
||||
|
||||
async function readProtocolStream(client: Puppeteer.CDPSession, handle: string, path?: string): Promise<Buffer> {
|
||||
async function readProtocolStream(client: CDPSession, handle: string, path?: string): Promise<Buffer> {
|
||||
let eof = false;
|
||||
let file;
|
||||
if (path)
|
||||
|
@ -247,6 +247,41 @@ function compareDocumentations(actual, expected) {
|
||||
checkType(source + ' ' + actual.name, actual.type, expected.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {!string} actualName
|
||||
* @param {!string} expectedName
|
||||
*/
|
||||
function namingMisMatchInTypeIsExpected(source, actualName, expectedName) {
|
||||
/* The DocLint tooling doesn't deal well with generics in TypeScript
|
||||
* source files. We could fix this but the longterm plan is to
|
||||
* auto-generate documentation from TS. So instead we document here
|
||||
* the methods that use generics that DocLint trips up on and if it
|
||||
* finds a mismatch that matches one of the cases below it doesn't
|
||||
* error. This still means we're protected from accidental changes, as
|
||||
* if the mismatch doesn't exactly match what's described below
|
||||
* DocLint will fail.
|
||||
*/
|
||||
const expectedNamingMismatches = new Map([
|
||||
['Method CDPSession.send() method', {
|
||||
actualName: 'string',
|
||||
expectedName: 'T'
|
||||
}],
|
||||
['Method CDPSession.send() params', {
|
||||
actualName: 'Object',
|
||||
expectedName: 'CommandParameters[T]'
|
||||
}],
|
||||
]);
|
||||
|
||||
const expectedForSource = expectedNamingMismatches.get(source);
|
||||
if (!expectedForSource) return false;
|
||||
|
||||
const namingMismatchIsExpected = expectedForSource.actualName === actualName && expectedForSource.expectedName === expectedName;
|
||||
|
||||
return namingMismatchIsExpected;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {!Documentation.Type} actual
|
||||
@ -260,8 +295,12 @@ function compareDocumentations(actual, expected) {
|
||||
const actualName = actual.name.replace(/[\? ]/g, '');
|
||||
// TypeScript likes to add some spaces
|
||||
const expectedName = expected.name.replace(/\ /g, '');
|
||||
if (expectedName !== actualName)
|
||||
if (expectedName !== actualName) {
|
||||
const namingMismatchIsExpected = namingMisMatchInTypeIsExpected(source, actualName, expectedName);
|
||||
|
||||
if (!namingMismatchIsExpected)
|
||||
errors.push(`${source} ${actualName} != ${expectedName}`);
|
||||
}
|
||||
const actualPropertiesMap = new Map(actual.properties.map(property => [property.name, property.type]));
|
||||
const expectedPropertiesMap = new Map(expected.properties.map(property => [property.name, property.type]));
|
||||
const propertiesDiff = diff(Array.from(actualPropertiesMap.keys()).sort(), Array.from(expectedPropertiesMap.keys()).sort());
|
||||
|
Loading…
Reference in New Issue
Block a user