puppeteer-core
Advanced tools
Comparing version 1.10.0 to 1.11.0
@@ -31,4 +31,8 @@ /** | ||
} | ||
if (process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD || process.env.npm_package_config_puppeteer_skip_chromium_download) { | ||
console.log('**INFO** Skipping Chromium download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in project config.'); | ||
return; | ||
} | ||
const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host; | ||
const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host || process.env.npm_package_config_puppeteer_download_host; | ||
@@ -38,3 +42,3 @@ const puppeteer = require('./index'); | ||
const revision = process.env.PUPPETEER_CHROMIUM_REVISION || process.env.npm_config_puppeteer_chromium_revision | ||
const revision = process.env.PUPPETEER_CHROMIUM_REVISION || process.env.npm_config_puppeteer_chromium_revision || process.env.npm_package_config_puppeteer_chromium_revision | ||
|| require('./package.json').puppeteer.chromium_revision; | ||
@@ -41,0 +45,0 @@ |
@@ -198,2 +198,3 @@ /** | ||
* @param {{timeout?: number}=} options | ||
* @return {!Promise<!Target>} | ||
*/ | ||
@@ -302,2 +303,3 @@ async waitForTarget(predicate, options = {}) { | ||
* @param {{timeout?: number}=} options | ||
* @return {!Promise<!Target>} | ||
*/ | ||
@@ -304,0 +306,0 @@ waitForTarget(predicate, options) { |
@@ -164,3 +164,2 @@ /** | ||
* @param {string} revision | ||
* @return {!Promise} | ||
*/ | ||
@@ -167,0 +166,0 @@ async remove(revision) { |
@@ -231,2 +231,3 @@ /** | ||
this._connection = null; | ||
this.emit(CDPSession.Events.Disconnected); | ||
} | ||
@@ -244,2 +245,7 @@ | ||
} | ||
CDPSession.Events = { | ||
Disconnected: Symbol('CDPSession.Events.Disconnected'), | ||
}; | ||
helper.tracePublicAPI(CDPSession); | ||
@@ -246,0 +252,0 @@ |
@@ -38,3 +38,3 @@ /** | ||
/** | ||
* @param {!Object} options | ||
* @param {!{resetOnNavigation?: boolean, reportAnonymousScripts?: boolean}} options | ||
*/ | ||
@@ -53,3 +53,3 @@ async startJSCoverage(options) { | ||
/** | ||
* @param {!Object} options | ||
* @param {{resetOnNavigation?: boolean}=} options | ||
*/ | ||
@@ -85,8 +85,12 @@ async startCSSCoverage(options) { | ||
/** | ||
* @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; | ||
@@ -180,7 +184,8 @@ this._scriptURLs.clear(); | ||
/** | ||
* @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; | ||
@@ -187,0 +192,0 @@ this._stylesheetURLs.clear(); |
@@ -218,3 +218,3 @@ /** | ||
/** | ||
* @return {!Promise<Map<string, !JSHandle>>} | ||
* @return {!Promise<!Map<string, !JSHandle>>} | ||
*/ | ||
@@ -380,3 +380,3 @@ async getProperties() { | ||
* @param {!Array<number>} quad | ||
* @return {!Array<object>} | ||
* @return {!Array<{x: number, y: number}>} | ||
*/ | ||
@@ -399,5 +399,5 @@ _fromProtocolQuad(quad) { | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
async click(options = {}) { | ||
async click(options) { | ||
await this._scrollIntoViewIfNeeded(); | ||
@@ -410,3 +410,2 @@ const {x, y} = await this._clickablePoint(); | ||
* @param {!Array<string>} filePaths | ||
* @return {!Promise} | ||
*/ | ||
@@ -416,3 +415,3 @@ async uploadFile(...filePaths) { | ||
const objectId = this._remoteObject.objectId; | ||
return this._client.send('DOM.setFileInputFiles', { objectId, files }); | ||
await this._client.send('DOM.setFileInputFiles', { objectId, files }); | ||
} | ||
@@ -441,3 +440,3 @@ | ||
* @param {string} key | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, text?: string}=} options | ||
*/ | ||
@@ -468,3 +467,3 @@ async press(key, options) { | ||
/** | ||
* @return {!Promise<?object>} | ||
* @return {!Promise<?BoxModel>} | ||
*/ | ||
@@ -491,3 +490,3 @@ async boxModel() { | ||
* @param {!Object=} options | ||
* @returns {!Promise<Object>} | ||
* @returns {!Promise<string|!Buffer>} | ||
*/ | ||
@@ -658,2 +657,12 @@ async screenshot(options = {}) { | ||
/** | ||
* @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); | ||
@@ -660,0 +669,0 @@ helper.tracePublicAPI(JSHandle); |
@@ -23,3 +23,3 @@ /** | ||
const {NetworkManager} = require('./NetworkManager'); | ||
const {Connection} = require('./Connection'); | ||
const {CDPSession} = require('./Connection'); | ||
@@ -69,13 +69,17 @@ const readFileAsync = helper.promisify(fs.readFile); | ||
* @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']; | ||
assertNoLegacyNavigationOptions(options); | ||
const { | ||
referer = this._networkManager.extraHTTPHeaders()['referer'], | ||
waitUntil = ['load'], | ||
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 LifecycleWatcher(this, frame, waitUntil, timeout); | ||
let ensureNewDocumentNavigation = false; | ||
let error = await Promise.race([ | ||
navigate(this._client, url, referrer, frame._id), | ||
navigate(this._client, url, referer, frame._id), | ||
watcher.timeoutOrTerminationPromise(), | ||
@@ -114,8 +118,12 @@ ]); | ||
* @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; | ||
const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options); | ||
async waitForFrameNavigation(frame, options = {}) { | ||
assertNoLegacyNavigationOptions(options); | ||
const { | ||
waitUntil = ['load'], | ||
timeout = this._defaultNavigationTimeout, | ||
} = options; | ||
const watcher = new LifecycleWatcher(this, frame, waitUntil, timeout); | ||
const error = await Promise.race([ | ||
@@ -403,6 +411,6 @@ watcher.timeoutOrTerminationPromise(), | ||
* @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); | ||
@@ -412,6 +420,6 @@ } | ||
/** | ||
* @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); | ||
@@ -529,4 +537,11 @@ } | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
*/ | ||
async setContent(html) { | ||
async setContent(html, options = {}) { | ||
const { | ||
waitUntil = ['load'], | ||
timeout = 30000, | ||
} = options; | ||
// We rely upon the fact that document.open() will reset frame lifecycle with "init" | ||
// lifecycle event. @see https://crrev.com/608658 | ||
await this.evaluate(html => { | ||
@@ -537,2 +552,10 @@ document.open(); | ||
}, html); | ||
const watcher = new LifecycleWatcher(this._frameManager, this, waitUntil, timeout); | ||
const error = await Promise.race([ | ||
watcher.timeoutOrTerminationPromise(), | ||
watcher.lifecyclePromise(), | ||
]); | ||
watcher.dispose(); | ||
if (error) | ||
throw error; | ||
} | ||
@@ -576,11 +599,16 @@ | ||
/** | ||
* @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) { | ||
@@ -591,12 +619,12 @@ 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(); | ||
} | ||
@@ -644,8 +672,12 @@ | ||
/** | ||
* @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 { | ||
@@ -659,5 +691,5 @@ const context = await this._contextPromise; | ||
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; | ||
@@ -667,5 +699,5 @@ 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(); | ||
} | ||
@@ -712,5 +744,5 @@ | ||
* @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); | ||
@@ -793,3 +825,3 @@ assert(handle, 'No node found for selector: ' + selector); | ||
* @param {!Array<*>} args | ||
* @return {!Promise} | ||
* @return {!Promise<!Puppeteer.JSHandle>} | ||
*/ | ||
@@ -814,6 +846,6 @@ waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) { | ||
* @param {string} selector | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
waitForSelector(selector, options = {}) { | ||
waitForSelector(selector, options) { | ||
return this._waitForSelectorOrXPath(selector, false, options); | ||
@@ -824,6 +856,6 @@ } | ||
* @param {string} xpath | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
waitForXPath(xpath, options = {}) { | ||
waitForXPath(xpath, options) { | ||
return this._waitForSelectorOrXPath(xpath, true, options); | ||
@@ -834,8 +866,10 @@ } | ||
* @param {Function|string} pageFunction | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @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; | ||
@@ -854,10 +888,12 @@ } | ||
* @param {boolean} isXPath | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @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' : ''}`; | ||
@@ -1131,20 +1167,20 @@ return new WaitTask(this, predicate, title, polling, timeout, selectorOrXPath, isXPath, waitForVisible, waitForHidden).promise; | ||
class NavigatorWatcher { | ||
function assertNoLegacyNavigationOptions(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.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead'); | ||
} | ||
class LifecycleWatcher { | ||
/** | ||
* @param {!Puppeteer.CDPSession} client | ||
* @param {!FrameManager} frameManager | ||
* @param {!NetworkManager} networkManager | ||
* @param {!Puppeteer.Frame} frame | ||
* @param {string|!Array<string>} waitUntil | ||
* @param {number} timeout | ||
* @param {!Object=} 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.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]; | ||
constructor(frameManager, frame, waitUntil, timeout) { | ||
if (Array.isArray(waitUntil)) | ||
waitUntil = waitUntil.slice(); | ||
else if (typeof waitUntil === 'string') | ||
waitUntil = [waitUntil]; | ||
this._expectedLifecycle = waitUntil.map(value => { | ||
@@ -1157,3 +1193,3 @@ const protocolEvent = puppeteerToProtocolLifecycle[value]; | ||
this._frameManager = frameManager; | ||
this._networkManager = networkManager; | ||
this._networkManager = frameManager._networkManager; | ||
this._frame = frame; | ||
@@ -1164,5 +1200,4 @@ this._initialLoaderId = frame._loaderId; | ||
this._navigationRequest = null; | ||
this._hasSameDocumentNavigation = false; | ||
this._eventListeners = [ | ||
helper.addEventListener(Connection.fromSession(client), Connection.Events.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper.addEventListener(frameManager._client, CDPSession.Events.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper.addEventListener(this._frameManager, FrameManager.Events.LifecycleEvent, this._checkLifecycleComplete.bind(this)), | ||
@@ -1178,2 +1213,6 @@ helper.addEventListener(this._frameManager, FrameManager.Events.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)), | ||
this._lifecyclePromise = new Promise(fulfill => { | ||
this._lifecycleCallback = fulfill; | ||
}); | ||
this._newDocumentNavigationPromise = new Promise(fulfill => { | ||
@@ -1238,2 +1277,9 @@ this._newDocumentNavigationCompleteCallback = fulfill; | ||
/** | ||
* @return {!Promise} | ||
*/ | ||
lifecyclePromise() { | ||
return this._lifecyclePromise; | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
@@ -1268,6 +1314,7 @@ */ | ||
// We expect navigation to commit. | ||
if (!checkLifecycle(this._frame, this._expectedLifecycle)) | ||
return; | ||
this._lifecycleCallback(); | ||
if (this._frame._loaderId === this._initialLoaderId && !this._hasSameDocumentNavigation) | ||
return; | ||
if (!checkLifecycle(this._frame, this._expectedLifecycle)) | ||
return; | ||
if (this._hasSameDocumentNavigation) | ||
@@ -1274,0 +1321,0 @@ this._sameDocumentNavigationCompleteCallback(); |
@@ -174,7 +174,8 @@ /** | ||
* @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)); | ||
@@ -202,10 +203,9 @@ await this.up(key); | ||
* @param {number} y | ||
* @param {Object=} options | ||
* @return {!Promise} | ||
* @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++) { | ||
@@ -225,9 +225,10 @@ await this._client.send('Input.dispatchMouseEvent', { | ||
* @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); | ||
@@ -237,13 +238,14 @@ } | ||
/** | ||
* @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 | ||
}); | ||
@@ -253,13 +255,14 @@ } | ||
/** | ||
* @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 | ||
}); | ||
@@ -266,0 +269,0 @@ } |
@@ -74,3 +74,3 @@ /** | ||
/** | ||
* @param {!(LaunchOptions & ChromeArgOptions & BrowserOptions)=} options | ||
* @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options | ||
* @return {!Promise<!Browser>} | ||
@@ -240,3 +240,3 @@ */ | ||
/** | ||
* @param {!ChromeArgOptions=} options | ||
* @param {!Launcher.ChromeArgOptions=} options | ||
* @return {!Array<string>} | ||
@@ -279,3 +279,3 @@ */ | ||
/** | ||
* @param {!(BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @return {!Promise<!Browser>} | ||
@@ -380,3 +380,3 @@ */ | ||
/** | ||
* @typedef {Object} ChromeArgOptions | ||
* @typedef {Object} Launcher.ChromeArgOptions | ||
* @property {boolean=} headless | ||
@@ -389,5 +389,5 @@ * @property {Array<string>=} args | ||
/** | ||
* @typedef {Object} LaunchOptions | ||
* @typedef {Object} Launcher.LaunchOptions | ||
* @property {string=} executablePath | ||
* @property {boolean=} ignoreDefaultArgs | ||
* @property {boolean|Array<string>=} ignoreDefaultArgs | ||
* @property {boolean=} handleSIGINT | ||
@@ -403,3 +403,3 @@ * @property {boolean=} handleSIGTERM | ||
/** | ||
* @typedef {Object} BrowserOptions | ||
* @typedef {Object} Launcher.BrowserOptions | ||
* @property {boolean=} ignoreHTTPSErrors | ||
@@ -406,0 +406,0 @@ * @property {(?Puppeteer.Viewport)=} defaultViewport |
@@ -394,3 +394,3 @@ /** | ||
/** | ||
* @param {!Object=} overrides | ||
* @param {!{url?: string, method?:string, postData?: string, headers?: !Object}} overrides | ||
*/ | ||
@@ -400,9 +400,15 @@ async continue(overrides = {}) { | ||
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 => { | ||
@@ -409,0 +415,0 @@ // In certain cases, protocol will return error if the request was already canceled |
228
lib/Page.js
@@ -353,3 +353,3 @@ /** | ||
/** | ||
* @param {Array<Network.CookieParam>} cookies | ||
* @param {Array<Protocol.Network.deleteCookiesParameters>} cookies | ||
*/ | ||
@@ -392,3 +392,3 @@ async deleteCookie(...cookies) { | ||
/** | ||
* @param {Object} options | ||
* @param {!{url?: string, path?: string, content?: string, type?: string}} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
@@ -401,3 +401,3 @@ */ | ||
/** | ||
* @param {Object} options | ||
* @param {!{url?: string, path?: string, content?: string}} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
@@ -434,3 +434,3 @@ */ | ||
me['lastSeq'] = seq; | ||
const promise = new Promise(fulfill => callbacks.set(seq, fulfill)); | ||
const promise = new Promise((resolve, reject) => callbacks.set(seq, {resolve, reject})); | ||
binding(JSON.stringify({name: bindingName, seq, args})); | ||
@@ -464,3 +464,3 @@ return promise; | ||
/** | ||
* @return {!Promise<!Object>} | ||
* @return {!Promise<!Metrics>} | ||
*/ | ||
@@ -473,3 +473,3 @@ async metrics() { | ||
/** | ||
* @param {*} event | ||
* @param {!Protocol.Performance.metricsPayload} event | ||
*/ | ||
@@ -485,3 +485,3 @@ _emitMetrics(event) { | ||
* @param {?Array<!Protocol.Performance.Metric>} metrics | ||
* @return {!Object} | ||
* @return {!Metrics} | ||
*/ | ||
@@ -521,10 +521,46 @@ _buildMetricsObject(metrics) { | ||
const {name, seq, args} = JSON.parse(event.payload); | ||
const result = await this._pageBindings.get(name)(...args); | ||
const expression = helper.evaluationString(deliverResult, name, seq, result); | ||
let expression = null; | ||
try { | ||
const result = await this._pageBindings.get(name)(...args); | ||
expression = helper.evaluationString(deliverResult, name, seq, result); | ||
} catch (error) { | ||
if (error instanceof Error) | ||
expression = helper.evaluationString(deliverError, name, seq, error.message, error.stack); | ||
else | ||
expression = helper.evaluationString(deliverErrorValue, name, seq, error); | ||
} | ||
this._client.send('Runtime.evaluate', { expression, contextId: event.executionContextId }).catch(debugError); | ||
/** | ||
* @param {string} name | ||
* @param {number} seq | ||
* @param {*} result | ||
*/ | ||
function deliverResult(name, seq, result) { | ||
window[name]['callbacks'].get(seq)(result); | ||
window[name]['callbacks'].get(seq).resolve(result); | ||
window[name]['callbacks'].delete(seq); | ||
} | ||
/** | ||
* @param {string} name | ||
* @param {number} seq | ||
* @param {string} message | ||
* @param {string} stack | ||
*/ | ||
function deliverError(name, seq, message, stack) { | ||
const error = new Error(message); | ||
error.stack = stack; | ||
window[name]['callbacks'].get(seq).reject(error); | ||
window[name]['callbacks'].delete(seq); | ||
} | ||
/** | ||
* @param {string} name | ||
* @param {number} seq | ||
* @param {*} value | ||
*/ | ||
function deliverErrorValue(name, seq, value) { | ||
window[name]['callbacks'].get(seq).reject(value); | ||
window[name]['callbacks'].delete(seq); | ||
} | ||
} | ||
@@ -576,3 +612,3 @@ | ||
/** | ||
* @return {!Promise<String>} | ||
* @return {!Promise<string>} | ||
*/ | ||
@@ -585,5 +621,6 @@ async content() { | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
*/ | ||
async setContent(html) { | ||
await this._frameManager.mainFrame().setContent(html); | ||
async setContent(html, options) { | ||
await this._frameManager.mainFrame().setContent(html, options); | ||
} | ||
@@ -593,6 +630,6 @@ | ||
* @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); | ||
@@ -602,3 +639,3 @@ } | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -615,3 +652,3 @@ */ | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -625,7 +662,9 @@ */ | ||
* @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 => { | ||
@@ -642,7 +681,9 @@ if (helper.isString(urlOrPredicate)) | ||
* @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 => { | ||
@@ -658,3 +699,3 @@ if (helper.isString(urlOrPredicate)) | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -667,3 +708,3 @@ */ | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -676,3 +717,3 @@ */ | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -697,6 +738,6 @@ */ | ||
/** | ||
* @param {!Object} options | ||
* @param {!{viewport: !Puppeteer.Viewport, userAgent: string}} options | ||
*/ | ||
async emulate(options) { | ||
return Promise.all([ | ||
await Promise.all([ | ||
this.setViewport(options.viewport), | ||
@@ -768,4 +809,3 @@ this.setUserAgent(options.userAgent) | ||
/** | ||
* @param {Boolean} enabled | ||
* @returns {!Promise} | ||
* @param {boolean} enabled | ||
*/ | ||
@@ -777,3 +817,3 @@ async setCacheEnabled(enabled = true) { | ||
/** | ||
* @param {!Object=} options | ||
* @param {!ScreenshotOptions=} options | ||
* @return {!Promise<!Buffer|!String>} | ||
@@ -818,3 +858,3 @@ */ | ||
* @param {"png"|"jpeg"} format | ||
* @param {!Object=} options | ||
* @param {!ScreenshotOptions=} options | ||
* @return {!Promise<!Buffer|!String>} | ||
@@ -824,5 +864,3 @@ */ | ||
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; | ||
@@ -862,13 +900,18 @@ if (options.fullPage) { | ||
/** | ||
* @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; | ||
@@ -887,28 +930,26 @@ let paperWidth = 8.5; | ||
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; | ||
@@ -954,3 +995,3 @@ } | ||
* @param {string} selector | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
@@ -1004,3 +1045,3 @@ click(selector, options = {}) { | ||
* @param {!Array<*>} args | ||
* @return {!Promise} | ||
* @return {!Promise<!Puppeteer.JSHandle>} | ||
*/ | ||
@@ -1013,4 +1054,4 @@ waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) { | ||
* @param {string} selector | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
@@ -1023,4 +1064,4 @@ waitForSelector(selector, options = {}) { | ||
* @param {string} xpath | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
@@ -1033,5 +1074,5 @@ waitForXPath(xpath, options = {}) { | ||
* @param {function()} pageFunction | ||
* @param {!Object=} options | ||
* @param {!{polling?: string|number, timeout?: number}=} options | ||
* @param {!Array<*>} args | ||
* @return {!Promise} | ||
* @return {!Promise<!Puppeteer.JSHandle>} | ||
*/ | ||
@@ -1043,2 +1084,47 @@ waitForFunction(pageFunction, options = {}, ...args) { | ||
/** | ||
* @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>} */ | ||
@@ -1045,0 +1131,0 @@ const supportedMetrics = new Set([ |
@@ -32,3 +32,3 @@ /** | ||
/** | ||
* @param {!Object=} options | ||
* @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options | ||
* @return {!Promise<!Puppeteer.Browser>} | ||
@@ -41,3 +41,3 @@ */ | ||
/** | ||
* @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean, transport?: !Puppeteer.ConnectionTransport}} options | ||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @return {!Promise<!Puppeteer.Browser>} | ||
@@ -57,2 +57,3 @@ */ | ||
/** | ||
* @param {!Launcher.ChromeArgOptions=} options | ||
* @return {!Array<string>} | ||
@@ -65,3 +66,3 @@ */ | ||
/** | ||
* @param {!Object=} options | ||
* @param {!BrowserFetcher.Options=} options | ||
* @return {!BrowserFetcher} | ||
@@ -68,0 +69,0 @@ */ |
@@ -34,3 +34,3 @@ /** | ||
/** | ||
* @param {!Object} options | ||
* @param {!{path: string, screenshots?: boolean, categories?: !Array<string>}} options | ||
*/ | ||
@@ -46,15 +46,22 @@ async start(options) { | ||
]; | ||
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(',') | ||
}); | ||
} | ||
/** | ||
* @return {!Promise<!Buffer>} | ||
*/ | ||
async stop() { | ||
@@ -61,0 +68,0 @@ let fulfill; |
@@ -380,2 +380,3 @@ /** | ||
* @param {{timeout?: number}=} options | ||
* @return {!Promise<!Target>} | ||
*/ | ||
@@ -614,2 +615,3 @@ /* async */ waitForTarget(predicate, options = {}) {return (fn => { | ||
* @param {{timeout?: number}=} options | ||
* @return {!Promise<!Target>} | ||
*/ | ||
@@ -616,0 +618,0 @@ waitForTarget(predicate, options) { |
@@ -216,3 +216,2 @@ /** | ||
* @param {string} revision | ||
* @return {!Promise} | ||
*/ | ||
@@ -219,0 +218,0 @@ /* async */ remove(revision) {return (fn => { |
@@ -309,2 +309,3 @@ /** | ||
this._connection = null; | ||
this.emit(CDPSession.Events.Disconnected); | ||
} | ||
@@ -322,2 +323,7 @@ | ||
} | ||
CDPSession.Events = { | ||
Disconnected: Symbol('CDPSession.Events.Disconnected'), | ||
}; | ||
helper.tracePublicAPI(CDPSession); | ||
@@ -324,0 +330,0 @@ |
@@ -38,3 +38,3 @@ /** | ||
/** | ||
* @param {!Object} options | ||
* @param {!{resetOnNavigation?: boolean, reportAnonymousScripts?: boolean}} options | ||
*/ | ||
@@ -105,3 +105,3 @@ /* async */ startJSCoverage(options) {return (fn => { | ||
/** | ||
* @param {!Object} options | ||
* @param {{resetOnNavigation?: boolean}=} options | ||
*/ | ||
@@ -189,3 +189,3 @@ /* async */ startCSSCoverage(options) {return (fn => { | ||
/** | ||
* @param {!Object} options | ||
* @param {!{resetOnNavigation?: boolean, reportAnonymousScripts?: boolean}} options | ||
*/ | ||
@@ -220,4 +220,8 @@ /* async */ start(options = {}) {return (fn => { | ||
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; | ||
@@ -363,3 +367,3 @@ this._scriptURLs.clear(); | ||
/** | ||
* @param {!Object} options | ||
* @param {{resetOnNavigation?: boolean}=} options | ||
*/ | ||
@@ -394,3 +398,4 @@ /* async */ start(options = {}) {return (fn => { | ||
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; | ||
@@ -397,0 +402,0 @@ this._stylesheetURLs.clear(); |
@@ -322,3 +322,3 @@ /** | ||
/** | ||
* @return {!Promise<Map<string, !JSHandle>>} | ||
* @return {!Promise<!Map<string, !JSHandle>>} | ||
*/ | ||
@@ -666,3 +666,3 @@ /* async */ getProperties() {return (fn => { | ||
* @param {!Array<number>} quad | ||
* @return {!Array<object>} | ||
* @return {!Array<{x: number, y: number}>} | ||
*/ | ||
@@ -711,5 +711,5 @@ _fromProtocolQuad(quad) { | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
/* async */ click(options = {}) {return (fn => { | ||
/* async */ click(options) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -748,3 +748,2 @@ return new Promise((resolve, reject) => { | ||
* @param {!Array<string>} filePaths | ||
* @return {!Promise} | ||
*/ | ||
@@ -780,3 +779,3 @@ /* async */ uploadFile(...filePaths) {return (fn => { | ||
const objectId = this._remoteObject.objectId; | ||
return this._client.send('DOM.setFileInputFiles', { objectId, files }); | ||
(yield this._client.send('DOM.setFileInputFiles', { objectId, files })); | ||
});} | ||
@@ -883,3 +882,3 @@ | ||
* @param {string} key | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, text?: string}=} options | ||
*/ | ||
@@ -962,3 +961,3 @@ /* async */ press(key, options) {return (fn => { | ||
/** | ||
* @return {!Promise<?object>} | ||
* @return {!Promise<?BoxModel>} | ||
*/ | ||
@@ -1011,3 +1010,3 @@ /* async */ boxModel() {return (fn => { | ||
* @param {!Object=} options | ||
* @returns {!Promise<Object>} | ||
* @returns {!Promise<string|!Buffer>} | ||
*/ | ||
@@ -1360,2 +1359,12 @@ /* async */ screenshot(options = {}) {return (fn => { | ||
/** | ||
* @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); | ||
@@ -1362,0 +1371,0 @@ helper.tracePublicAPI(JSHandle); |
@@ -23,3 +23,3 @@ /** | ||
const {NetworkManager} = require('./NetworkManager'); | ||
const {Connection} = require('./Connection'); | ||
const {CDPSession} = require('./Connection'); | ||
@@ -69,3 +69,3 @@ const readFileAsync = helper.promisify(fs.readFile); | ||
* @param {string} url | ||
* @param {!Object=} options | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -100,9 +100,13 @@ */ | ||
})(function*(){ | ||
const referrer = typeof options.referer === 'string' ? options.referer : this._networkManager.extraHTTPHeaders()['referer']; | ||
assertNoLegacyNavigationOptions(options); | ||
const { | ||
referer = this._networkManager.extraHTTPHeaders()['referer'], | ||
waitUntil = ['load'], | ||
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 LifecycleWatcher(this, frame, waitUntil, timeout); | ||
let ensureNewDocumentNavigation = false; | ||
let error = (yield Promise.race([ | ||
navigate(this._client, url, referrer, frame._id), | ||
navigate(this._client, url, referer, frame._id), | ||
watcher.timeoutOrTerminationPromise(), | ||
@@ -167,6 +171,6 @@ ])); | ||
* @param {!Puppeteer.Frame} frame | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
*/ | ||
/* async */ waitForFrameNavigation(frame, options) {return (fn => { | ||
/* async */ waitForFrameNavigation(frame, options = {}) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -198,4 +202,8 @@ return new Promise((resolve, reject) => { | ||
})(function*(){ | ||
const timeout = typeof options.timeout === 'number' ? options.timeout : this._defaultNavigationTimeout; | ||
const watcher = new NavigatorWatcher(this._client, this, this._networkManager, frame, timeout, options); | ||
assertNoLegacyNavigationOptions(options); | ||
const { | ||
waitUntil = ['load'], | ||
timeout = this._defaultNavigationTimeout, | ||
} = options; | ||
const watcher = new LifecycleWatcher(this, frame, waitUntil, timeout); | ||
const error = (yield Promise.race([ | ||
@@ -483,6 +491,6 @@ watcher.timeoutOrTerminationPromise(), | ||
* @param {string} url | ||
* @param {!Object=} options | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
*/ | ||
/* async */ goto(url, options = {}) {return (fn => { | ||
/* async */ goto(url, options) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -518,6 +526,6 @@ return new Promise((resolve, reject) => { | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
*/ | ||
/* async */ waitForNavigation(options = {}) {return (fn => { | ||
/* async */ waitForNavigation(options) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -921,4 +929,5 @@ return new Promise((resolve, reject) => { | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
*/ | ||
/* async */ setContent(html) {return (fn => { | ||
/* async */ setContent(html, options = {}) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -950,2 +959,8 @@ return new Promise((resolve, reject) => { | ||
})(function*(){ | ||
const { | ||
waitUntil = ['load'], | ||
timeout = 30000, | ||
} = options; | ||
// We rely upon the fact that document.open() will reset frame lifecycle with "init" | ||
// lifecycle event. @see https://crrev.com/608658 | ||
(yield this.evaluate(html => { | ||
@@ -956,2 +971,10 @@ document.open(); | ||
}, html)); | ||
const watcher = new LifecycleWatcher(this._frameManager, this, waitUntil, timeout); | ||
const error = (yield Promise.race([ | ||
watcher.timeoutOrTerminationPromise(), | ||
watcher.lifecyclePromise(), | ||
])); | ||
watcher.dispose(); | ||
if (error) | ||
throw error; | ||
});} | ||
@@ -995,3 +1018,3 @@ | ||
/** | ||
* @param {Object} options | ||
* @param {!{url?: string, path?: string, content?: string, type?: string}} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
@@ -1026,7 +1049,12 @@ */ | ||
})(function*(){ | ||
if (typeof options.url === 'string') { | ||
const url = options.url; | ||
const { | ||
url = null, | ||
path = null, | ||
content = null, | ||
type = '' | ||
} = options; | ||
if (url !== null) { | ||
try { | ||
const context = (yield this._contextPromise); | ||
return ((yield context.evaluateHandle(addScriptUrl, url, options.type))).asElement(); | ||
return ((yield context.evaluateHandle(addScriptUrl, url, type))).asElement(); | ||
} catch (error) { | ||
@@ -1037,12 +1065,12 @@ throw new Error(`Loading script from ${url} failed`); | ||
if (typeof options.path === 'string') { | ||
let contents = (yield readFileAsync(options.path, 'utf8')); | ||
contents += '//# sourceURL=' + options.path.replace(/\n/g, ''); | ||
if (path !== null) { | ||
let contents = (yield readFileAsync(path, 'utf8')); | ||
contents += '//# sourceURL=' + path.replace(/\n/g, ''); | ||
const context = (yield this._contextPromise); | ||
return ((yield context.evaluateHandle(addScriptContent, contents, options.type))).asElement(); | ||
return ((yield context.evaluateHandle(addScriptContent, contents, type))).asElement(); | ||
} | ||
if (typeof options.content === 'string') { | ||
if (content !== null) { | ||
const context = (yield this._contextPromise); | ||
return ((yield context.evaluateHandle(addScriptContent, options.content, options.type))).asElement(); | ||
return ((yield context.evaluateHandle(addScriptContent, content, type))).asElement(); | ||
} | ||
@@ -1116,3 +1144,3 @@ | ||
/** | ||
* @param {Object} options | ||
* @param {!{url?: string, path?: string, content?: string}} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
@@ -1147,4 +1175,8 @@ */ | ||
})(function*(){ | ||
if (typeof options.url === 'string') { | ||
const url = options.url; | ||
const { | ||
url = null, | ||
path = null, | ||
content = null | ||
} = options; | ||
if (url !== null) { | ||
try { | ||
@@ -1158,5 +1190,5 @@ const context = (yield this._contextPromise); | ||
if (typeof options.path === 'string') { | ||
let contents = (yield readFileAsync(options.path, 'utf8')); | ||
contents += '/*# sourceURL=' + options.path.replace(/\n/g, '') + '*/'; | ||
if (path !== null) { | ||
let contents = (yield readFileAsync(path, 'utf8')); | ||
contents += '/*# sourceURL=' + path.replace(/\n/g, '') + '*/'; | ||
const context = (yield this._contextPromise); | ||
@@ -1166,5 +1198,5 @@ return ((yield context.evaluateHandle(addStyleContent, contents))).asElement(); | ||
if (typeof options.content === 'string') { | ||
if (content !== null) { | ||
const context = (yield this._contextPromise); | ||
return ((yield context.evaluateHandle(addStyleContent, options.content))).asElement(); | ||
return ((yield context.evaluateHandle(addStyleContent, content))).asElement(); | ||
} | ||
@@ -1263,5 +1295,5 @@ | ||
* @param {string} selector | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
/* async */ click(selector, options = {}) {return (fn => { | ||
/* async */ click(selector, options) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -1474,3 +1506,3 @@ return new Promise((resolve, reject) => { | ||
* @param {!Array<*>} args | ||
* @return {!Promise} | ||
* @return {!Promise<!Puppeteer.JSHandle>} | ||
*/ | ||
@@ -1495,6 +1527,6 @@ waitFor(selectorOrFunctionOrTimeout, options = {}, ...args) { | ||
* @param {string} selector | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
waitForSelector(selector, options = {}) { | ||
waitForSelector(selector, options) { | ||
return this._waitForSelectorOrXPath(selector, false, options); | ||
@@ -1505,6 +1537,6 @@ } | ||
* @param {string} xpath | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options | ||
* @return {!Promise<!Puppeteer.ElementHandle>} | ||
*/ | ||
waitForXPath(xpath, options = {}) { | ||
waitForXPath(xpath, options) { | ||
return this._waitForSelectorOrXPath(xpath, true, options); | ||
@@ -1515,8 +1547,10 @@ } | ||
* @param {Function|string} pageFunction | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @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; | ||
@@ -1561,10 +1595,12 @@ } | ||
* @param {boolean} isXPath | ||
* @param {!Object=} options | ||
* @return {!Promise} | ||
* @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' : ''}`; | ||
@@ -1890,20 +1926,20 @@ return new WaitTask(this, predicate, title, polling, timeout, selectorOrXPath, isXPath, waitForVisible, waitForHidden).promise; | ||
class NavigatorWatcher { | ||
function assertNoLegacyNavigationOptions(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.waitUntil !== 'networkidle', 'ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead'); | ||
} | ||
class LifecycleWatcher { | ||
/** | ||
* @param {!Puppeteer.CDPSession} client | ||
* @param {!FrameManager} frameManager | ||
* @param {!NetworkManager} networkManager | ||
* @param {!Puppeteer.Frame} frame | ||
* @param {string|!Array<string>} waitUntil | ||
* @param {number} timeout | ||
* @param {!Object=} 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.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]; | ||
constructor(frameManager, frame, waitUntil, timeout) { | ||
if (Array.isArray(waitUntil)) | ||
waitUntil = waitUntil.slice(); | ||
else if (typeof waitUntil === 'string') | ||
waitUntil = [waitUntil]; | ||
this._expectedLifecycle = waitUntil.map(value => { | ||
@@ -1916,3 +1952,3 @@ const protocolEvent = puppeteerToProtocolLifecycle[value]; | ||
this._frameManager = frameManager; | ||
this._networkManager = networkManager; | ||
this._networkManager = frameManager._networkManager; | ||
this._frame = frame; | ||
@@ -1923,5 +1959,4 @@ this._initialLoaderId = frame._loaderId; | ||
this._navigationRequest = null; | ||
this._hasSameDocumentNavigation = false; | ||
this._eventListeners = [ | ||
helper.addEventListener(Connection.fromSession(client), Connection.Events.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper.addEventListener(frameManager._client, CDPSession.Events.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper.addEventListener(this._frameManager, FrameManager.Events.LifecycleEvent, this._checkLifecycleComplete.bind(this)), | ||
@@ -1937,2 +1972,6 @@ helper.addEventListener(this._frameManager, FrameManager.Events.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)), | ||
this._lifecyclePromise = new Promise(fulfill => { | ||
this._lifecycleCallback = fulfill; | ||
}); | ||
this._newDocumentNavigationPromise = new Promise(fulfill => { | ||
@@ -1997,2 +2036,9 @@ this._newDocumentNavigationCompleteCallback = fulfill; | ||
/** | ||
* @return {!Promise} | ||
*/ | ||
lifecyclePromise() { | ||
return this._lifecyclePromise; | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
@@ -2027,6 +2073,7 @@ */ | ||
// We expect navigation to commit. | ||
if (!checkLifecycle(this._frame, this._expectedLifecycle)) | ||
return; | ||
this._lifecycleCallback(); | ||
if (this._frame._loaderId === this._initialLoaderId && !this._hasSameDocumentNavigation) | ||
return; | ||
if (!checkLifecycle(this._frame, this._expectedLifecycle)) | ||
return; | ||
if (this._hasSameDocumentNavigation) | ||
@@ -2033,0 +2080,0 @@ this._sameDocumentNavigationCompleteCallback(); |
@@ -278,5 +278,5 @@ /** | ||
* @param {string} key | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, text?: string}=} options | ||
*/ | ||
/* async */ press(key, options) {return (fn => { | ||
/* async */ press(key, options = {}) {return (fn => { | ||
const gen = fn.call(this); | ||
@@ -308,4 +308,5 @@ return new Promise((resolve, reject) => { | ||
})(function*(){ | ||
const {delay = null} = options; | ||
(yield this.down(key, options)); | ||
if (options && options.delay) | ||
if (delay !== null) | ||
(yield new Promise(f => setTimeout(f, options.delay))); | ||
@@ -333,4 +334,3 @@ (yield this.up(key)); | ||
* @param {number} y | ||
* @param {Object=} options | ||
* @return {!Promise} | ||
* @param {!{steps?: number}=} options | ||
*/ | ||
@@ -364,6 +364,6 @@ /* async */ move(x, y, options = {}) {return (fn => { | ||
})(function*(){ | ||
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++) { | ||
@@ -383,3 +383,3 @@ (yield this._client.send('Input.dispatchMouseEvent', { | ||
* @param {number} y | ||
* @param {!Object=} options | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
@@ -413,6 +413,7 @@ /* async */ click(x, y, options = {}) {return (fn => { | ||
})(function*(){ | ||
const {delay = null} = options; | ||
this.move(x, y); | ||
this.down(options); | ||
if (typeof options.delay === 'number') | ||
(yield new Promise(f => setTimeout(f, options.delay))); | ||
if (delay !== null) | ||
(yield new Promise(f => setTimeout(f, delay))); | ||
(yield this.up(options)); | ||
@@ -422,3 +423,3 @@ });} | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
@@ -452,10 +453,11 @@ /* async */ down(options = {}) {return (fn => { | ||
})(function*(){ | ||
this._button = (options.button || 'left'); | ||
const {button = 'left', clickCount = 1} = options; | ||
this._button = button; | ||
(yield 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 | ||
})); | ||
@@ -465,3 +467,3 @@ });} | ||
/** | ||
* @param {!Object=} options | ||
* @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
@@ -495,10 +497,11 @@ /* async */ up(options = {}) {return (fn => { | ||
})(function*(){ | ||
const {button = 'left', clickCount = 1} = options; | ||
this._button = 'none'; | ||
(yield 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 | ||
})); | ||
@@ -505,0 +508,0 @@ });} |
@@ -74,3 +74,3 @@ /** | ||
/** | ||
* @param {!(LaunchOptions & ChromeArgOptions & BrowserOptions)=} options | ||
* @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options | ||
* @return {!Promise<!Browser>} | ||
@@ -292,3 +292,3 @@ */ | ||
/** | ||
* @param {!ChromeArgOptions=} options | ||
* @param {!Launcher.ChromeArgOptions=} options | ||
* @return {!Array<string>} | ||
@@ -331,3 +331,3 @@ */ | ||
/** | ||
* @param {!(BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @return {!Promise<!Browser>} | ||
@@ -458,3 +458,3 @@ */ | ||
/** | ||
* @typedef {Object} ChromeArgOptions | ||
* @typedef {Object} Launcher.ChromeArgOptions | ||
* @property {boolean=} headless | ||
@@ -467,5 +467,5 @@ * @property {Array<string>=} args | ||
/** | ||
* @typedef {Object} LaunchOptions | ||
* @typedef {Object} Launcher.LaunchOptions | ||
* @property {string=} executablePath | ||
* @property {boolean=} ignoreDefaultArgs | ||
* @property {boolean|Array<string>=} ignoreDefaultArgs | ||
* @property {boolean=} handleSIGINT | ||
@@ -481,3 +481,3 @@ * @property {boolean=} handleSIGTERM | ||
/** | ||
* @typedef {Object} BrowserOptions | ||
* @typedef {Object} Launcher.BrowserOptions | ||
* @property {boolean=} ignoreHTTPSErrors | ||
@@ -484,0 +484,0 @@ * @property {(?Puppeteer.Viewport)=} defaultViewport |
@@ -550,3 +550,3 @@ /** | ||
/** | ||
* @param {!Object=} overrides | ||
* @param {!{url?: string, method?:string, postData?: string, headers?: !Object}} overrides | ||
*/ | ||
@@ -582,9 +582,15 @@ /* async */ continue(overrides = {}) {return (fn => { | ||
assert(!this._interceptionHandled, 'Request is already handled!'); | ||
const { | ||
url, | ||
method, | ||
postData, | ||
headers | ||
} = overrides; | ||
this._interceptionHandled = true; | ||
(yield 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 => { | ||
@@ -591,0 +597,0 @@ // In certain cases, protocol will return error if the request was already canceled |
@@ -32,3 +32,3 @@ /** | ||
/** | ||
* @param {!Object=} options | ||
* @param {!(Launcher.LaunchOptions & Launcher.ChromeArgOptions & Launcher.BrowserOptions)=} options | ||
* @return {!Promise<!Puppeteer.Browser>} | ||
@@ -41,3 +41,3 @@ */ | ||
/** | ||
* @param {{browserWSEndpoint: string, ignoreHTTPSErrors: boolean, transport?: !Puppeteer.ConnectionTransport}} options | ||
* @param {!(Launcher.BrowserOptions & {browserWSEndpoint: string, transport?: !Puppeteer.ConnectionTransport})} options | ||
* @return {!Promise<!Puppeteer.Browser>} | ||
@@ -57,2 +57,3 @@ */ | ||
/** | ||
* @param {!Launcher.ChromeArgOptions=} options | ||
* @return {!Array<string>} | ||
@@ -65,3 +66,3 @@ */ | ||
/** | ||
* @param {!Object=} options | ||
* @param {!BrowserFetcher.Options=} options | ||
* @return {!BrowserFetcher} | ||
@@ -68,0 +69,0 @@ */ |
@@ -34,3 +34,3 @@ /** | ||
/** | ||
* @param {!Object} options | ||
* @param {!{path: string, screenshots?: boolean, categories?: !Array<string>}} options | ||
*/ | ||
@@ -72,15 +72,22 @@ /* async */ start(options) {return (fn => { | ||
]; | ||
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; | ||
(yield this._client.send('Tracing.start', { | ||
transferMode: 'ReturnAsStream', | ||
categories: categoriesArray.join(',') | ||
categories: categories.join(',') | ||
})); | ||
});} | ||
/** | ||
* @return {!Promise<!Buffer>} | ||
*/ | ||
/* async */ stop() {return (fn => { | ||
@@ -87,0 +94,0 @@ const gen = fn.call(this); |
{ | ||
"name": "puppeteer-core", | ||
"version": "1.10.0", | ||
"version": "1.11.0", | ||
"description": "A high-level API to control headless Chrome over the DevTools Protocol", | ||
@@ -11,3 +11,3 @@ "main": "index.js", | ||
"puppeteer": { | ||
"chromium_revision": "599821" | ||
"chromium_revision": "609904" | ||
}, | ||
@@ -35,13 +35,13 @@ "scripts": { | ||
"dependencies": { | ||
"debug": "^3.1.0", | ||
"debug": "^4.1.0", | ||
"extract-zip": "^1.6.6", | ||
"https-proxy-agent": "^2.2.1", | ||
"mime": "^2.0.3", | ||
"progress": "^2.0.0", | ||
"progress": "^2.0.1", | ||
"proxy-from-env": "^1.0.0", | ||
"rimraf": "^2.6.1", | ||
"ws": "^5.1.1" | ||
"ws": "^6.1.0" | ||
}, | ||
"devDependencies": { | ||
"@types/debug": "0.0.30", | ||
"@types/debug": "0.0.31", | ||
"@types/extract-zip": "^1.6.2", | ||
@@ -51,6 +51,6 @@ "@types/mime": "^2.0.0", | ||
"@types/rimraf": "^2.0.2", | ||
"@types/ws": "^3.0.2", | ||
"commonmark": "^0.27.0", | ||
"@types/ws": "^6.0.1", | ||
"commonmark": "^0.28.1", | ||
"cross-env": "^5.0.5", | ||
"eslint": "^4.19.1", | ||
"eslint": "^5.9.0", | ||
"esprima": "^4.0.0", | ||
@@ -63,3 +63,3 @@ "jpeg-js": "^0.3.4", | ||
"text-diff": "^1.0.1", | ||
"typescript": "^3.1.1" | ||
"typescript": "3.1.6" | ||
}, | ||
@@ -66,0 +66,0 @@ "browser": { |
@@ -9,3 +9,3 @@ # Puppeteer | ||
###### [API](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md) | [FAQ](#faq) | [Contributing](https://github.com/GoogleChrome/puppeteer/blob/master/CONTRIBUTING.md) | [Troubleshooting](https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md) | ||
###### [API](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md) | [FAQ](#faq) | [Contributing](https://github.com/GoogleChrome/puppeteer/blob/master/CONTRIBUTING.md) | [Troubleshooting](https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md) | ||
@@ -41,3 +41,3 @@ > Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the [DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/). Puppeteer runs [headless](https://developers.google.com/web/updates/2017/04/headless-chrome) by default, but can be configured to run full (non-headless) Chrome or Chromium. | ||
Note: When you install Puppeteer, it downloads a recent version of Chromium (~170MB Mac, ~282MB Linux, ~280MB Win) that is guaranteed to work with the API. To skip the download, see [Environment variables](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#environment-variables). | ||
Note: When you install Puppeteer, it downloads a recent version of Chromium (~170MB Mac, ~282MB Linux, ~280MB Win) that is guaranteed to work with the API. To skip the download, see [Environment variables](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#environment-variables). | ||
@@ -64,3 +64,3 @@ | ||
Puppeteer will be familiar to people using other browser testing frameworks. You create an instance | ||
of `Browser`, open pages, and then manipulate them with [Puppeteer's API](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#). | ||
of `Browser`, open pages, and then manipulate them with [Puppeteer's API](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#). | ||
@@ -90,3 +90,3 @@ **Example** - navigating to https://example.com and saving a screenshot as *example.png*: | ||
Puppeteer sets an initial page size to 800px x 600px, which defines the screenshot size. The page size can be customized with [`Page.setViewport()`](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#pagesetviewportviewport). | ||
Puppeteer sets an initial page size to 800px x 600px, which defines the screenshot size. The page size can be customized with [`Page.setViewport()`](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pagesetviewportviewport). | ||
@@ -116,3 +116,3 @@ **Example** - create a PDF. | ||
See [`Page.pdf()`](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#pagepdfoptions) for more information about creating pdfs. | ||
See [`Page.pdf()`](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pagepdfoptions) for more information about creating pdfs. | ||
@@ -152,3 +152,3 @@ **Example** - evaluate script in the context of the page | ||
See [`Page.evaluate()`](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#pageevaluatepagefunction-args) for more information on `evaluate` and related methods like `evaluateOnNewDocument` and `exposeFunction`. | ||
See [`Page.evaluate()`](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageevaluatepagefunction-args) for more information on `evaluate` and related methods like `evaluateOnNewDocument` and `exposeFunction`. | ||
@@ -162,3 +162,3 @@ <!-- [END getstarted] --> | ||
Puppeteer launches Chromium in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). To launch a full version of Chromium, set the ['headless' option](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#puppeteerlaunchoptions) when launching a browser: | ||
Puppeteer launches Chromium in [headless mode](https://developers.google.com/web/updates/2017/04/headless-chrome). To launch a full version of Chromium, set the ['headless' option](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#puppeteerlaunchoptions) when launching a browser: | ||
@@ -179,5 +179,5 @@ ```js | ||
See [`Puppeteer.launch()`](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#puppeteerlaunchoptions) for more information. | ||
See [`Puppeteer.launch()`](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#puppeteerlaunchoptions) for more information. | ||
See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [`This article`](https://chromium.googlesource.com/chromium/src/+/lkcr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users. | ||
See [`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [`This article`](https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users. | ||
@@ -192,3 +192,3 @@ **3. Creates a fresh user profile** | ||
- [API Documentation](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md) | ||
- [API Documentation](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md) | ||
- [Examples](https://github.com/GoogleChrome/puppeteer/tree/master/examples/) | ||
@@ -358,3 +358,3 @@ - [Community list of Puppeteer resources](https://github.com/transitive-bullshit/awesome-puppeteer) | ||
* Puppeteer is bundled with Chromium--not Chrome--and so by default, it inherits all of [Chromium's media-related limitations](https://www.chromium.org/audio-video). This means that Puppeteer does not support licensed formats such as AAC or H.264. (However, it is possible to force Puppeteer to use a separately-installed version Chrome instead of Chromium via the [`executablePath` option to `puppeteer.launch`](https://github.com/GoogleChrome/puppeteer/blob/v1.10.0/docs/api.md#puppeteerlaunchoptions). You should only use this configuration if you need an official release of Chrome that supports these media formats.) | ||
* Puppeteer is bundled with Chromium--not Chrome--and so by default, it inherits all of [Chromium's media-related limitations](https://www.chromium.org/audio-video). This means that Puppeteer does not support licensed formats such as AAC or H.264. (However, it is possible to force Puppeteer to use a separately-installed version Chrome instead of Chromium via the [`executablePath` option to `puppeteer.launch`](https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#puppeteerlaunchoptions). You should only use this configuration if you need an official release of Chrome that supports these media formats.) | ||
* Since Puppeteer (in all configurations) controls a desktop version of Chromium/Chrome, features that are only supported by the mobile version of Chrome are not supported. This means that Puppeteer [does not support HTTP Live Streaming (HLS)](https://caniuse.com/#feat=http-live-streaming). | ||
@@ -361,0 +361,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
663307
19778
39
+ Addeddebug@4.3.7(transitive)
+ Addedws@6.2.3(transitive)
- Removedws@5.2.4(transitive)
Updateddebug@^4.1.0
Updatedprogress@^2.0.1
Updatedws@^6.1.0