fix(types): fix parameters where they disagree with the api (#3525)

This commit is contained in:
Joel Einbinder 2018-11-12 12:59:21 -08:00 committed by Andrey Lushnikov
parent 27ea226bbc
commit 568734386d
10 changed files with 286 additions and 177 deletions

View File

@ -451,6 +451,7 @@ puppeteer.launch().then(async browser => {
- `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false`
- `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`.
- `slowMo` <[number]> Slows down Puppeteer operations by the specified amount of milliseconds. Useful so that you can see what is going on. - `slowMo` <[number]> Slows down Puppeteer operations by the specified amount of milliseconds. Useful so that you can see what is going on.
- `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Puppeteer to use.
- returns: <[Promise]<[Browser]>> - returns: <[Promise]<[Browser]>>
This methods attaches Puppeteer to an existing Chromium instance. This methods attaches Puppeteer to an existing Chromium instance.
@ -489,7 +490,7 @@ The default flags that Chromium will be launched with.
- `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false`
- `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`.
- `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/). - `args` <[Array]<[string]>> Additional arguments to pass to the browser instance. The list of Chromium flags can be found [here](http://peter.sh/experiments/chromium-command-line-switches/).
- `ignoreDefaultArgs` <([boolean]|<[Array]<[string]>>)> If `true`, then do not use [`puppeteer.defaultArgs()`](#puppeteerdefaultargs-options). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`. - `ignoreDefaultArgs` <[boolean]|[Array]<[string]>> If `true`, then do not use [`puppeteer.defaultArgs()`](#puppeteerdefaultargs-options). If an array is given, then filter out the given default arguments. Dangerous option; use with care. Defaults to `false`.
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`. - `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
- `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`. - `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`.
- `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`. - `handleSIGHUP` <[boolean]> Close the browser process on SIGHUP. Defaults to `true`.
@ -1145,10 +1146,11 @@ Gets the full HTML contents of the page, including the doctype.
- `domain` <[string]> - `domain` <[string]>
- `path` <[string]> - `path` <[string]>
- `expires` <[number]> Unix time in seconds. - `expires` <[number]> Unix time in seconds.
- `size` <[number]>
- `httpOnly` <[boolean]> - `httpOnly` <[boolean]>
- `secure` <[boolean]> - `secure` <[boolean]>
- `session` <[boolean]> - `session` <[boolean]>
- `sameSite` <[string]> `"Strict"` or `"Lax"`. - `sameSite` <"Strict"|"Lax">
If no URLs are specified, this method returns cookies for the current page URL. If no URLs are specified, this method returns cookies for the current page URL.
If URLs are specified, only cookies for those URLs are returned. If URLs are specified, only cookies for those URLs are returned.
@ -1163,7 +1165,6 @@ If URLs are specified, only cookies for those URLs are returned.
- `url` <[string]> - `url` <[string]>
- `domain` <[string]> - `domain` <[string]>
- `path` <[string]> - `path` <[string]>
- `secure` <[boolean]>
- returns: <[Promise]> - returns: <[Promise]>
#### page.emulate(options) #### page.emulate(options)
@ -1424,7 +1425,7 @@ Shortcut for [page.mainFrame().hover(selector)](#framehoverselector).
#### page.isClosed() #### page.isClosed()
- returns: boolean - returns: <[boolean]>
Indicates that the page has been closed. Indicates that the page has been closed.
@ -1475,13 +1476,13 @@ Page is guaranteed to have a main frame which persists during navigations.
- `landscape` <[boolean]> Paper orientation. Defaults to `false`. - `landscape` <[boolean]> Paper orientation. Defaults to `false`.
- `pageRanges` <[string]> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. - `pageRanges` <[string]> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
- `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'. - `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'.
- `width` <[string]> Paper width, accepts values labeled with units. - `width` <[string]|[number]> Paper width, accepts values labeled with units.
- `height` <[string]> Paper height, accepts values labeled with units. - `height` <[string]|[number]> Paper height, accepts values labeled with units.
- `margin` <[Object]> Paper margins, defaults to none. - `margin` <[Object]> Paper margins, defaults to none.
- `top` <[string]> Top margin, accepts values labeled with units. - `top` <[string]|[number]> Top margin, accepts values labeled with units.
- `right` <[string]> Right margin, accepts values labeled with units. - `right` <[string]|[number]> Right margin, accepts values labeled with units.
- `bottom` <[string]> Bottom margin, accepts values labeled with units. - `bottom` <[string]|[number]> Bottom margin, accepts values labeled with units.
- `left` <[string]> Left margin, accepts values labeled with units. - `left` <[string]|[number]> Left margin, accepts values labeled with units.
- `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size. - `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size.
- returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer. - returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer.
@ -1619,7 +1620,7 @@ Toggles ignoring cache for each request based on the enabled state. By default,
- `expires` <[number]> Unix time in seconds. - `expires` <[number]> Unix time in seconds.
- `httpOnly` <[boolean]> - `httpOnly` <[boolean]>
- `secure` <[boolean]> - `secure` <[boolean]>
- `sameSite` <[string]> `"Strict"` or `"Lax"`. - `sameSite` <"Strict"|"Lax">
- returns: <[Promise]> - returns: <[Promise]>
```js ```js
@ -2004,7 +2005,7 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
#### accessibility.snapshot([options]) #### accessibility.snapshot([options])
- `options` <[Object]> - `options` <[Object]>
- `interestingOnly` <[boolean]> Prune uninteresting nodes from the tree. Defaults to `true`. - `interestingOnly` <[boolean]> Prune uninteresting nodes from the tree. Defaults to `true`.
- returns: <[Promise]<[AXNode]>> Returns an AXNode object with the following properties: - returns: <[Promise]<[Object]>> Returns an [AXNode] object with the following properties:
- `role` <[string]> The [role](https://www.w3.org/TR/wai-aria/#usage_intro). - `role` <[string]> The [role](https://www.w3.org/TR/wai-aria/#usage_intro).
- `name` <[string]> A human readable name for the node. - `name` <[string]> A human readable name for the node.
- `value` <[string]|[number]> The current value of the node. - `value` <[string]|[number]> The current value of the node.
@ -2021,8 +2022,8 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
- `readonly` <[boolean]> Whether the node is read only. - `readonly` <[boolean]> Whether the node is read only.
- `required` <[boolean]> Whether the node is required. - `required` <[boolean]> Whether the node is required.
- `selected` <[boolean]> Whether the node is selected in its parent node. - `selected` <[boolean]> Whether the node is selected in its parent node.
- `checked` <[boolean]|[string]> Whether the checkbox is checked, or "mixed". - `checked` <[boolean]|"mixed"> Whether the checkbox is checked, or "mixed".
- `pressed` <[boolean]|[string]> Whether the toggle button is checked, or "mixed". - `pressed` <[boolean]|"mixed"> Whether the toggle button is checked, or "mixed".
- `level` <[number]> The level of a heading. - `level` <[number]> The level of a heading.
- `valuemin` <[number]> The minimum value in a node. - `valuemin` <[number]> The minimum value in a node.
- `valuemax` <[number]> The maximum value in a node. - `valuemax` <[number]> The maximum value in a node.
@ -2030,7 +2031,7 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
- `haspopup` <[string]> What kind of popup is currently being shown for a node. - `haspopup` <[string]> What kind of popup is currently being shown for a node.
- `invalid` <[string]> Whether and in what way this node's value is invalid. - `invalid` <[string]> Whether and in what way this node's value is invalid.
- `orientation` <[string]> Whether the node is oriented horizontally or vertically. - `orientation` <[string]> Whether the node is oriented horizontally or vertically.
- `children` <[Array]<[AXNode]>> Child nodes of this node, if any. - `children` <[Array]<[Object]>> Child [AXNode]s of this node, if any.
Captures the current state of the accessibility tree. The returned object represents the root accessible node of the page. Captures the current state of the accessibility tree. The returned object represents the root accessible node of the page.
@ -2841,7 +2842,7 @@ Returns either `null` or the object handle itself, if the object handle is an in
The `jsHandle.dispose` method stops referencing the element handle. The `jsHandle.dispose` method stops referencing the element handle.
#### jsHandle.executionContext() #### jsHandle.executionContext()
- returns: [ExecutionContext] - returns: <[ExecutionContext]>
Returns execution context the handle belongs to. Returns execution context the handle belongs to.
@ -2966,10 +2967,18 @@ This method returns the bounding box of the element (relative to the main frame)
#### elementHandle.boxModel() #### elementHandle.boxModel()
- returns: <[Promise]<?[Object]>> - returns: <[Promise]<?[Object]>>
- content <[Array]<[Object]>> Content box, represented as an array of {x, y} points. - content <[Array]<[Object]>> Content box.
- padding <[Array]<[Object]>> Padding box, represented as an array of {x, y} points. - x <[number]>
- border <[Array]<[Object]>> Border box, represented as an array of {x, y} points. - y <[number]>
- margin <[Array]<[Object]>> Margin box, represented as an array of {x, y} points. - padding <[Array]<[Object]>> Padding box.
- x <[number]>
- y <[number]>
- border <[Array]<[Object]>> Border box.
- x <[number]>
- y <[number]>
- margin <[Array]<[Object]>> Margin box.
- x <[number]>
- y <[number]>
- width <[number]> Element's width. - width <[number]> Element's width.
- height <[number]> Element's height. - height <[number]> Element's height.
@ -2994,7 +3003,7 @@ If the element is detached from DOM, the method throws an error.
The `elementHandle.dispose` method stops referencing the element handle. The `elementHandle.dispose` method stops referencing the element handle.
#### elementHandle.executionContext() #### elementHandle.executionContext()
- returns: [ExecutionContext] - returns: <[ExecutionContext]>
#### elementHandle.focus() #### elementHandle.focus()
- returns: <[Promise]> - returns: <[Promise]>
@ -3224,7 +3233,7 @@ ResourceType will be one of the following: `document`, `stylesheet`, `image`, `m
- `status` <[number]> Response status code, defaults to `200`. - `status` <[number]> Response status code, defaults to `200`.
- `headers` <[Object]> Optional response headers - `headers` <[Object]> Optional response headers
- `contentType` <[string]> If set, equals to setting `Content-Type` response header - `contentType` <[string]> If set, equals to setting `Content-Type` response header
- `body` <[Buffer]|[string]> Optional response body - `body` <[string]|[Buffer]> Optional response body
- returns: <[Promise]> - returns: <[Promise]>
Fulfills request with given response. To use this, request interception should Fulfills request with given response. To use this, request interception should
@ -3524,3 +3533,4 @@ TimeoutError is emitted whenever certain operations are terminated due to timeou
[Worker]: #class-worker "Worker" [Worker]: #class-worker "Worker"
[Accessibility]: #class-accessibility "Accessibility" [Accessibility]: #class-accessibility "Accessibility"
[AXNode]: #accessibilitysnapshotoptions "AXNode" [AXNode]: #accessibilitysnapshotoptions "AXNode"
[ConnectionTransport]: ../lib/WebSocketTransport.js "ConnectionTransport"

View File

@ -35,7 +35,7 @@ class Coverage {
} }
/** /**
* @param {!Object} options * @param {!{resetOnNavigation?: boolean, reportAnonymousScripts?: boolean}} options
*/ */
async startJSCoverage(options) { async startJSCoverage(options) {
return await this._jsCoverage.start(options); return await this._jsCoverage.start(options);
@ -49,7 +49,7 @@ class Coverage {
} }
/** /**
* @param {!Object} options * @param {{resetOnNavigation?: boolean}=} options
*/ */
async startCSSCoverage(options) { async startCSSCoverage(options) {
return await this._cssCoverage.start(options); return await this._cssCoverage.start(options);
@ -80,12 +80,16 @@ class JSCoverage {
} }
/** /**
* @param {!Object} options * @param {!{resetOnNavigation?: boolean, reportAnonymousScripts?: boolean}} options
*/ */
async start(options = {}) { async start(options = {}) {
assert(!this._enabled, 'JSCoverage is already enabled'); assert(!this._enabled, 'JSCoverage is already enabled');
this._resetOnNavigation = options.resetOnNavigation === undefined ? true : !!options.resetOnNavigation; const {
this._reportAnonymousScripts = !!options.reportAnonymousScripts; resetOnNavigation = true,
reportAnonymousScripts = false
} = options;
this._resetOnNavigation = resetOnNavigation;
this._reportAnonymousScripts = reportAnonymousScripts;
this._enabled = true; this._enabled = true;
this._scriptURLs.clear(); this._scriptURLs.clear();
this._scriptSources.clear(); this._scriptSources.clear();
@ -174,11 +178,12 @@ class CSSCoverage {
} }
/** /**
* @param {!Object} options * @param {{resetOnNavigation?: boolean}=} options
*/ */
async start(options = {}) { async start(options = {}) {
assert(!this._enabled, 'CSSCoverage is already enabled'); assert(!this._enabled, 'CSSCoverage is already enabled');
this._resetOnNavigation = options.resetOnNavigation === undefined ? true : !!options.resetOnNavigation; const {resetOnNavigation = true} = options;
this._resetOnNavigation = resetOnNavigation;
this._enabled = true; this._enabled = true;
this._stylesheetURLs.clear(); this._stylesheetURLs.clear();
this._stylesheetSources.clear(); this._stylesheetSources.clear();

View File

@ -376,7 +376,7 @@ class ElementHandle extends JSHandle {
/** /**
* @param {!Array<number>} quad * @param {!Array<number>} quad
* @return {!Array<object>} * @return {!Array<{x: number, y: number}>}
*/ */
_fromProtocolQuad(quad) { _fromProtocolQuad(quad) {
return [ return [
@ -394,9 +394,9 @@ class ElementHandle extends JSHandle {
} }
/** /**
* @param {!Object=} options * @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
async click(options = {}) { async click(options) {
await this._scrollIntoViewIfNeeded(); await this._scrollIntoViewIfNeeded();
const {x, y} = await this._clickablePoint(); const {x, y} = await this._clickablePoint();
await this._page.mouse.click(x, y, options); await this._page.mouse.click(x, y, options);
@ -432,7 +432,7 @@ class ElementHandle extends JSHandle {
/** /**
* @param {string} key * @param {string} key
* @param {!Object=} options * @param {!{delay?: number, text?: string}=} options
*/ */
async press(key, options) { async press(key, options) {
await this.focus(); await this.focus();
@ -458,7 +458,7 @@ class ElementHandle extends JSHandle {
} }
/** /**
* @return {!Promise<?object>} * @return {!Promise<?BoxModel>}
*/ */
async boxModel() { async boxModel() {
const result = await this._getBoxModel(); const result = await this._getBoxModel();
@ -646,6 +646,16 @@ function computeQuadArea(quad) {
return Math.abs(area); return Math.abs(area);
} }
/**
* @typedef {Object} BoxModel
* @property {!Array<!{x: number, y: number}>} content
* @property {!Array<!{x: number, y: number}>} padding
* @property {!Array<!{x: number, y: number}>} border
* @property {!Array<!{x: number, y: number}>} margin
* @property {number} width
* @property {number} height
*/
helper.tracePublicAPI(ElementHandle); helper.tracePublicAPI(ElementHandle);
helper.tracePublicAPI(JSHandle); helper.tracePublicAPI(JSHandle);
helper.tracePublicAPI(ExecutionContext); helper.tracePublicAPI(ExecutionContext);

View File

@ -65,17 +65,19 @@ class FrameManager extends EventEmitter {
/** /**
* @param {!Puppeteer.Frame} frame * @param {!Puppeteer.Frame} frame
* @param {string} url * @param {string} url
* @param {!Object=} options * @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async navigateFrame(frame, url, options = {}) { async navigateFrame(frame, url, options = {}) {
const referrer = typeof options.referer === 'string' ? options.referer : this._networkManager.extraHTTPHeaders()['referer']; const {
referer = this._networkManager.extraHTTPHeaders()['referer'],
timeout = this._defaultNavigationTimeout,
} = options;
const timeout = typeof options.timeout === 'number' ? options.timeout : this._defaultNavigationTimeout;
const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options); const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options);
let ensureNewDocumentNavigation = false; let ensureNewDocumentNavigation = false;
let error = await Promise.race([ let error = await Promise.race([
navigate(this._client, url, referrer, frame._id), navigate(this._client, url, referer, frame._id),
watcher.timeoutOrTerminationPromise(), watcher.timeoutOrTerminationPromise(),
]); ]);
if (!error) { if (!error) {
@ -109,11 +111,13 @@ class FrameManager extends EventEmitter {
/** /**
* @param {!Puppeteer.Frame} frame * @param {!Puppeteer.Frame} frame
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async waitForFrameNavigation(frame, options) { async waitForFrameNavigation(frame, options = {}) {
const timeout = typeof options.timeout === 'number' ? options.timeout : this._defaultNavigationTimeout; const {
timeout = this._defaultNavigationTimeout
} = options;
const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options); const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options);
const error = await Promise.race([ const error = await Promise.race([
watcher.timeoutOrTerminationPromise(), watcher.timeoutOrTerminationPromise(),
@ -397,18 +401,18 @@ class Frame {
/** /**
* @param {string} url * @param {string} url
* @param {!Object=} options * @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async goto(url, options = {}) { async goto(url, options) {
return await this._frameManager.navigateFrame(this, url, options); return await this._frameManager.navigateFrame(this, url, options);
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async waitForNavigation(options = {}) { async waitForNavigation(options) {
return await this._frameManager.waitForFrameNavigation(this, options); return await this._frameManager.waitForFrameNavigation(this, options);
} }
@ -566,30 +570,35 @@ class Frame {
} }
/** /**
* @param {Object} options * @param {!{url?: string, path?: string, content?: string, type?: string}} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
async addScriptTag(options) { async addScriptTag(options) {
if (typeof options.url === 'string') { const {
const url = options.url; url = null,
path = null,
content = null,
type = ''
} = options;
if (url !== null) {
try { try {
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addScriptUrl, url, options.type)).asElement(); return (await context.evaluateHandle(addScriptUrl, url, type)).asElement();
} catch (error) { } catch (error) {
throw new Error(`Loading script from ${url} failed`); throw new Error(`Loading script from ${url} failed`);
} }
} }
if (typeof options.path === 'string') { if (path !== null) {
let contents = await readFileAsync(options.path, 'utf8'); let contents = await readFileAsync(path, 'utf8');
contents += '//# sourceURL=' + options.path.replace(/\n/g, ''); contents += '//# sourceURL=' + path.replace(/\n/g, '');
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addScriptContent, contents, options.type)).asElement(); return (await context.evaluateHandle(addScriptContent, contents, type)).asElement();
} }
if (typeof options.content === 'string') { if (content !== null) {
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addScriptContent, options.content, options.type)).asElement(); return (await context.evaluateHandle(addScriptContent, content, type)).asElement();
} }
throw new Error('Provide an object with a `url`, `path` or `content` property'); throw new Error('Provide an object with a `url`, `path` or `content` property');
@ -632,12 +641,16 @@ class Frame {
} }
/** /**
* @param {Object} options * @param {!{url?: string, path?: string, content?: string}} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
async addStyleTag(options) { async addStyleTag(options) {
if (typeof options.url === 'string') { const {
const url = options.url; url = null,
path = null,
content = null
} = options;
if (url !== null) {
try { try {
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addStyleUrl, url)).asElement(); return (await context.evaluateHandle(addStyleUrl, url)).asElement();
@ -646,16 +659,16 @@ class Frame {
} }
} }
if (typeof options.path === 'string') { if (path !== null) {
let contents = await readFileAsync(options.path, 'utf8'); let contents = await readFileAsync(path, 'utf8');
contents += '/*# sourceURL=' + options.path.replace(/\n/g, '') + '*/'; contents += '/*# sourceURL=' + path.replace(/\n/g, '') + '*/';
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addStyleContent, contents)).asElement(); return (await context.evaluateHandle(addStyleContent, contents)).asElement();
} }
if (typeof options.content === 'string') { if (content !== null) {
const context = await this._contextPromise; const context = await this._contextPromise;
return (await context.evaluateHandle(addStyleContent, options.content)).asElement(); return (await context.evaluateHandle(addStyleContent, content)).asElement();
} }
throw new Error('Provide an object with a `url`, `path` or `content` property'); throw new Error('Provide an object with a `url`, `path` or `content` property');
@ -697,9 +710,9 @@ class Frame {
/** /**
* @param {string} selector * @param {string} selector
* @param {!Object=} options * @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
async click(selector, options = {}) { async click(selector, options) {
const handle = await this.$(selector); const handle = await this.$(selector);
assert(handle, 'No node found for selector: ' + selector); assert(handle, 'No node found for selector: ' + selector);
await handle.click(options); await handle.click(options);
@ -797,30 +810,32 @@ class Frame {
/** /**
* @param {string} selector * @param {string} selector
* @param {!Object=} options * @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
waitForSelector(selector, options = {}) { waitForSelector(selector, options) {
return this._waitForSelectorOrXPath(selector, false, options); return this._waitForSelectorOrXPath(selector, false, options);
} }
/** /**
* @param {string} xpath * @param {string} xpath
* @param {!Object=} options * @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
waitForXPath(xpath, options = {}) { waitForXPath(xpath, options) {
return this._waitForSelectorOrXPath(xpath, true, options); return this._waitForSelectorOrXPath(xpath, true, options);
} }
/** /**
* @param {Function|string} pageFunction * @param {Function|string} pageFunction
* @param {!Object=} options * @param {!{polling?: string|number, timeout?: number}=} options
* @return {!Promise<!Puppeteer.JSHandle>} * @return {!Promise<!Puppeteer.JSHandle>}
*/ */
waitForFunction(pageFunction, options = {}, ...args) { waitForFunction(pageFunction, options = {}, ...args) {
const timeout = helper.isNumber(options.timeout) ? options.timeout : 30000; const {
const polling = options.polling || 'raf'; polling = 'raf',
timeout = 30000
} = options;
return new WaitTask(this, pageFunction, 'function', polling, timeout, ...args).promise; return new WaitTask(this, pageFunction, 'function', polling, timeout, ...args).promise;
} }
@ -834,14 +849,16 @@ class Frame {
/** /**
* @param {string} selectorOrXPath * @param {string} selectorOrXPath
* @param {boolean} isXPath * @param {boolean} isXPath
* @param {!Object=} options * @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
_waitForSelectorOrXPath(selectorOrXPath, isXPath, options = {}) { _waitForSelectorOrXPath(selectorOrXPath, isXPath, options = {}) {
const waitForVisible = !!options.visible; const {
const waitForHidden = !!options.hidden; visible: waitForVisible = false,
hidden: waitForHidden = false,
timeout = 30000,
} = options;
const polling = waitForVisible || waitForHidden ? 'raf' : 'mutation'; const polling = waitForVisible || waitForHidden ? 'raf' : 'mutation';
const timeout = helper.isNumber(options.timeout) ? options.timeout : 30000;
const title = `${isXPath ? 'XPath' : 'selector'} "${selectorOrXPath}"${waitForHidden ? ' to be hidden' : ''}`; const title = `${isXPath ? 'XPath' : 'selector'} "${selectorOrXPath}"${waitForHidden ? ' to be hidden' : ''}`;
return new WaitTask(this, predicate, title, polling, timeout, selectorOrXPath, isXPath, waitForVisible, waitForHidden).promise; return new WaitTask(this, predicate, title, polling, timeout, selectorOrXPath, isXPath, waitForVisible, waitForHidden).promise;
@ -1117,17 +1134,19 @@ class NavigatorWatcher {
* @param {!NetworkManager} networkManager * @param {!NetworkManager} networkManager
* @param {!Puppeteer.Frame} frame * @param {!Puppeteer.Frame} frame
* @param {number} timeout * @param {number} timeout
* @param {!Object=} options * @param {!{waitUntil?: string|!Array<string>}} options
*/ */
constructor(client, frameManager, networkManager, frame, timeout, options = {}) { constructor(client, frameManager, networkManager, frame, timeout, options = {}) {
assert(options.networkIdleTimeout === undefined, 'ERROR: networkIdleTimeout option is no longer supported.'); assert(options['networkIdleTimeout'] === undefined, 'ERROR: networkIdleTimeout option is no longer supported.');
assert(options.networkIdleInflight === undefined, 'ERROR: networkIdleInflight option is no longer supported.'); assert(options['networkIdleInflight'] === undefined, 'ERROR: networkIdleInflight option is no longer supported.');
assert(options.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead'); assert(options.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead');
let waitUntil = ['load']; let {
if (Array.isArray(options.waitUntil)) waitUntil = ['load']
waitUntil = options.waitUntil.slice(); } = options;
else if (typeof options.waitUntil === 'string') if (Array.isArray(waitUntil))
waitUntil = [options.waitUntil]; waitUntil = waitUntil.slice();
else if (typeof waitUntil === 'string')
waitUntil = [waitUntil];
this._expectedLifecycle = waitUntil.map(value => { this._expectedLifecycle = waitUntil.map(value => {
const protocolEvent = puppeteerToProtocolLifecycle[value]; const protocolEvent = puppeteerToProtocolLifecycle[value];
assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value); assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value);

View File

@ -171,11 +171,12 @@ class Keyboard {
/** /**
* @param {string} key * @param {string} key
* @param {!Object=} options * @param {!{delay?: number, text?: string}=} options
*/ */
async press(key, options) { async press(key, options = {}) {
const {delay = null} = options;
await this.down(key, options); await this.down(key, options);
if (options && options.delay) if (delay !== null)
await new Promise(f => setTimeout(f, options.delay)); await new Promise(f => setTimeout(f, options.delay));
await this.up(key); await this.up(key);
} }
@ -198,13 +199,13 @@ class Mouse {
/** /**
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @param {Object=} options * @param {!{steps?: number}=} options
*/ */
async move(x, y, options = {}) { async move(x, y, options = {}) {
const {steps = 1} = options;
const fromX = this._x, fromY = this._y; const fromX = this._x, fromY = this._y;
this._x = x; this._x = x;
this._y = y; this._y = y;
const steps = options.steps || 1;
for (let i = 1; i <= steps; i++) { for (let i = 1; i <= steps; i++) {
await this._client.send('Input.dispatchMouseEvent', { await this._client.send('Input.dispatchMouseEvent', {
type: 'mouseMoved', type: 'mouseMoved',
@ -219,43 +220,46 @@ class Mouse {
/** /**
* @param {number} x * @param {number} x
* @param {number} y * @param {number} y
* @param {!Object=} options * @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
async click(x, y, options = {}) { async click(x, y, options = {}) {
const {delay = null} = options;
this.move(x, y); this.move(x, y);
this.down(options); this.down(options);
if (typeof options.delay === 'number') if (delay !== null)
await new Promise(f => setTimeout(f, options.delay)); await new Promise(f => setTimeout(f, delay));
await this.up(options); await this.up(options);
} }
/** /**
* @param {!Object=} options * @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
async down(options = {}) { async down(options = {}) {
this._button = (options.button || 'left'); const {button = 'left', clickCount = 1} = options;
this._button = button;
await this._client.send('Input.dispatchMouseEvent', { await this._client.send('Input.dispatchMouseEvent', {
type: 'mousePressed', type: 'mousePressed',
button: this._button, button,
x: this._x, x: this._x,
y: this._y, y: this._y,
modifiers: this._keyboard._modifiers, modifiers: this._keyboard._modifiers,
clickCount: (options.clickCount || 1) clickCount
}); });
} }
/** /**
* @param {!Object=} options * @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
async up(options = {}) { async up(options = {}) {
const {button = 'left', clickCount = 1} = options;
this._button = 'none'; this._button = 'none';
await this._client.send('Input.dispatchMouseEvent', { await this._client.send('Input.dispatchMouseEvent', {
type: 'mouseReleased', type: 'mouseReleased',
button: (options.button || 'left'), button,
x: this._x, x: this._x,
y: this._y, y: this._y,
modifiers: this._keyboard._modifiers, modifiers: this._keyboard._modifiers,
clickCount: (options.clickCount || 1) clickCount
}); });
} }
} }

View File

@ -71,7 +71,7 @@ class Launcher {
} }
/** /**
* @param {!(LaunchOptions & ChromeArgOptions & BrowserOptions)=} options * @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options
* @return {!Promise<!Browser>} * @return {!Promise<!Browser>}
*/ */
async launch(options = {}) { async launch(options = {}) {
@ -236,7 +236,7 @@ class Launcher {
} }
/** /**
* @param {!ChromeArgOptions=} options * @param {!Launcher.ChromeArgOptions=} options
* @return {!Array<string>} * @return {!Array<string>}
*/ */
defaultArgs(options = {}) { defaultArgs(options = {}) {
@ -274,7 +274,7 @@ class Launcher {
} }
/** /**
* @param {!(BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options * @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options
* @return {!Promise<!Browser>} * @return {!Promise<!Browser>}
*/ */
async connect(options) { async connect(options) {
@ -374,7 +374,7 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
} }
/** /**
* @typedef {Object} ChromeArgOptions * @typedef {Object} Launcher.ChromeArgOptions
* @property {boolean=} headless * @property {boolean=} headless
* @property {Array<string>=} args * @property {Array<string>=} args
* @property {string=} userDataDir * @property {string=} userDataDir
@ -382,9 +382,9 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
*/ */
/** /**
* @typedef {Object} LaunchOptions * @typedef {Object} Launcher.LaunchOptions
* @property {string=} executablePath * @property {string=} executablePath
* @property {boolean=} ignoreDefaultArgs * @property {boolean|Array<string>=} ignoreDefaultArgs
* @property {boolean=} handleSIGINT * @property {boolean=} handleSIGINT
* @property {boolean=} handleSIGTERM * @property {boolean=} handleSIGTERM
* @property {boolean=} handleSIGHUP * @property {boolean=} handleSIGHUP
@ -395,7 +395,7 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
*/ */
/** /**
* @typedef {Object} BrowserOptions * @typedef {Object} Launcher.BrowserOptions
* @property {boolean=} ignoreHTTPSErrors * @property {boolean=} ignoreHTTPSErrors
* @property {(?Puppeteer.Viewport)=} defaultViewport * @property {(?Puppeteer.Viewport)=} defaultViewport
* @property {number=} slowMo * @property {number=} slowMo

View File

@ -391,18 +391,24 @@ class Request {
} }
/** /**
* @param {!Object=} overrides * @param {!{url?: string, method?:string, postData?: string, headers?: !Object}} overrides
*/ */
async continue(overrides = {}) { async continue(overrides = {}) {
assert(this._allowInterception, 'Request Interception is not enabled!'); assert(this._allowInterception, 'Request Interception is not enabled!');
assert(!this._interceptionHandled, 'Request is already handled!'); assert(!this._interceptionHandled, 'Request is already handled!');
const {
url,
method,
postData,
headers
} = overrides;
this._interceptionHandled = true; this._interceptionHandled = true;
await this._client.send('Network.continueInterceptedRequest', { await this._client.send('Network.continueInterceptedRequest', {
interceptionId: this._interceptionId, interceptionId: this._interceptionId,
url: overrides.url, url,
method: overrides.method, method,
postData: overrides.postData, postData,
headers: overrides.headers, headers,
}).catch(error => { }).catch(error => {
// In certain cases, protocol will return error if the request was already canceled // In certain cases, protocol will return error if the request was already canceled
// or the page was closed. We should tolerate these errors. // or the page was closed. We should tolerate these errors.

View File

@ -350,7 +350,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {Array<Network.CookieParam>} cookies * @param {Array<Protocol.Network.deleteCookiesParameters>} cookies
*/ */
async deleteCookie(...cookies) { async deleteCookie(...cookies) {
const pageURL = this.url(); const pageURL = this.url();
@ -388,7 +388,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {Object} options * @param {!{url?: string, path?: string, content?: string, type?: string}} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
async addScriptTag(options) { async addScriptTag(options) {
@ -396,7 +396,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {Object} options * @param {!{url?: string, path?: string, content?: string}} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
async addStyleTag(options) { async addStyleTag(options) {
@ -457,7 +457,7 @@ class Page extends EventEmitter {
} }
/** /**
* @return {!Promise<!Object>} * @return {!Promise<!Metrics>}
*/ */
async metrics() { async metrics() {
const response = await this._client.send('Performance.getMetrics'); const response = await this._client.send('Performance.getMetrics');
@ -465,7 +465,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {*} event * @param {!Protocol.Performance.metricsPayload} event
*/ */
_emitMetrics(event) { _emitMetrics(event) {
this.emit(Page.Events.Metrics, { this.emit(Page.Events.Metrics, {
@ -476,7 +476,7 @@ class Page extends EventEmitter {
/** /**
* @param {?Array<!Protocol.Performance.Metric>} metrics * @param {?Array<!Protocol.Performance.Metric>} metrics
* @return {!Object} * @return {!Metrics}
*/ */
_buildMetricsObject(metrics) { _buildMetricsObject(metrics) {
const result = {}; const result = {};
@ -580,15 +580,15 @@ class Page extends EventEmitter {
/** /**
* @param {string} url * @param {string} url
* @param {!Object=} options * @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async goto(url, options = {}) { async goto(url, options) {
return await this._frameManager.mainFrame().goto(url, options); return await this._frameManager.mainFrame().goto(url, options);
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async reload(options) { async reload(options) {
@ -600,7 +600,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async waitForNavigation(options = {}) { async waitForNavigation(options = {}) {
@ -609,11 +609,13 @@ class Page extends EventEmitter {
/** /**
* @param {(string|Function)} urlOrPredicate * @param {(string|Function)} urlOrPredicate
* @param {!Object=} options * @param {!{timeout?: number}=} options
* @return {!Promise<!Puppeteer.Request>} * @return {!Promise<!Puppeteer.Request>}
*/ */
async waitForRequest(urlOrPredicate, options = {}) { async waitForRequest(urlOrPredicate, options = {}) {
const timeout = typeof options.timeout === 'number' ? options.timeout : 30000; const {
timeout = 30000
} = options;
return helper.waitForEvent(this._networkManager, NetworkManager.Events.Request, request => { return helper.waitForEvent(this._networkManager, NetworkManager.Events.Request, request => {
if (helper.isString(urlOrPredicate)) if (helper.isString(urlOrPredicate))
return (urlOrPredicate === request.url()); return (urlOrPredicate === request.url());
@ -625,11 +627,13 @@ class Page extends EventEmitter {
/** /**
* @param {(string|Function)} urlOrPredicate * @param {(string|Function)} urlOrPredicate
* @param {!Object=} options * @param {!{timeout?: number}=} options
* @return {!Promise<!Puppeteer.Response>} * @return {!Promise<!Puppeteer.Response>}
*/ */
async waitForResponse(urlOrPredicate, options = {}) { async waitForResponse(urlOrPredicate, options = {}) {
const timeout = typeof options.timeout === 'number' ? options.timeout : 30000; const {
timeout = 30000
} = options;
return helper.waitForEvent(this._networkManager, NetworkManager.Events.Response, response => { return helper.waitForEvent(this._networkManager, NetworkManager.Events.Response, response => {
if (helper.isString(urlOrPredicate)) if (helper.isString(urlOrPredicate))
return (urlOrPredicate === response.url()); return (urlOrPredicate === response.url());
@ -640,7 +644,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async goBack(options) { async goBack(options) {
@ -648,7 +652,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async goForward(options) { async goForward(options) {
@ -656,7 +660,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>} * @return {!Promise<?Puppeteer.Response>}
*/ */
async _go(delta, options) { async _go(delta, options) {
@ -676,7 +680,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object} options * @param {!{viewport: !Puppeteer.Viewport, userAgent: string}} options
*/ */
async emulate(options) { async emulate(options) {
await Promise.all([ await Promise.all([
@ -753,7 +757,7 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!ScreenshotOptions=} options
* @return {!Promise<!Buffer|!String>} * @return {!Promise<!Buffer|!String>}
*/ */
async screenshot(options = {}) { async screenshot(options = {}) {
@ -793,14 +797,12 @@ class Page extends EventEmitter {
/** /**
* @param {"png"|"jpeg"} format * @param {"png"|"jpeg"} format
* @param {!Object=} options * @param {!ScreenshotOptions=} options
* @return {!Promise<!Buffer|!String>} * @return {!Promise<!Buffer|!String>}
*/ */
async _screenshotTask(format, options) { async _screenshotTask(format, options) {
await this._client.send('Target.activateTarget', {targetId: this._target._targetId}); await this._client.send('Target.activateTarget', {targetId: this._target._targetId});
let clip = options.clip ? Object.assign({}, options['clip']) : undefined; let clip = options.clip ? Object.assign({}, options['clip'], {scale: 1}) : undefined;
if (clip)
clip.scale = 1;
if (options.fullPage) { if (options.fullPage) {
const metrics = await this._client.send('Page.getLayoutMetrics'); const metrics = await this._client.send('Page.getLayoutMetrics');
@ -835,17 +837,22 @@ class Page extends EventEmitter {
} }
/** /**
* @param {!Object=} options * @param {!PDFOptions=} options
* @return {!Promise<!Buffer>} * @return {!Promise<!Buffer>}
*/ */
async pdf(options = {}) { async pdf(options = {}) {
const scale = options.scale || 1; const {
const displayHeaderFooter = !!options.displayHeaderFooter; scale = 1,
const headerTemplate = options.headerTemplate || ''; displayHeaderFooter = false,
const footerTemplate = options.footerTemplate || ''; headerTemplate = '',
const printBackground = !!options.printBackground; footerTemplate = '',
const landscape = !!options.landscape; printBackground = false,
const pageRanges = options.pageRanges || ''; landscape = false,
pageRanges = '',
preferCSSPageSize = false,
margin = {},
path = null
} = options;
let paperWidth = 8.5; let paperWidth = 8.5;
let paperHeight = 11; let paperHeight = 11;
@ -859,32 +866,30 @@ class Page extends EventEmitter {
paperHeight = convertPrintParameterToInches(options.height) || paperHeight; paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
} }
const marginOptions = options.margin || {}; const marginTop = convertPrintParameterToInches(margin.top) || 0;
const marginTop = convertPrintParameterToInches(marginOptions.top) || 0; const marginLeft = convertPrintParameterToInches(margin.left) || 0;
const marginLeft = convertPrintParameterToInches(marginOptions.left) || 0; const marginBottom = convertPrintParameterToInches(margin.bottom) || 0;
const marginBottom = convertPrintParameterToInches(marginOptions.bottom) || 0; const marginRight = convertPrintParameterToInches(margin.right) || 0;
const marginRight = convertPrintParameterToInches(marginOptions.right) || 0;
const preferCSSPageSize = options.preferCSSPageSize || false;
const result = await this._client.send('Page.printToPDF', { const result = await this._client.send('Page.printToPDF', {
landscape: landscape, landscape,
displayHeaderFooter: displayHeaderFooter, displayHeaderFooter,
headerTemplate: headerTemplate, headerTemplate,
footerTemplate: footerTemplate, footerTemplate,
printBackground: printBackground, printBackground,
scale: scale, scale,
paperWidth: paperWidth, paperWidth,
paperHeight: paperHeight, paperHeight,
marginTop: marginTop, marginTop,
marginBottom: marginBottom, marginBottom,
marginLeft: marginLeft, marginLeft,
marginRight: marginRight, marginRight,
pageRanges: pageRanges, pageRanges,
preferCSSPageSize: preferCSSPageSize preferCSSPageSize
}); });
const buffer = Buffer.from(result.data, 'base64'); const buffer = Buffer.from(result.data, 'base64');
if (options.path) if (path !== null)
await writeFileAsync(options.path, buffer); await writeFileAsync(path, buffer);
return buffer; return buffer;
} }
@ -925,7 +930,7 @@ class Page extends EventEmitter {
/** /**
* @param {string} selector * @param {string} selector
* @param {!Object=} options * @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/ */
click(selector, options = {}) { click(selector, options = {}) {
return this.mainFrame().click(selector, options); return this.mainFrame().click(selector, options);
@ -982,7 +987,7 @@ class Page extends EventEmitter {
/** /**
* @param {string} selector * @param {string} selector
* @param {!Object=} options * @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
waitForSelector(selector, options = {}) { waitForSelector(selector, options = {}) {
@ -991,7 +996,7 @@ class Page extends EventEmitter {
/** /**
* @param {string} xpath * @param {string} xpath
* @param {!Object=} options * @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>} * @return {!Promise<!Puppeteer.ElementHandle>}
*/ */
waitForXPath(xpath, options = {}) { waitForXPath(xpath, options = {}) {
@ -1000,7 +1005,7 @@ class Page extends EventEmitter {
/** /**
* @param {function()} pageFunction * @param {function()} pageFunction
* @param {!Object=} options * @param {!{polling?: string|number, timeout?: number}=} options
* @param {!Array<*>} args * @param {!Array<*>} args
* @return {!Promise<!Puppeteer.JSHandle>} * @return {!Promise<!Puppeteer.JSHandle>}
*/ */
@ -1009,6 +1014,51 @@ class Page extends EventEmitter {
} }
} }
/**
* @typedef {Object} PDFOptions
* @property {number=} scale
* @property {boolean=} displayHeaderFooter
* @property {string=} headerTemplate
* @property {string=} footerTemplate
* @property {boolean=} printBackground
* @property {boolean=} landscape
* @property {string=} pageRanges
* @property {string=} format
* @property {string|number=} width
* @property {string|number=} height
* @property {boolean=} preferCSSPageSize
* @property {!{top?: string|number, bottom?: string|number, left?: string|number, right?: string|number}=} margin
* @property {string=} path
*/
/**
* @typedef {Object} Metrics
* @property {number=} Timestamp
* @property {number=} Documents
* @property {number=} Frames
* @property {number=} JSEventListeners
* @property {number=} Nodes
* @property {number=} LayoutCount
* @property {number=} RecalcStyleCount
* @property {number=} LayoutDuration
* @property {number=} RecalcStyleDuration
* @property {number=} ScriptDuration
* @property {number=} TaskDuration
* @property {number=} JSHeapUsedSize
* @property {number=} JSHeapTotalSize
*/
/**
* @typedef {Object} ScreenshotOptions
* @property {string=} type
* @property {string=} path
* @property {boolean=} fullPage
* @property {{x: number, y: number, width: number, height: number}=} clip
* @property {number=} quality
* @property {boolean=} omitBackground
* @property {string=} encoding
*/
/** @type {!Set<string>} */ /** @type {!Set<string>} */
const supportedMetrics = new Set([ const supportedMetrics = new Set([
'Timestamp', 'Timestamp',

View File

@ -29,7 +29,7 @@ module.exports = class {
} }
/** /**
* @param {!Object=} options * @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options
* @return {!Promise<!Puppeteer.Browser>} * @return {!Promise<!Puppeteer.Browser>}
*/ */
launch(options) { launch(options) {
@ -37,7 +37,7 @@ module.exports = class {
} }
/** /**
* @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean, transport?: !Puppeteer.ConnectionTransport}} options * @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options
* @return {!Promise<!Puppeteer.Browser>} * @return {!Promise<!Puppeteer.Browser>}
*/ */
connect(options) { connect(options) {
@ -52,6 +52,7 @@ module.exports = class {
} }
/** /**
* @param {!Launcher.ChromeArgOptions=} options
* @return {!Array<string>} * @return {!Array<string>}
*/ */
defaultArgs(options) { defaultArgs(options) {
@ -59,7 +60,7 @@ module.exports = class {
} }
/** /**
* @param {!Object=} options * @param {!BrowserFetcher.Options=} options
* @return {!BrowserFetcher} * @return {!BrowserFetcher}
*/ */
createBrowserFetcher(options) { createBrowserFetcher(options) {

View File

@ -31,7 +31,7 @@ class Tracing {
} }
/** /**
* @param {!Object} options * @param {!{path: string, screenshots?: boolean, categories?: !Array<string>}} options
*/ */
async start(options) { async start(options) {
assert(!this._recording, 'Cannot start recording trace while already recording trace.'); assert(!this._recording, 'Cannot start recording trace while already recording trace.');
@ -42,16 +42,20 @@ class Tracing {
'blink.console', 'blink.user_timing', 'latencyInfo', 'disabled-by-default-devtools.timeline.stack', 'blink.console', 'blink.user_timing', 'latencyInfo', 'disabled-by-default-devtools.timeline.stack',
'disabled-by-default-v8.cpu_profiler', 'disabled-by-default-v8.cpu_profiler.hires' 'disabled-by-default-v8.cpu_profiler', 'disabled-by-default-v8.cpu_profiler.hires'
]; ];
const categoriesArray = options.categories || defaultCategories; const {
path = null,
screenshots = false,
categories = defaultCategories,
} = options;
if (options.screenshots) if (screenshots)
categoriesArray.push('disabled-by-default-devtools.screenshot'); categories.push('disabled-by-default-devtools.screenshot');
this._path = options.path; this._path = path;
this._recording = true; this._recording = true;
await this._client.send('Tracing.start', { await this._client.send('Tracing.start', {
transferMode: 'ReturnAsStream', transferMode: 'ReturnAsStream',
categories: categoriesArray.join(',') categories: categories.join(',')
}); });
} }