chore: Use Typescript to lint JSDoc annotations (#986)

This patch starts using typescript to lint JSDoc annotations.

Note: this uses typescript's bleeding edge. We should migrate to stable once
it has all the necessary bugfixes.

References #65.
This commit is contained in:
JoelEinbinder 2017-10-09 22:31:40 -07:00 committed by Andrey Lushnikov
parent 7b5d7ddac2
commit e59172de83
22 changed files with 198 additions and 131 deletions

View File

@ -20,9 +20,9 @@ const EventEmitter = require('events');
class Browser extends EventEmitter { class Browser extends EventEmitter {
/** /**
* @param {!Connection} connection * @param {!Puppeteer.Connection} connection
* @param {!Object=} options * @param {!Object=} options
* @param {function():Promise=} closeCallback * @param {(function():Promise)=} closeCallback
*/ */
constructor(connection, options = {}, closeCallback) { constructor(connection, options = {}, closeCallback) {
super(); super();
@ -63,7 +63,6 @@ class Browser extends EventEmitter {
} }
} }
module.exports = Browser;
helper.tracePublicAPI(Browser); helper.tracePublicAPI(Browser);
class TaskQueue { class TaskQueue {
@ -81,3 +80,4 @@ class TaskQueue {
return result; return result;
} }
} }
module.exports = { Browser, TaskQueue };

View File

@ -173,7 +173,7 @@ class Session extends EventEmitter {
if (!this._callbacks.has(id)) if (!this._callbacks.has(id))
return; return;
const callback = this._callbacks.get(id); const callback = this._callbacks.get(id);
this._callbacks.delete(object.id); this._callbacks.delete(id);
callback.reject(e); callback.reject(e);
}); });
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -212,4 +212,4 @@ class Session extends EventEmitter {
} }
} }
module.exports = Connection; module.exports = {Connection, Session};

View File

