Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/Coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class JSCoverage {
}

/**
* @param {!Object} event
* @param {!Protocol.Debugger.scriptParsedPayload} event
*/
async _onScriptParsed(event) {
// Ignore anonymous scripts
Expand Down Expand Up @@ -193,7 +193,7 @@ class CSSCoverage {
}

/**
* @param {!Object} event
* @param {!Protocol.CSS.styleSheetAddedPayload} event
*/
async _onStyleSheet(event) {
const header = event.header;
Expand Down
2 changes: 1 addition & 1 deletion lib/ElementHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class ElementHandle extends JSHandle {
}

/**
* @return {!Promise<?{model: object}>}
* @return {!Promise<void|Protocol.DOM.getBoxModelReturnValue>}
*/
_getBoxModel() {
return this._client.send('DOM.getBoxModel', {
Expand Down
4 changes: 2 additions & 2 deletions lib/EmulationManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ class EmulationManager {
const width = viewport.width;
const height = viewport.height;
const deviceScaleFactor = viewport.deviceScaleFactor || 1;
/** @type {Protocol.Emulation.ScreenOrientation} */
const screenOrientation = viewport.isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' };

await Promise.all([
this._client.send('Emulation.setDeviceMetricsOverride', { mobile, width, height, deviceScaleFactor, screenOrientation }),
this._client.send('Emulation.setTouchEmulationEnabled', {
enabled: viewport.hasTouch || false,
configuration: viewport.isMobile ? 'mobile' : 'desktop'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is configuration removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such option on Emulation.setTouchEmulationEnabled. It is only on Page.setTouchEmulationEnabled.

enabled: viewport.hasTouch || false
})
]);

Expand Down
2 changes: 1 addition & 1 deletion lib/ExecutionContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ExecutionContext {
async evaluateHandle(pageFunction, ...args) {
if (helper.isString(pageFunction)) {
const contextId = this._contextId;
const expression = pageFunction;
const expression = /** @type {string} */ (pageFunction);
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', { expression, contextId, returnByValue: false, awaitPromise: true});
if (exceptionDetails)
throw new Error('Evaluation failed: ' + helper.getExceptionMessage(exceptionDetails));
Expand Down
12 changes: 6 additions & 6 deletions lib/FrameManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const readFileAsync = helper.promisify(fs.readFile);
class FrameManager extends EventEmitter {
/**
* @param {!Puppeteer.CDPSession} client
* @param {{frame: Object, childFrames: ?Array}} frameTree
* @param {!Protocol.Page.FrameTree} frameTree
* @param {!Puppeteer.Page} page
*/
constructor(client, frameTree, page) {
Expand All @@ -34,7 +34,7 @@ class FrameManager extends EventEmitter {
this._page = page;
/** @type {!Map<string, !Frame>} */
this._frames = new Map();
/** @type {!Map<string, !ExecutionContext>} */
/** @type {!Map<number, !ExecutionContext>} */
this._contextIdToContext = new Map();

this._client.on('Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId));
Expand All @@ -49,7 +49,7 @@ class FrameManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Page.lifecycleEventPayload} event
*/
_onLifecycleEvent(event) {
const frame = this._frames.get(event.frameId);
Expand All @@ -60,7 +60,7 @@ class FrameManager extends EventEmitter {
}

/**
* @param {{frame: Object, childFrames: ?Array}} frameTree
* @param {!Protocol.Page.FrameTree} frameTree
*/
_handleFrameTree(frameTree) {
if (frameTree.frame.parentId)
Expand Down Expand Up @@ -171,7 +171,7 @@ class FrameManager extends EventEmitter {
}

/**
* @param {string} executionContextId
* @param {number} executionContextId
*/
_onExecutionContextDestroyed(executionContextId) {
const context = this._contextIdToContext.get(executionContextId);
Expand All @@ -188,7 +188,7 @@ class FrameManager extends EventEmitter {
}

/**
* @param {string} contextId
* @param {number} contextId
* @param {*} remoteObject
* @return {!JSHandle}
*/
Expand Down
13 changes: 7 additions & 6 deletions lib/NetworkManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.requestInterceptedPayload} event
*/
_onRequestIntercepted(event) {
if (event.authChallenge) {
/** @type {"Default"|"CancelAuth"|"ProvideCredentials"} */
let response = 'Default';
if (this._attemptedAuthentications.has(event.interceptionId)) {
response = 'CancelAuth';
Expand Down Expand Up @@ -170,7 +171,7 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.requestServedFromCachePayload} event
*/
_onRequestServedFromCache(event) {
const request = this._requestIdToRequest.get(event.requestId);
Expand Down Expand Up @@ -219,7 +220,7 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.requestWillBeSentPayload} event
*/
_onRequestWillBeSent(event) {
if (this._protocolRequestInterceptionEnabled) {
Expand Down Expand Up @@ -251,7 +252,7 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.responseReceivedPayload} event
*/
_onResponseReceived(event) {
const request = this._requestIdToRequest.get(event.requestId);
Expand All @@ -265,7 +266,7 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.loadingFinishedPayload} event
*/
_onLoadingFinished(event) {
const request = this._requestIdToRequest.get(event.requestId);
Expand All @@ -281,7 +282,7 @@ class NetworkManager extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Network.loadingFailedPayload} event
*/
_onLoadingFailed(event) {
const request = this._requestIdToRequest.get(event.requestId);
Expand Down
11 changes: 6 additions & 5 deletions lib/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Page extends EventEmitter {
/**
* @param {!Puppeteer.CDPSession} client
* @param {!Puppeteer.Target} target
* @param {{frame: Object, childFrames: ?Array}} frameTree
* @param {!Protocol.Page.FrameTree} frameTree
* @param {boolean} ignoreHTTPSErrors
* @param {!Puppeteer.TaskQueue} screenshotTaskQueue
*/
Expand Down Expand Up @@ -182,7 +182,7 @@ class Page extends EventEmitter {
}

/**
* @param {!Object} event
* @param {!Protocol.Security.certificateErrorPayload} event
*/
_onCertificateError(event) {
if (!this._ignoreHTTPSErrors)
Expand Down Expand Up @@ -404,7 +404,7 @@ class Page extends EventEmitter {
}

/**
* @param {!Object} exceptionDetails
* @param {!Protocol.Runtime.ExceptionDetails} exceptionDetails
*/
_handleException(exceptionDetails) {
const message = helper.getExceptionMessage(exceptionDetails);
Expand Down Expand Up @@ -708,7 +708,7 @@ class Page extends EventEmitter {
}

/**
* @param {string} format
* @param {"png"|"jpeg"} format
* @param {!Object=} options
* @return {!Promise<!Buffer>}
*/
Expand All @@ -728,6 +728,7 @@ class Page extends EventEmitter {
const mobile = this._viewport.isMobile || false;
const deviceScaleFactor = this._viewport.deviceScaleFactor || 1;
const landscape = this._viewport.isLandscape || false;
/** @type {!Protocol.Emulation.ScreenOrientation} */
const screenOrientation = landscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' };
await this._client.send('Emulation.setDeviceMetricsOverride', { mobile, width, height, deviceScaleFactor, screenOrientation });
}
Expand Down Expand Up @@ -1024,7 +1025,7 @@ Page.Events = {
/**
* @typedef {Object} Network.CookieParam
* @property {string} name
* @property {string=} value
* @property {string} value
* @property {string=} url
* @property {string=} domain
* @property {string=} path
Expand Down
5 changes: 4 additions & 1 deletion lib/externs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import * as child_process from 'child_process';
declare global {
module Puppeteer {
export class Connection extends RealConnection {}
export class CDPSession extends RealCDPSession {}
export class CDPSession extends RealCDPSession {
on<T extends keyof Protocol.Events>(event: T, listener: (arg: Protocol.Events[T]) => void): this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like black magic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is!

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 {}
Expand Down
72 changes: 59 additions & 13 deletions utils/protocol-types-generator/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-check
const puppeteer = require('../..');
puppeteer.launch({
pipe: false,
Expand All @@ -11,28 +12,59 @@ puppeteer.launch({
await browser.close();
const output = `// This is generated from /utils/protocol-types-generator/index.js
declare global {
module Protocol {
${json.domains.map(domain => `${domain.description ? `
module Protocol {${json.domains.map(domain => `${domain.description ? `
/**
* ${domain.description}
*/` : ''}
export module ${domain.domain} {
${(domain.types || []).map(type => `${type.description ? `
export module ${domain.domain} {${(domain.types || []).map(type => `${type.description ? `
/**
* ${type.description}
*/` : ''}${type.properties ? `
export interface ${type.id} {
${(type.properties || []).map(property => `${property.description ? `
export interface ${type.id} {${(type.properties || []).map(property => `${property.description ? `
/**
* ${property.description}
*/` : ''}
${property.name}${property.optional ? '?' : ''}: ${typeOfProperty(property)};
`).join(``)}
${property.name}${property.optional ? '?' : ''}: ${typeOfProperty(property)};`).join(``)}
}` : `
export type ${type.id} = ${typeOfProperty(type)};`}
`).join('')}
export type ${type.id} = ${typeOfProperty(type)};`}`).join('')}
${(domain.events || []).map(event => `${event.description ? `
/**
* ${event.description}
*/` : ''}${event.parameters ? `
export type ${event.name}Payload = {${event.parameters.map(parameter => `${parameter.description ? `
/**
* ${parameter.description}
*/` : ''}
${parameter.name}${parameter.optional ? '?' : ''}: ${typeOfProperty(parameter)};`).join(``)}
}` : `
export type ${event.name}Payload = void;`}`).join('')}
${(domain.commands || []).map(command => `${command.description ? `
/**
* ${command.description}
*/` : ''}
export type ${command.name}Parameters = {${(command.parameters || []).map(parameter => `${parameter.description ? `
/**
* ${parameter.description}
*/` : ''}
${parameter.name}${parameter.optional ? '?' : ''}: ${typeOfProperty(parameter)};`).join(``)}
}
export type ${command.name}ReturnValue = {${(command.returns || []).map(retVal => `${retVal.description ? `
/**
* ${retVal.description}
*/` : ''}
${retVal.name}${retVal.optional ? '?' : ''}: ${typeOfProperty(retVal)};`).join(``)}
}`).join('')}
}
`).join('')}
export interface Events {${json.domains.map(domain => (domain.events || []).map(event => `
"${domain.domain}.${event.name}": ${domain.domain}.${event.name}Payload;`).join('')).join('')}
}
export interface CommandParameters {${json.domains.map(domain => (domain.commands || []).map(command => `
"${domain.domain}.${command.name}": ${domain.domain}.${command.name}Parameters;`).join('')).join('')}
}
export interface CommandReturnValues {${json.domains.map(domain => (domain.commands || []).map(command => `
"${domain.domain}.${command.name}": ${domain.domain}.${command.name}ReturnValue;`).join('')).join('')}
}
}
}
// empty export to keep file a module
Expand All @@ -41,12 +73,26 @@ export {}
require('fs').writeFileSync(require('path').join(__dirname, '..', '..', 'lib', 'protocol.d.ts'), output);
});

function typeOfProperty(property) {
if (property.$ref) return property.$ref;

/**
* @typedef {Object} Property
* @property {string=} $ref
* @property {!Array=} enum
* @property {string=} type
* @property {!Property=} items
* @property {string=} description
*/

/**
* @param {!Property} property
* @param {string=} domain
*/
function typeOfProperty(property, domain) {
if (property.$ref) return property.$ref.includes('.') || !domain ? property.$ref : domain + '.' + property.$ref;
if (property.enum) return property.enum.map(value => JSON.stringify(value)).join('|');
switch (property.type) {
case 'array':
return typeOfProperty(property.items) + '[]';
return typeOfProperty(property.items, domain) + '[]';
case 'integer':
return 'number';
}
Expand Down