Socket
Socket
Sign inDemoInstall

puppeteer-core

Package Overview
Dependencies
Maintainers
1
Versions
238
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

puppeteer-core - npm Package Compare versions

Comparing version 1.10.0 to 1.11.0

8

install.js

@@ -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

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc