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`
- `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.
- `transport` <[ConnectionTransport]> **Experimental** Specify a custom transport object for Puppeteer to use.
- returns: <[Promise]<[Browser]>>
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`
- `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/).
- `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`.
- `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. 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]>
- `path` <[string]>
- `expires` <[number]> Unix time in seconds.
- `size` <[number]>
- `httpOnly` <[boolean]>
- `secure` <[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 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]>
- `domain` <[string]>
- `path` <[string]>
- `secure` <[boolean]>
- returns: <[Promise]>
#### page.emulate(options)
@ -1424,7 +1425,7 @@ Shortcut for [page.mainFrame().hover(selector)](#framehoverselector).
#### page.isClosed()
- returns: boolean
- returns: <[boolean]>
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`.
- `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'.
- `width` <[string]> Paper width, accepts values labeled with units.
- `height` <[string]> Paper height, accepts values labeled with units.
- `width` <[string]|[number]> Paper width, accepts values labeled with units.
- `height` <[string]|[number]> Paper height, accepts values labeled with units.
- `margin` <[Object]> Paper margins, defaults to none.
- `top` <[string]> Top margin, accepts values labeled with units.
- `right` <[string]> Right margin, accepts values labeled with units.
- `bottom` <[string]> Bottom margin, accepts values labeled with units.
- `left` <[string]> Left margin, accepts values labeled with units.
- `top` <[string]|[number]> Top margin, accepts values labeled with units.
- `right` <[string]|[number]> Right margin, accepts values labeled with units.
- `bottom` <[string]|[number]> Bottom 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.
- 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.
- `httpOnly` <[boolean]>
- `secure` <[boolean]>
- `sameSite` <[string]> `"Strict"` or `"Lax"`.
- `sameSite` <"Strict"|"Lax">
- returns: <[Promise]>
```js
@ -2004,7 +2005,7 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
#### accessibility.snapshot([options])
- `options` <[Object]>
- `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).
- `name` <[string]> A human readable name for 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.
- `required` <[boolean]> Whether the node is required.
- `selected` <[boolean]> Whether the node is selected in its parent node.
- `checked` <[boolean]|[string]> Whether the checkbox is checked, or "mixed".
- `pressed` <[boolean]|[string]> Whether the toggle button is checked, or "mixed".
- `checked` <[boolean]|"mixed"> Whether the checkbox is checked, or "mixed".
- `pressed` <[boolean]|"mixed"> Whether the toggle button is checked, or "mixed".
- `level` <[number]> The level of a heading.
- `valuemin` <[number]> The minimum 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.
- `invalid` <[string]> Whether and in what way this node's value is invalid.
- `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.
@ -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.
#### jsHandle.executionContext()
- returns: [ExecutionContext]
- returns: <[ExecutionContext]>
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()
- returns: <[Promise]<?[Object]>>
- content <[Array]<[Object]>> Content box, represented as an array of {x, y} points.
- padding <[Array]<[Object]>> Padding box, represented as an array of {x, y} points.
- border <[Array]<[Object]>> Border box, represented as an array of {x, y} points.
- margin <[Array]<[Object]>> Margin box, represented as an array of {x, y} points.
- content <[Array]<[Object]>> Content box.
- x <[number]>
- y <[number]>
- 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.
- 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.
#### elementHandle.executionContext()
- returns: [ExecutionContext]
- returns: <[ExecutionContext]>
#### elementHandle.focus()
- 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`.
- `headers` <[Object]> Optional response headers
- `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]>
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"
[Accessibility]: #class-accessibility "Accessibility"
[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) {
return await this._jsCoverage.start(options);
@ -49,7 +49,7 @@ class Coverage {
}
/**
* @param {!Object} options
* @param {{resetOnNavigation?: boolean}=} options
*/
async startCSSCoverage(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 = {}) {
assert(!this._enabled, 'JSCoverage is already enabled');
this._resetOnNavigation = options.resetOnNavigation === undefined ? true : !!options.resetOnNavigation;
this._reportAnonymousScripts = !!options.reportAnonymousScripts;
const {
resetOnNavigation = true,
reportAnonymousScripts = false
} = options;
this._resetOnNavigation = resetOnNavigation;
this._reportAnonymousScripts = reportAnonymousScripts;
this._enabled = true;
this._scriptURLs.clear();
this._scriptSources.clear();
@ -174,11 +178,12 @@ class CSSCoverage {
}
/**
* @param {!Object} options
* @param {{resetOnNavigation?: boolean}=} options
*/
async start(options = {}) {
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._stylesheetURLs.clear();
this._stylesheetSources.clear();

View File

@ -376,7 +376,7 @@ class ElementHandle extends JSHandle {
/**
* @param {!Array<number>} quad
* @return {!Array<object>}
* @return {!Array<{x: number, y: number}>}
*/
_fromProtocolQuad(quad) {
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();
const {x, y} = await this._clickablePoint();
await this._page.mouse.click(x, y, options);
@ -432,7 +432,7 @@ class ElementHandle extends JSHandle {
/**
* @param {string} key
* @param {!Object=} options
* @param {!{delay?: number, text?: string}=} options
*/
async press(key, options) {
await this.focus();
@ -458,7 +458,7 @@ class ElementHandle extends JSHandle {
}
/**
* @return {!Promise<?object>}
* @return {!Promise<?BoxModel>}
*/
async boxModel() {
const result = await this._getBoxModel();
@ -646,6 +646,16 @@ function computeQuadArea(quad) {
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(JSHandle);
helper.tracePublicAPI(ExecutionContext);

View File

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

View File

@ -171,11 +171,12 @@ class Keyboard {
/**
* @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);
if (options && options.delay)
if (delay !== null)
await new Promise(f => setTimeout(f, options.delay));
await this.up(key);
}
@ -198,13 +199,13 @@ class Mouse {
/**
* @param {number} x
* @param {number} y
* @param {Object=} options
* @param {!{steps?: number}=} options
*/
async move(x, y, options = {}) {
const {steps = 1} = options;
const fromX = this._x, fromY = this._y;
this._x = x;
this._y = y;
const steps = options.steps || 1;
for (let i = 1; i <= steps; i++) {
await this._client.send('Input.dispatchMouseEvent', {
type: 'mouseMoved',
@ -219,43 +220,46 @@ class Mouse {
/**
* @param {number} x
* @param {number} y
* @param {!Object=} options
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/
async click(x, y, options = {}) {
const {delay = null} = options;
this.move(x, y);
this.down(options);
if (typeof options.delay === 'number')
await new Promise(f => setTimeout(f, options.delay));
if (delay !== null)
await new Promise(f => setTimeout(f, delay));
await this.up(options);
}
/**
* @param {!Object=} options
* @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
*/
async down(options = {}) {
this._button = (options.button || 'left');
const {button = 'left', clickCount = 1} = options;
this._button = button;
await this._client.send('Input.dispatchMouseEvent', {
type: 'mousePressed',
button: this._button,
button,
x: this._x,
y: this._y,
modifiers: this._keyboard._modifiers,
clickCount: (options.clickCount || 1)
clickCount
});
}
/**
* @param {!Object=} options
* @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options
*/
async up(options = {}) {
const {button = 'left', clickCount = 1} = options;
this._button = 'none';
await this._client.send('Input.dispatchMouseEvent', {
type: 'mouseReleased',
button: (options.button || 'left'),
button,
x: this._x,
y: this._y,
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>}
*/
async launch(options = {}) {
@ -236,7 +236,7 @@ class Launcher {
}
/**
* @param {!ChromeArgOptions=} options
* @param {!Launcher.ChromeArgOptions=} options
* @return {!Array<string>}
*/
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>}
*/
async connect(options) {
@ -374,7 +374,7 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
}
/**
* @typedef {Object} ChromeArgOptions
* @typedef {Object} Launcher.ChromeArgOptions
* @property {boolean=} headless
* @property {Array<string>=} args
* @property {string=} userDataDir
@ -382,9 +382,9 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
*/
/**
* @typedef {Object} LaunchOptions
* @typedef {Object} Launcher.LaunchOptions
* @property {string=} executablePath
* @property {boolean=} ignoreDefaultArgs
* @property {boolean|Array<string>=} ignoreDefaultArgs
* @property {boolean=} handleSIGINT
* @property {boolean=} handleSIGTERM
* @property {boolean=} handleSIGHUP
@ -395,7 +395,7 @@ function waitForWSEndpoint(chromeProcess, timeout, preferredRevision) {
*/
/**
* @typedef {Object} BrowserOptions
* @typedef {Object} Launcher.BrowserOptions
* @property {boolean=} ignoreHTTPSErrors
* @property {(?Puppeteer.Viewport)=} defaultViewport
* @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 = {}) {
assert(this._allowInterception, 'Request Interception is not enabled!');
assert(!this._interceptionHandled, 'Request is already handled!');
const {
url,
method,
postData,
headers
} = overrides;
this._interceptionHandled = true;
await this._client.send('Network.continueInterceptedRequest', {
interceptionId: this._interceptionId,
url: overrides.url,
method: overrides.method,
postData: overrides.postData,
headers: overrides.headers,
url,
method,
postData,
headers,
}).catch(error => {
// In certain cases, protocol will return error if the request was already canceled
// 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) {
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>}
*/
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>}
*/
async addStyleTag(options) {
@ -457,7 +457,7 @@ class Page extends EventEmitter {
}
/**
* @return {!Promise<!Object>}
* @return {!Promise<!Metrics>}
*/
async metrics() {
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) {
this.emit(Page.Events.Metrics, {
@ -476,7 +476,7 @@ class Page extends EventEmitter {
/**
* @param {?Array<!Protocol.Performance.Metric>} metrics
* @return {!Object}
* @return {!Metrics}
*/
_buildMetricsObject(metrics) {
const result = {};
@ -580,15 +580,15 @@ class Page extends EventEmitter {
/**
* @param {string} url
* @param {!Object=} options
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options
* @return {!Promise<?Puppeteer.Response>}
*/
async goto(url, options = {}) {
async 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>}
*/
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>}
*/
async waitForNavigation(options = {}) {
@ -609,11 +609,13 @@ class Page extends EventEmitter {
/**
* @param {(string|Function)} urlOrPredicate
* @param {!Object=} options
* @param {!{timeout?: number}=} options
* @return {!Promise<!Puppeteer.Request>}
*/
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 => {
if (helper.isString(urlOrPredicate))
return (urlOrPredicate === request.url());
@ -625,11 +627,13 @@ class Page extends EventEmitter {
/**
* @param {(string|Function)} urlOrPredicate
* @param {!Object=} options
* @param {!{timeout?: number}=} options
* @return {!Promise<!Puppeteer.Response>}
*/
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 => {
if (helper.isString(urlOrPredicate))
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>}
*/
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>}
*/
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>}
*/
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) {
await Promise.all([
@ -753,7 +757,7 @@ class Page extends EventEmitter {
}
/**
* @param {!Object=} options
* @param {!ScreenshotOptions=} options
* @return {!Promise<!Buffer|!String>}
*/
async screenshot(options = {}) {
@ -793,14 +797,12 @@ class Page extends EventEmitter {
/**
* @param {"png"|"jpeg"} format
* @param {!Object=} options
* @param {!ScreenshotOptions=} options
* @return {!Promise<!Buffer|!String>}
*/
async _screenshotTask(format, options) {
await this._client.send('Target.activateTarget', {targetId: this._target._targetId});
let clip = options.clip ? Object.assign({}, options['clip']) : undefined;
if (clip)
clip.scale = 1;
let clip = options.clip ? Object.assign({}, options['clip'], {scale: 1}) : undefined;
if (options.fullPage) {
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>}
*/
async pdf(options = {}) {
const scale = options.scale || 1;
const displayHeaderFooter = !!options.displayHeaderFooter;
const headerTemplate = options.headerTemplate || '';
const footerTemplate = options.footerTemplate || '';
const printBackground = !!options.printBackground;
const landscape = !!options.landscape;
const pageRanges = options.pageRanges || '';
const {
scale = 1,
displayHeaderFooter = false,
headerTemplate = '',
footerTemplate = '',
printBackground = false,
landscape = false,
pageRanges = '',
preferCSSPageSize = false,
margin = {},
path = null
} = options;
let paperWidth = 8.5;
let paperHeight = 11;
@ -859,32 +866,30 @@ class Page extends EventEmitter {
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
}
const marginOptions = options.margin || {};
const marginTop = convertPrintParameterToInches(marginOptions.top) || 0;
const marginLeft = convertPrintParameterToInches(marginOptions.left) || 0;
const marginBottom = convertPrintParameterToInches(marginOptions.bottom) || 0;
const marginRight = convertPrintParameterToInches(marginOptions.right) || 0;
const preferCSSPageSize = options.preferCSSPageSize || false;
const marginTop = convertPrintParameterToInches(margin.top) || 0;
const marginLeft = convertPrintParameterToInches(margin.left) || 0;
const marginBottom = convertPrintParameterToInches(margin.bottom) || 0;
const marginRight = convertPrintParameterToInches(margin.right) || 0;
const result = await this._client.send('Page.printToPDF', {
landscape: landscape,
displayHeaderFooter: displayHeaderFooter,
headerTemplate: headerTemplate,
footerTemplate: footerTemplate,
printBackground: printBackground,
scale: scale,
paperWidth: paperWidth,
paperHeight: paperHeight,
marginTop: marginTop,
marginBottom: marginBottom,
marginLeft: marginLeft,
marginRight: marginRight,
pageRanges: pageRanges,
preferCSSPageSize: preferCSSPageSize
landscape,
displayHeaderFooter,
headerTemplate,
footerTemplate,
printBackground,
scale,
paperWidth,
paperHeight,
marginTop,
marginBottom,
marginLeft,
marginRight,
pageRanges,
preferCSSPageSize
});
const buffer = Buffer.from(result.data, 'base64');
if (options.path)
await writeFileAsync(options.path, buffer);
if (path !== null)
await writeFileAsync(path, buffer);
return buffer;
}
@ -925,7 +930,7 @@ class Page extends EventEmitter {
/**
* @param {string} selector
* @param {!Object=} options
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options
*/
click(selector, options = {}) {
return this.mainFrame().click(selector, options);
@ -982,7 +987,7 @@ class Page extends EventEmitter {
/**
* @param {string} selector
* @param {!Object=} options
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>}
*/
waitForSelector(selector, options = {}) {
@ -991,7 +996,7 @@ class Page extends EventEmitter {
/**
* @param {string} xpath
* @param {!Object=} options
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
* @return {!Promise<!Puppeteer.ElementHandle>}
*/
waitForXPath(xpath, options = {}) {
@ -1000,7 +1005,7 @@ class Page extends EventEmitter {
/**
* @param {function()} pageFunction
* @param {!Object=} options
* @param {!{polling?: string|number, timeout?: number}=} options
* @param {!Array<*>} args
* @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>} */
const supportedMetrics = new Set([
'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>}
*/
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>}
*/
connect(options) {
@ -52,6 +52,7 @@ module.exports = class {
}
/**
* @param {!Launcher.ChromeArgOptions=} options
* @return {!Array<string>}
*/
defaultArgs(options) {
@ -59,7 +60,7 @@ module.exports = class {
}
/**
* @param {!Object=} options
* @param {!BrowserFetcher.Options=} options
* @return {!BrowserFetcher}
*/
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) {
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',
'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)
categoriesArray.push('disabled-by-default-devtools.screenshot');
if (screenshots)
categories.push('disabled-by-default-devtools.screenshot');
this._path = options.path;
this._path = path;
this._recording = true;
await this._client.send('Tracing.start', {
transferMode: 'ReturnAsStream',
categories: categoriesArray.join(',')
categories: categories.join(',')
});
}