@ -18,8 +18,8 @@ const {helper} = require('./helper');
class Dialog { class Dialog {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Dialog.Type} type * @param {string} type
* @param {string} message * @param {string} message
* @param {(string|undefined)} defaultValue * @param {(string|undefined)} defaultValue
*/ */

View File

@ -19,10 +19,10 @@ const {helper} = require('./helper');
class ElementHandle extends JSHandle { class ElementHandle extends JSHandle {
/** /**
* @param {!ExecutionContext} context * @param {!Puppeteer.ExecutionContext} context
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Object} remoteObject * @param {!Object} remoteObject
* @param {!Page} page * @param {!Puppeteer.Page} page
*/ */
constructor(context, client, remoteObject, page) { constructor(context, client, remoteObject, page) {
super(context, client, remoteObject); super(context, client, remoteObject);
@ -47,7 +47,7 @@ class ElementHandle extends JSHandle {
const error = await this.executionContext().evaluate(element => { const error = await this.executionContext().evaluate(element => {
if (!element.ownerDocument.contains(element)) if (!element.ownerDocument.contains(element))
return 'Node is detached from document'; return 'Node is detached from document';
if (element.nodeType !== HTMLElement.ELEMENT_NODE) if (element.nodeType !== Node.ELEMENT_NODE)
return 'Node is not of type HTMLElement'; return 'Node is not of type HTMLElement';
element.scrollIntoViewIfNeeded(); element.scrollIntoViewIfNeeded();
}, this); }, this);

View File

@ -16,7 +16,7 @@
class EmulationManager { class EmulationManager {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
*/ */
constructor(client) { constructor(client) {
this._client = client; this._client = client;
@ -25,7 +25,7 @@ class EmulationManager {
} }
/** /**
* @param {!Page.Viewport} viewport * @param {!EmulationManager.Viewport} viewport
* @return {Promise<boolean>} * @return {Promise<boolean>}
*/ */
async emulateViewport(client, viewport) { async emulateViewport(client, viewport) {
@ -61,6 +61,7 @@ class EmulationManager {
function injectedTouchEventsFunction() { function injectedTouchEventsFunction() {
const touchEvents = ['ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel']; const touchEvents = ['ontouchstart', 'ontouchend', 'ontouchmove', 'ontouchcancel'];
// @ts-ignore
const recepients = [window.__proto__, document.__proto__]; const recepients = [window.__proto__, document.__proto__];
for (let i = 0; i < touchEvents.length; ++i) { for (let i = 0; i < touchEvents.length; ++i) {
for (let j = 0; j < recepients.length; ++j) { for (let j = 0; j < recepients.length; ++j) {
@ -75,4 +76,14 @@ class EmulationManager {
} }
} }
/**
* @typedef {Object} EmulationManager.Viewport
* @property {number} width
* @property {number} height
* @property {number=} deviceScaleFactor
* @property {boolean=} isMobile
* @property {boolean=} isLandscape
* @property {boolean=} hasTouch
*/
module.exports = EmulationManager; module.exports = EmulationManager;

View File

@ -18,7 +18,7 @@ const {helper} = require('./helper');
class ExecutionContext { class ExecutionContext {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {string} contextId * @param {string} contextId
* @param {function(*):!JSHandle} objectHandleFactory * @param {function(*):!JSHandle} objectHandleFactory
*/ */
@ -100,7 +100,7 @@ class ExecutionContext {
class JSHandle { class JSHandle {
/** /**
* @param {!ExecutionContext} context * @param {!ExecutionContext} context
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Object} remoteObject * @param {!Object} remoteObject
*/ */
constructor(context, client, remoteObject) { constructor(context, client, remoteObject) {
@ -134,7 +134,7 @@ class JSHandle {
} }
/** /**
* @return {!Property<Map<string, !ObjectHandle>>} * @return {!Promise<Map<string, !JSHandle>>}
*/ */
async getProperties() { async getProperties() {
const response = await this._client.send('Runtime.getProperties', { const response = await this._client.send('Runtime.getProperties', {
@ -162,7 +162,7 @@ class JSHandle {
} }
/** /**
* @return {?ElementHandle} * @return {?Puppeteer.ElementHandle}
*/ */
asElement() { asElement() {
return null; return null;

View File

@ -22,8 +22,8 @@ const ElementHandle = require('./ElementHandle');
class FrameManager extends EventEmitter { class FrameManager extends EventEmitter {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Page} page * @param {!Puppeteer.Page} page
*/ */
constructor(client, page) { constructor(client, page) {
super(); super();
@ -87,7 +87,7 @@ class FrameManager extends EventEmitter {
if (isMainFrame) { if (isMainFrame) {
if (frame) { if (frame) {
// Update frame id to retain frame identity on cross-process navigation. // Update frame id to retain frame identity on cross-process navigation.
this._frames.delete(frame._id, frame); this._frames.delete(frame._id);
frame._id = framePayload.id; frame._id = framePayload.id;
} else { } else {
// Initial main frame navigation. // Initial main frame navigation.
@ -154,7 +154,6 @@ class FrameManager extends EventEmitter {
} }
/** /**
* @param {!Frame} frame
* @return {boolean} * @return {boolean}
*/ */
isMainFrameLoadingFailed() { isMainFrameLoadingFailed() {
@ -174,7 +173,7 @@ FrameManager.Events = {
*/ */
class Frame { class Frame {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {?Frame} parentFrame * @param {?Frame} parentFrame
* @param {string} frameId * @param {string} frameId
*/ */
@ -202,9 +201,9 @@ class Frame {
} }
/** /**
* @param {function()|string} pageFunction * @param {Function|string} pageFunction
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise<(!Object|undefined)>} * @return {!Promise<*>}
*/ */
async evaluate(pageFunction, ...args) { async evaluate(pageFunction, ...args) {
return this._context.evaluate(pageFunction, ...args); return this._context.evaluate(pageFunction, ...args);
@ -225,7 +224,7 @@ class Frame {
/** /**
* @param {string} selector * @param {string} selector
* @param {function()|string} pageFunction * @param {Function|string} pageFunction
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise<(!Object|undefined)>} * @return {!Promise<(!Object|undefined)>}
*/ */
@ -344,14 +343,14 @@ class Frame {
} }
/** /**
* @param {(string|number|function())} selectorOrTimeout * @param {(string|number|Function)} selectorOrFunctionOrTimeout
* @param {!Object=} options * @param {!Object=} options
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise} * @return {!Promise}
*/ */
waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) { waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) {
if (helper.isString(selectorOrFunctionOrTimeout)) if (helper.isString(selectorOrFunctionOrTimeout))
return this.waitForSelector(selectorOrFunctionOrTimeout, options); return this.waitForSelector(/** @type {string} */(selectorOrFunctionOrTimeout), options);
if (helper.isNumber(selectorOrFunctionOrTimeout)) if (helper.isNumber(selectorOrFunctionOrTimeout))
return new Promise(fulfill => setTimeout(fulfill, selectorOrFunctionOrTimeout)); return new Promise(fulfill => setTimeout(fulfill, selectorOrFunctionOrTimeout));
if (typeof selectorOrFunctionOrTimeout === 'function') if (typeof selectorOrFunctionOrTimeout === 'function')
@ -387,7 +386,7 @@ class Frame {
} }
/** /**
* @param {function()} pageFunction * @param {Function} pageFunction
* @param {!Object=} options * @param {!Object=} options
* @return {!Promise} * @return {!Promise}
*/ */
@ -429,7 +428,7 @@ class WaitTask {
/** /**
* @param {!Frame} frame * @param {!Frame} frame
* @param {string} predicateBody * @param {string} predicateBody
* @param {string} polling * @param {string|number} polling
* @param {number} timeout * @param {number} timeout
*/ */
constructor(frame, predicateBody, polling, timeout) { constructor(frame, predicateBody, polling, timeout) {
@ -524,7 +523,7 @@ async function waitForPredicatePageFunction(predicateBody, polling, timeout) {
return !timedOut; return !timedOut;
/** /**
* @return {!Promise<!Element>} * @return {!Promise}
*/ */
function pollMutation() { function pollMutation() {
if (predicate()) if (predicate())
@ -582,4 +581,4 @@ async function waitForPredicatePageFunction(predicateBody, polling, timeout) {
} }
} }
module.exports = FrameManager; module.exports = {FrameManager, Frame};

View File

@ -18,7 +18,7 @@ const {helper} = require('./helper');
class Keyboard { class Keyboard {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
*/ */
constructor(client) { constructor(client) {
this._client = client; this._client = client;
@ -28,10 +28,10 @@ class Keyboard {
/** /**
* @param {string} key * @param {string} key
* @param {{text: (string|undefined)}} options * @param {{text: string}=} options
*/ */
async down(key, options = {}) { async down(key, options = {text: ''}) {
const text = options.text; const {text} = options;
const autoRepeat = this._pressedKeys.has(key); const autoRepeat = this._pressedKeys.has(key);
this._pressedKeys.add(key); this._pressedKeys.add(key);
this._modifiers |= this._modifierBit(key); this._modifiers |= this._modifierBit(key);
@ -118,7 +118,7 @@ class Keyboard {
class Mouse { class Mouse {
/** /**
* @param {!Session} client * @param {Puppeteer.Session} client
* @param {!Keyboard} keyboard * @param {!Keyboard} keyboard
*/ */
constructor(client, keyboard) { constructor(client, keyboard) {
@ -197,7 +197,7 @@ class Mouse {
class Touchscreen { class Touchscreen {
/** /**
* @param {Session} client * @param {Puppeteer.Session} client
* @param {Keyboard} keyboard * @param {Keyboard} keyboard
*/ */
constructor(client, keyboard) { constructor(client, keyboard) {

View File

@ -18,11 +18,12 @@ const path = require('path');
const removeSync = require('rimraf').sync; const removeSync = require('rimraf').sync;
const childProcess = require('child_process'); const childProcess = require('child_process');
const Downloader = require('../utils/ChromiumDownloader'); const Downloader = require('../utils/ChromiumDownloader');
const Connection = require('./Connection'); const {Connection} = require('./Connection');
const Browser = require('./Browser'); const {Browser} = require('./Browser');
const readline = require('readline'); const readline = require('readline');
const fs = require('fs'); const fs = require('fs');
const {helper} = require('./helper'); const {helper} = require('./helper');
// @ts-ignore
const ChromiumRevision = require('../package.json').puppeteer.chromium_revision; const ChromiumRevision = require('../package.json').puppeteer.chromium_revision;
const CHROME_PROFILE_PATH = path.join(os.tmpdir(), 'puppeteer_dev_profile-'); const CHROME_PROFILE_PATH = path.join(os.tmpdir(), 'puppeteer_dev_profile-');
@ -178,7 +179,7 @@ class Launcher {
} }
/** /**
* @param {!ChildProcess} chromeProcess * @param {!Puppeteer.ChildProcess} chromeProcess
* @param {number} timeout * @param {number} timeout
* @return {!Promise<string>} * @return {!Promise<string>}
*/ */

View File

@ -14,19 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
/**
* @template K, V
*/
class Multimap { class Multimap {
constructor() { constructor() {
/** @type {!Map<K, !Set<!V>>} */
this._map = new Map(); this._map = new Map();
} }
/**
* @param {K} key
* @param {V} value
*/
set(key, value) { set(key, value) {
let set = this._map.get(key); let set = this._map.get(key);
if (!set) { if (!set) {
@ -36,10 +28,6 @@ class Multimap {
set.add(value); set.add(value);
} }
/**
* @param {K} key
* @return {!Set<!V>}
*/
get(key) { get(key) {
let result = this._map.get(key); let result = this._map.get(key);
if (!result) if (!result)
@ -47,19 +35,10 @@ class Multimap {
return result; return result;
} }
/**
* @param {K} key
* @return {boolean}
*/
has(key) { has(key) {
return this._map.has(key); return this._map.has(key);
} }
/**
* @param {K} key
* @param {V} value
* @return {boolean}
*/
hasValue(key, value) { hasValue(key, value) {
const set = this._map.get(key); const set = this._map.get(key);
if (!set) if (!set)
@ -74,11 +53,6 @@ class Multimap {
return this._map.size; return this._map.size;
} }
/**
* @param {K} key
* @param {V} value
* @return {boolean}
*/
delete(key, value) { delete(key, value) {
const values = this.get(key); const values = this.get(key);
const result = values.delete(value); const result = values.delete(value);
@ -87,17 +61,10 @@ class Multimap {
return result; return result;
} }
/**
* @param {K} key
*/
deleteAll(key) { deleteAll(key) {
this._map.delete(key); this._map.delete(key);
} }
/**
* @param {K} key
* @return {?V} value
*/
firstValue(key) { firstValue(key) {
const set = this._map.get(key); const set = this._map.get(key);
if (!set) if (!set)
@ -105,16 +72,10 @@ class Multimap {
return set.values().next().value; return set.values().next().value;
} }
/**
* @return {K}
*/
firstKey() { firstKey() {
return this._map.keys().next().value; return this._map.keys().next().value;
} }
/**
* @return {!Array<!V>}
*/
valuesArray() { valuesArray() {
const result = []; const result = [];
for (const key of this._map.keys()) for (const key of this._map.keys())
@ -122,9 +83,6 @@ class Multimap {
return result; return result;
} }
/**
* @return {!Array<!K>}
*/
keysArray() { keysArray() {
return Array.from(this._map.keys()); return Array.from(this._map.keys());
} }

View File

@ -18,7 +18,7 @@ const {helper} = require('./helper');
class NavigatorWatcher { class NavigatorWatcher {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {boolean} ignoreHTTPSErrors * @param {boolean} ignoreHTTPSErrors
* @param {!Object=} options * @param {!Object=} options
*/ */

View File

@ -20,7 +20,7 @@ const url = require('url');
class NetworkManager extends EventEmitter { class NetworkManager extends EventEmitter {
/** /**
* @param {!Session} client * @param {Puppeteer.Session} client
*/ */
constructor(client) { constructor(client) {
super(); super();
@ -38,9 +38,9 @@ class NetworkManager extends EventEmitter {
this._attemptedAuthentications = new Set(); this._attemptedAuthentications = new Set();
this._userRequestInterceptionEnabled = false; this._userRequestInterceptionEnabled = false;
this._protocolRequestInterceptionEnabled = false; this._protocolRequestInterceptionEnabled = false;
/** @type {!Multimap<string, string>} */ /** @type {!Multimap} */
this._requestHashToRequestIds = new Multimap(); this._requestHashToRequestIds = new Multimap();
/** @type {!Multimap<string, !Object>} */ /** @type {!Multimap} */
this._requestHashToInterceptions = new Multimap(); this._requestHashToInterceptions = new Multimap();
this._client.on('Network.requestWillBeSent', this._onRequestWillBeSent.bind(this)); this._client.on('Network.requestWillBeSent', this._onRequestWillBeSent.bind(this));
@ -116,7 +116,7 @@ class NetworkManager extends EventEmitter {
response = 'ProvideCredentials'; response = 'ProvideCredentials';
this._attemptedAuthentications.add(event.interceptionId); this._attemptedAuthentications.add(event.interceptionId);
} }
const {username, password} = this._credentials || {}; const {username, password} = this._credentials || {username: undefined, password: undefined};
this._client.send('Network.continueInterceptedRequest', { this._client.send('Network.continueInterceptedRequest', {
interceptionId: event.interceptionId, interceptionId: event.interceptionId,
authChallengeResponse: { response, username, password } authChallengeResponse: { response, username, password }
@ -192,7 +192,6 @@ class NetworkManager extends EventEmitter {
/** /**
* @param {string} requestHash * @param {string} requestHash
* @param {!{requestEvent: ?Object, interceptionEvent: ?Object}} interception
*/ */
_maybeResolveInterception(requestHash) { _maybeResolveInterception(requestHash) {
const requestId = this._requestHashToRequestIds.firstValue(requestHash); const requestId = this._requestHashToRequestIds.firstValue(requestHash);
@ -252,10 +251,10 @@ class NetworkManager extends EventEmitter {
class Request { class Request {
/** /**
* @param {!Connection} client * @param {!Puppeteer.Session} client
* @param {string} requestId * @param {string} requestId
* @param {string} interceptionId * @param {string} interceptionId
* @param {string} allowInterception * @param {boolean} allowInterception
* @param {string} url * @param {string} url
* @param {string} resourceType * @param {string} resourceType
* @param {!Object} payload * @param {!Object} payload
@ -331,9 +330,9 @@ helper.tracePublicAPI(Request);
class Response { class Response {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Request} request * @param {!Request} request
* @param {integer} status * @param {number} status
* @param {!Object} headers * @param {!Object} headers
*/ */
constructor(client, request, status, headers) { constructor(client, request, status, headers) {
@ -381,7 +380,7 @@ class Response {
} }
/** /**
* @return {!Response} * @return {!Request}
*/ */
request() { request() {
return this._request; return this._request;

View File

@ -21,18 +21,17 @@ const NetworkManager = require('./NetworkManager');
const NavigatorWatcher = require('./NavigatorWatcher'); const NavigatorWatcher = require('./NavigatorWatcher');
const Dialog = require('./Dialog'); const Dialog = require('./Dialog');
const EmulationManager = require('./EmulationManager'); const EmulationManager = require('./EmulationManager');
const FrameManager = require('./FrameManager'); const {FrameManager} = require('./FrameManager');
const {Keyboard, Mouse, Touchscreen} = require('./Input'); const {Keyboard, Mouse, Touchscreen} = require('./Input');
const Tracing = require('./Tracing'); const Tracing = require('./Tracing');
const {helper, debugError} = require('./helper'); const {helper, debugError} = require('./helper');
class Page extends EventEmitter { class Page extends EventEmitter {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {string} sessionId
* @param {boolean} ignoreHTTPSErrors * @param {boolean} ignoreHTTPSErrors
* @param {boolean} appMode * @param {boolean} appMode
* @param {!TaskQueue} screenshotTaskQueue * @param {!Puppeteer.TaskQueue} screenshotTaskQueue
* @return {!Promise<!Page>} * @return {!Promise<!Page>}
*/ */
static async create(client, ignoreHTTPSErrors, appMode, screenshotTaskQueue) { static async create(client, ignoreHTTPSErrors, appMode, screenshotTaskQueue) {
@ -53,9 +52,9 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {boolean} ignoreHTTPSErrors * @param {boolean} ignoreHTTPSErrors
* @param {!TaskQueue} screenshotTaskQueue * @param {!Puppeteer.TaskQueue} screenshotTaskQueue
*/ */
constructor(client, ignoreHTTPSErrors, screenshotTaskQueue) { constructor(client, ignoreHTTPSErrors, screenshotTaskQueue) {
super(); super();
@ -67,7 +66,7 @@ class Page extends EventEmitter {
this._networkManager = new NetworkManager(client); this._networkManager = new NetworkManager(client);
this._emulationManager = new EmulationManager(client); this._emulationManager = new EmulationManager(client);
this._tracing = new Tracing(client); this._tracing = new Tracing(client);
/** @type {!Map<string, function>} */ /** @type {!Map<string, Function>} */
this._pageBindings = new Map(); this._pageBindings = new Map();
this._ignoreHTTPSErrors = ignoreHTTPSErrors; this._ignoreHTTPSErrors = ignoreHTTPSErrors;
@ -95,7 +94,7 @@ class Page extends EventEmitter {
} }
/** /**
* @return {!Frame} * @return {!Puppeteer.Frame}
*/ */
mainFrame() { mainFrame() {
return this._frameManager.mainFrame(); return this._frameManager.mainFrame();
@ -133,7 +132,7 @@ class Page extends EventEmitter {
} }
/** /**
* @return {!Array<!Frame>} * @return {!Array<Puppeteer.Frame>}
*/ */
frames() { frames() {
return this._frameManager.frames(); return this._frameManager.frames();
@ -160,17 +159,16 @@ class Page extends EventEmitter {
/** /**
* @param {string} selector * @param {string} selector
* @return {!Promise<?ElementHandle>} * @return {!Promise<?Puppeteer.ElementHandle>}
*/ */
async $(selector) { async $(selector) {
return this.mainFrame().$(selector); return this.mainFrame().$(selector);
} }
/** /**
* @param {string} selector
* @param {function()|string} pageFunction * @param {function()|string} pageFunction
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise<!JSHandle>} * @return {!Promise<!Puppeteer.JSHandle>}
*/ */
async evaluateHandle(pageFunction, ...args) { async evaluateHandle(pageFunction, ...args) {
return this.mainFrame().executionContext().evaluateHandle(pageFunction, ...args); return this.mainFrame().executionContext().evaluateHandle(pageFunction, ...args);
@ -188,7 +186,7 @@ class Page extends EventEmitter {
/** /**
* @param {string} selector * @param {string} selector
* @return {!Promise<!Array<!ElementHandle>>} * @return {!Promise<!Array<!Puppeteer.ElementHandle>>}
*/ */
async $$(selector) { async $$(selector) {
return this.mainFrame().$$(selector); return this.mainFrame().$$(selector);
@ -385,7 +383,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {string} html * @param {string} url
* @param {!Object=} options * @param {!Object=} options
* @return {!Promise<?Response>} * @return {!Promise<?Response>}
*/ */
@ -518,7 +516,7 @@ class Page extends EventEmitter {
/** /**
* @param {function()} pageFunction * @param {function()} pageFunction
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise<(!Object|undefined)>} * @return {!Promise<*>}
*/ */
async evaluate(pageFunction, ...args) { async evaluate(pageFunction, ...args) {
return this._frameManager.mainFrame().evaluate(pageFunction, ...args); return this._frameManager.mainFrame().evaluate(pageFunction, ...args);
@ -749,7 +747,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {(string|number|function())} selectorOrTimeout * @param {(string|number|Function)} selectorOrFunctionOrTimeout
* @param {!Object=} options * @param {!Object=} options
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise} * @return {!Promise}
@ -811,7 +809,7 @@ function convertPrintParameterToInches(parameter) {
// Treat numbers as pixel values to be aligned with phantom's paperSize. // Treat numbers as pixel values to be aligned with phantom's paperSize.
pixels = /** @type {number} */ (parameter); pixels = /** @type {number} */ (parameter);
} else if (helper.isString(parameter)) { } else if (helper.isString(parameter)) {
const text = parameter; const text = /** @type {string} */ (parameter);
let unit = text.substring(text.length - 2).toLowerCase(); let unit = text.substring(text.length - 2).toLowerCase();
let valueText = ''; let valueText = '';
if (unitToPixels.hasOwnProperty(unit)) { if (unitToPixels.hasOwnProperty(unit)) {
@ -848,8 +846,15 @@ Page.Events = {
Load: 'load', Load: 'load',
}; };
/** @typedef {{width: number, height: number, deviceScaleFactor: number|undefined, isMobile: boolean|undefined, isLandscape: boolean, hasTouch: boolean|undefined}} */ /**
Page.Viewport; * @typedef {Object} Page.Viewport
* @property {number} width
* @property {number} height
* @property {number=} deviceScaleFactor
* @property {boolean=} isMobile
* @property {boolean=} isLandscape
* @property {boolean=} hasTouch
*/
/** /**
* @typedef {Object} Network.Cookie * @typedef {Object} Network.Cookie

View File

@ -19,15 +19,15 @@ const Launcher = require('./Launcher');
class Puppeteer { class Puppeteer {
/** /**
* @param {!Object=} options * @param {!Object=} options
* @return {!Promise<!Browser>} * @return {!Promise<!Puppeteer.Browser>}
*/ */
static launch(options) { static launch(options) {
return Launcher.launch(options); return Launcher.launch(options);
} }
/** /**
* @param {string} options * @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean}} options
* @return {!Promise<!Browser>} * @return {!Promise<!Puppeteer.Browser>}
*/ */
static connect(options) { static connect(options) {
return Launcher.connect(options); return Launcher.connect(options);

View File

@ -18,7 +18,7 @@ const {helper} = require('./helper');
class Tracing { class Tracing {
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
*/ */
constructor(client) { constructor(client) {
this._client = client; this._client = client;

28
lib/externs.d.ts vendored Normal file
View File

@ -0,0 +1,28 @@
import { Connection as RealConnection, Session as RealSession } from './Connection.js';
import {Browser as RealBrowser, TaskQueue as RealTaskQueue} from './Browser.js';
import * as RealPage from './Page.js';
import {Mouse as RealMouse, Keyboard as RealKeyboard, Touchscreen as RealTouchscreen} from './Input.js';
import {Frame as RealFrame, FrameManager as RealFrameManager} from './FrameManager.js';
import {JSHandle as RealJSHandle, ExecutionContext as RealExecutionContext} from './ExecutionContext.js';
import * as RealElementHandle from './ElementHandle.js';
import * as RealNetworkManager from './NetworkManager.js';
import * as child_process from 'child_process';
export as namespace Puppeteer;
export class Connection extends RealConnection {}
export class Session extends RealSession {}
export class Mouse extends RealMouse {}
export class Keyboard extends RealKeyboard {}
export class Touchscreen extends RealTouchscreen {}
export class TaskQueue extends RealTaskQueue {}
export class Browser extends RealBrowser {}
export class Frame extends RealFrame {}
export class FrameManager extends RealFrameManager {}
export class NetworkManager extends RealNetworkManager {}
export class ElementHandle extends RealElementHandle {}
export class JSHandle extends RealJSHandle {}
export class ExecutionContext extends RealExecutionContext {}
export class Page extends RealPage {}
export interface ChildProcess extends child_process.ChildProcess {}

View File

@ -19,14 +19,14 @@ const debugError = require('debug')(`puppeteer:error`);
let apiCoverage = null; let apiCoverage = null;
class Helper { class Helper {
/** /**
* @param {function()|string} fun * @param {Function|string} fun
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {string} * @return {string}
*/ */
static evaluationString(fun, ...args) { static evaluationString(fun, ...args) {
if (Helper.isString(fun)) { if (Helper.isString(fun)) {
console.assert(args.length === 0, 'Cannot evaluate a string with arguments'); console.assert(args.length === 0, 'Cannot evaluate a string with arguments');
return fun; return /** @type {string} */ (fun);
} }
return `(${fun})(${args.map(serializeArgument).join(',')})`; return `(${fun})(${args.map(serializeArgument).join(',')})`;
@ -60,9 +60,8 @@ class Helper {
} }
/** /**
* @param {!Session} client
* @param {!Object} remoteObject * @param {!Object} remoteObject
* @return {!Promise<!Object>} * @return {*}
*/ */
static valueFromRemoteObject(remoteObject) { static valueFromRemoteObject(remoteObject) {
console.assert(!remoteObject.objectId, 'Cannot extract value when objectId is given'); console.assert(!remoteObject.objectId, 'Cannot extract value when objectId is given');
@ -84,7 +83,7 @@ class Helper {
} }
/** /**
* @param {!Session} client * @param {!Puppeteer.Session} client
* @param {!Object} remoteObject * @param {!Object} remoteObject
*/ */
static async releaseObject(client, remoteObject) { static async releaseObject(client, remoteObject) {
@ -165,10 +164,10 @@ class Helper {
} }
/** /**
* @param {!EventEmitter} emitter * @param {!NodeJS.EventEmitter} emitter
* @param {string} eventName * @param {string} eventName
* @param {function(?)} handler * @param {function(?)} handler
* @return {{emitter: !EventEmitter, eventName: string, handler: function(?)}} * @return {{emitter: !NodeJS.EventEmitter, eventName: string, handler: function(?)}}
*/ */
static addEventListener(emitter, eventName, handler) { static addEventListener(emitter, eventName, handler) {
emitter.on(eventName, handler); emitter.on(eventName, handler);
@ -176,7 +175,7 @@ class Helper {
} }
/** /**
* @param {!Array<{emitter: !EventEmitter, eventName: string, handler: function(?)}>} * @param {!Array<{emitter: !NodeJS.EventEmitter, eventName: string, handler: function(?)}>} listeners
*/ */
static removeEventListeners(listeners) { static removeEventListeners(listeners) {
for (const listener of listeners) for (const listener of listeners)

View File

@ -13,12 +13,13 @@
"test-doclint": "jasmine utils/doclint/check_public_api/test/test.js && jasmine utils/doclint/preprocessor/test.js", "test-doclint": "jasmine utils/doclint/check_public_api/test/test.js && jasmine utils/doclint/preprocessor/test.js",
"test": "npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-node6-transformer", "test": "npm run lint --silent && npm run coverage && npm run test-doclint && npm run test-node6-transformer",
"install": "node install.js", "install": "node install.js",
"lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run doc", "lint": "([ \"$CI\" = true ] && eslint --quiet -f codeframe . || eslint .) && npm run tsc && npm run doc",
"doc": "node utils/doclint/cli.js", "doc": "node utils/doclint/cli.js",
"coverage": "COVERAGE=true npm run unit", "coverage": "COVERAGE=true npm run unit",
"test-node6-transformer": "jasmine utils/node6-transform/test/test.js", "test-node6-transformer": "jasmine utils/node6-transform/test/test.js",
"build": "node utils/node6-transform/index.js", "build": "node utils/node6-transform/index.js",
"unit-node6": "jasmine node6-test/test.js" "unit-node6": "jasmine node6-test/test.js",
"tsc": "tsc -p ."
}, },
"author": "The Chromium Authors", "author": "The Chromium Authors",
"license": "Apache-2.0", "license": "Apache-2.0",
@ -36,6 +37,12 @@
"chromium_revision": "503964" "chromium_revision": "503964"
}, },
"devDependencies": { "devDependencies": {
"@types/debug": "0.0.30",
"@types/extract-zip": "^1.6.2",
"@types/mime": "^1.3.1",
"@types/node": "^8.0.26",
"@types/rimraf": "^2.0.2",
"@types/ws": "^3.0.2",
"commonmark": "^0.27.0", "commonmark": "^0.27.0",
"eslint": "^4.0.0", "eslint": "^4.0.0",
"esprima": "^4.0.0", "esprima": "^4.0.0",
@ -46,6 +53,7 @@
"pdfjs-dist": "^1.8.595", "pdfjs-dist": "^1.8.595",
"pixelmatch": "^4.0.2", "pixelmatch": "^4.0.2",
"pngjs": "^3.2.0", "pngjs": "^3.2.0",
"text-diff": "^1.0.1" "text-diff": "^1.0.1",
"typescript": "next"
} }
} }

11
tsconfig.json Normal file
View File

@ -0,0 +1,11 @@
{
"compilerOptions": {
"noEmit": true,
"allowJs": true,
"checkJs": true,
"target": "es2017"
},
"include": [
"lib"
]
}

View File

@ -22,7 +22,9 @@ const extract = require('extract-zip');
const util = require('util'); const util = require('util');
const URL = require('url'); const URL = require('url');
const removeRecursive = require('rimraf'); const removeRecursive = require('rimraf');
// @ts-ignore
const ProxyAgent = require('https-proxy-agent'); const ProxyAgent = require('https-proxy-agent');
// @ts-ignore
const getProxyForUrl = require('proxy-from-env').getProxyForUrl; const getProxyForUrl = require('proxy-from-env').getProxyForUrl;
const DOWNLOADS_FOLDER = path.join(__dirname, '..', '.local-chromium'); const DOWNLOADS_FOLDER = path.join(__dirname, '..', '.local-chromium');
@ -144,7 +146,7 @@ module.exports = {
else if (platform === 'win32' || platform === 'win64') else if (platform === 'win32' || platform === 'win64')
executablePath = path.join(folderPath, 'chrome-win32', 'chrome.exe'); executablePath = path.join(folderPath, 'chrome-win32', 'chrome.exe');
else else
throw 'Unsupported platfrom: ' + platfrom; throw 'Unsupported platfrom: ' + platform;
return { return {
executablePath, executablePath,
folderPath, folderPath,
@ -202,7 +204,7 @@ function downloadFile(url, destinationPath, progressCallback) {
file.on('finish', () => fulfill()); file.on('finish', () => fulfill());
file.on('error', error => reject(error)); file.on('error', error => reject(error));
response.pipe(file); response.pipe(file);
const totalBytes = parseInt(response.headers['content-length'], 10); const totalBytes = parseInt(/** @type {string} */ (response.headers['content-length']), 10);
if (progressCallback) if (progressCallback)
response.on('data', onData.bind(null, totalBytes)); response.on('data', onData.bind(null, totalBytes));
}); });
@ -224,11 +226,13 @@ function extractZip(zipPath, folderPath) {
} }
function requestOptions(url, method = 'GET') { function requestOptions(url, method = 'GET') {
/** @type {Object} */
const result = URL.parse(url); const result = URL.parse(url);
result.method = method; result.method = method;
const proxyURL = getProxyForUrl(url); const proxyURL = getProxyForUrl(url);
if (proxyURL) { if (proxyURL) {
/** @type {Object} */
const parsedProxyURL = URL.parse(proxyURL); const parsedProxyURL = URL.parse(proxyURL);
parsedProxyURL.secureProxy = parsedProxyURL.protocol === 'https:'; parsedProxyURL.secureProxy = parsedProxyURL.protocol === 'https:';

View File

@ -86,13 +86,13 @@ class JSOutline {
} }
const args = []; const args = [];
for (const param of node.value.params) { for (const param of node.value.params) {
if (param.type === 'AssignmentPattern') if (param.type === 'AssignmentPattern' && param.left.name)
args.push(new Documentation.Argument(param.left.name)); args.push(new Documentation.Argument(param.left.name));
else if (param.type === 'RestElement') else if (param.type === 'RestElement')
args.push(new Documentation.Argument('...' + param.argument.name)); args.push(new Documentation.Argument('...' + param.argument.name));
else if (param.type === 'Identifier') else if (param.type === 'Identifier')
args.push(new Documentation.Argument(param.name)); args.push(new Documentation.Argument(param.name));
else if (param.type === 'ObjectPattern') else if (param.type === 'ObjectPattern' || param.type === 'AssignmentPattern')
args.push(new Documentation.Argument('options')); args.push(new Documentation.Argument('options'));
else else
this.errors.push(`JS Parsing issue: unsupported syntax to define parameter in ${this._currentClassName}.${methodName}(): ${this._extractText(param)}`); this.errors.push(`JS Parsing issue: unsupported syntax to define parameter in ${this._currentClassName}.${methodName}(): ${this._extractText(param)}`);

View File

@ -2,6 +2,46 @@
# yarn lockfile v1 # yarn lockfile v1
"@types/debug@0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-0.0.30.tgz#dc1e40f7af3b9c815013a7860e6252f6352a84df"
"@types/extract-zip@^1.6.2":
version "1.6.2"
resolved "https://registry.yarnpkg.com/@types/extract-zip/-/extract-zip-1.6.2.tgz#5c7eb441c41136167a42b88b64051e6260c29e86"
"@types/glob@*":
version "5.0.32"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.32.tgz#aec5cfe987c72f099fdb1184452986aa506d5e8f"
dependencies:
"@types/minimatch" "*"
"@types/node" "*"
"@types/mime@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.1.tgz#2cf42972d0931c1060c7d5fa6627fce6bd876f2f"
"@types/minimatch@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.1.tgz#b683eb60be358304ef146f5775db4c0e3696a550"
"@types/node@*", "@types/node@^8.0.26":
version "8.0.26"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.26.tgz#4d58be925306fd22b1141085535a0268b8beb189"
"@types/rimraf@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e"
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/ws@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-3.0.2.tgz#b538b6a16daee454ac04054991271f3da38772de"
dependencies:
"@types/node" "*"
acorn-jsx@^3.0.0: acorn-jsx@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
@ -1070,6 +1110,10 @@ typedarray@^0.0.6:
version "0.0.6" version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
typescript@next:
version "2.6.0-dev.20171007"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.0-dev.20171007.tgz#feead6b2bd906771c95fb8ae27e146d5b5ff6cd6"
ultron@~1.1.0: ultron@~1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864"