Socket
Socket
Sign inDemoInstall

puppeteer-core

Package Overview
Dependencies
Maintainers
5
Versions
239
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 3.0.4 to 3.1.0

lib/ConsoleMessage.js

19

index.js

@@ -17,5 +17,5 @@ /**

const {helper} = require('./lib/helper');
const { helper } = require('./lib/helper');
const api = require('./lib/api');
const {Page} = require('./lib/Page');
const { Page } = require('./lib/Page');
for (const className in api) {

@@ -29,3 +29,3 @@ if (typeof api[className] === 'function')

const {Puppeteer} = require('./lib/Puppeteer');
const { Puppeteer } = require('./lib/Puppeteer');
const packageJson = require('./package.json');

@@ -35,7 +35,16 @@ let preferredRevision = packageJson.puppeteer.chromium_revision;

// puppeteer-core ignores environment variables
const product = isPuppeteerCore ? undefined : process.env.PUPPETEER_PRODUCT || process.env.npm_config_puppeteer_product || process.env.npm_package_config_puppeteer_product;
const product = isPuppeteerCore
? undefined
: process.env.PUPPETEER_PRODUCT ||
process.env.npm_config_puppeteer_product ||
process.env.npm_package_config_puppeteer_product;
if (!isPuppeteerCore && product === 'firefox')
preferredRevision = packageJson.puppeteer.firefox_revision;
const puppeteer = new Puppeteer(__dirname, preferredRevision, isPuppeteerCore, product);
const puppeteer = new Puppeteer(
__dirname,
preferredRevision,
isPuppeteerCore,
product
);

@@ -42,0 +51,0 @@ // The introspection in `Helper.installAsyncStackHooks` references `Puppeteer._launcher`

@@ -29,5 +29,7 @@ /**

const firefoxVersions =
'https://product-details.mozilla.org/1.0/firefox_versions.json';
const supportedProducts = {
'chrome': 'Chromium',
'firefox': 'Firefox Nightly'
chrome: 'Chromium',
firefox: 'Firefox Nightly',
};

@@ -38,6 +40,16 @@

const downloadHost = process.env.PUPPETEER_DOWNLOAD_HOST || process.env.npm_config_puppeteer_download_host || process.env.npm_package_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;
const puppeteer = require('./index');
const product = process.env.PUPPETEER_PRODUCT || process.env.npm_config_puppeteer_product || process.env.npm_package_config_puppeteer_product || 'chrome';
const browserFetcher = puppeteer.createBrowserFetcher({product, host: downloadHost});
const product =
process.env.PUPPETEER_PRODUCT ||
process.env.npm_config_puppeteer_product ||
process.env.npm_package_config_puppeteer_product ||
'chrome';
const browserFetcher = puppeteer.createBrowserFetcher({
product,
host: downloadHost,
});
const revision = await getRevision();

@@ -48,7 +60,14 @@ await fetchBinary(revision);

if (product === 'chrome') {
return 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;
return (
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
);
} else if (product === 'firefox') {
puppeteer._preferredRevision = require('./package.json').puppeteer.firefox_revision;
return getFirefoxNightlyVersion(browserFetcher.host()).catch(error => { console.error(error); process.exit(1); });
return getFirefoxNightlyVersion(browserFetcher.host()).catch((error) => {
console.error(error);
process.exit(1);
});
} else {

@@ -64,3 +83,5 @@ throw new Error(`Unsupported product ${product}`);

if (revisionInfo.local) {
logPolitely(`${supportedProducts[product]} is already in ${revisionInfo.folderPath}; skipping download.`);
logPolitely(
`${supportedProducts[product]} is already in ${revisionInfo.folderPath}; skipping download.`
);
return;

@@ -70,12 +91,11 @@ }

// Override current environment proxy settings with npm configuration, if any.
const NPM_HTTPS_PROXY = process.env.npm_config_https_proxy || process.env.npm_config_proxy;
const NPM_HTTP_PROXY = process.env.npm_config_http_proxy || process.env.npm_config_proxy;
const NPM_HTTPS_PROXY =
process.env.npm_config_https_proxy || process.env.npm_config_proxy;
const NPM_HTTP_PROXY =
process.env.npm_config_http_proxy || process.env.npm_config_proxy;
const NPM_NO_PROXY = process.env.npm_config_no_proxy;
if (NPM_HTTPS_PROXY)
process.env.HTTPS_PROXY = NPM_HTTPS_PROXY;
if (NPM_HTTP_PROXY)
process.env.HTTP_PROXY = NPM_HTTP_PROXY;
if (NPM_NO_PROXY)
process.env.NO_PROXY = NPM_NO_PROXY;
if (NPM_HTTPS_PROXY) process.env.HTTPS_PROXY = NPM_HTTPS_PROXY;
if (NPM_HTTP_PROXY) process.env.HTTP_PROXY = NPM_HTTP_PROXY;
if (NPM_NO_PROXY) process.env.NO_PROXY = NPM_NO_PROXY;

@@ -87,5 +107,11 @@ /**

function onSuccess(localRevisions) {
logPolitely(`${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}`);
localRevisions = localRevisions.filter(revision => revision !== revisionInfo.revision);
const cleanupOldVersions = localRevisions.map(revision => browserFetcher.remove(revision));
logPolitely(
`${supportedProducts[product]} (${revisionInfo.revision}) downloaded to ${revisionInfo.folderPath}`
);
localRevisions = localRevisions.filter(
(revision) => revision !== revisionInfo.revision
);
const cleanupOldVersions = localRevisions.map((revision) =>
browserFetcher.remove(revision)
);
Promise.all([...cleanupOldVersions]);

@@ -98,3 +124,5 @@ }

function onError(error) {
console.error(`ERROR: Failed to set up ${supportedProducts[product]} r${revision}! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.`);
console.error(
`ERROR: Failed to set up ${supportedProducts[product]} r${revision}! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.`
);
console.error(error);

@@ -109,8 +137,13 @@ process.exit(1);

const ProgressBar = require('progress');
progressBar = new ProgressBar(`Downloading ${supportedProducts[product]} r${revision} - ${toMegabytes(totalBytes)} [:bar] :percent :etas `, {
complete: '=',
incomplete: ' ',
width: 20,
total: totalBytes,
});
progressBar = new ProgressBar(
`Downloading ${
supportedProducts[product]
} r${revision} - ${toMegabytes(totalBytes)} [:bar] :percent :etas `,
{
complete: '=',
incomplete: ' ',
width: 20,
total: totalBytes,
}
);
}

@@ -122,6 +155,7 @@ const delta = downloadedBytes - lastDownloadedBytes;

return browserFetcher.download(revisionInfo.revision, onProgress)
.then(() => browserFetcher.localRevisions())
.then(onSuccess)
.catch(onError);
return browserFetcher
.download(revisionInfo.revision, onProgress)
.then(() => browserFetcher.localRevisions())
.then(onSuccess)
.catch(onError);
}

@@ -139,24 +173,19 @@

logPolitely(`Requesting latest Firefox Nightly version from ${host}`);
https.get(host + '/', r => {
if (r.statusCode >= 400)
return reject(new Error(`Got status code ${r.statusCode}`));
r.on('data', chunk => {
data += chunk;
});
r.on('end', parseVersion);
}).on('error', reject);
function parseVersion() {
const regex = /firefox\-(?<version>\d\d)\..*/gm;
let result = 0;
let match;
while ((match = regex.exec(data)) !== null) {
const version = parseInt(match.groups.version, 10);
if (version > result)
result = version;
}
if (result)
resolve(result.toString());
else reject(new Error('Firefox version not found'));
}
https
.get(firefoxVersions, (r) => {
if (r.statusCode >= 400)
return reject(new Error(`Got status code ${r.statusCode}`));
r.on('data', (chunk) => {
data += chunk;
});
r.on('end', () => {
try {
const versions = JSON.parse(data);
return resolve(versions.FIREFOX_NIGHTLY);
} catch {
return reject(new Error('Firefox version not found'));
}
});
})
.on('error', reject);
});

@@ -171,28 +200,51 @@ return promise;

if (!logLevelDisplay)
console.log(toBeLogged);
if (!logLevelDisplay) console.log(toBeLogged);
}
if (process.env.PUPPETEER_SKIP_DOWNLOAD) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" environment variable was found.');
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" environment variable was found.'
);
return;
}
if (process.env.NPM_CONFIG_PUPPETEER_SKIP_DOWNLOAD || process.env.npm_config_puppeteer_skip_download) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in npm config.');
if (
process.env.NPM_CONFIG_PUPPETEER_SKIP_DOWNLOAD ||
process.env.npm_config_puppeteer_skip_download
) {
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in npm config.'
);
return;
}
if (process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_DOWNLOAD || process.env.npm_package_config_puppeteer_skip_download) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in project config.');
if (
process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_DOWNLOAD ||
process.env.npm_package_config_puppeteer_skip_download
) {
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_DOWNLOAD" was set in project config.'
);
return;
}
if (process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" environment variable was found.');
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" environment variable was found.'
);
return;
}
if (process.env.NPM_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD || process.env.npm_config_puppeteer_skip_chromium_download) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in npm config.');
if (
process.env.NPM_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD ||
process.env.npm_config_puppeteer_skip_chromium_download
) {
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in npm config.'
);
return;
}
if (process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD || process.env.npm_package_config_puppeteer_skip_chromium_download) {
logPolitely('**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in project config.');
if (
process.env.NPM_PACKAGE_CONFIG_PUPPETEER_SKIP_CHROMIUM_DOWNLOAD ||
process.env.npm_package_config_puppeteer_skip_chromium_download
) {
logPolitely(
'**INFO** Skipping browser download. "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" was set in project config.'
);
return;

@@ -202,2 +254,1 @@ }

download();

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Accessibility = void 0;
class Accessibility {

@@ -24,7 +25,9 @@ constructor(client) {

async snapshot(options = {}) {
const { interestingOnly = true, root = null, } = options;
const { interestingOnly = true, root = null } = options;
const { nodes } = await this._client.send('Accessibility.getFullAXTree');
let backendNodeId = null;
if (root) {
const { node } = await this._client.send('DOM.describeNode', { objectId: root._remoteObject.objectId });
const { node } = await this._client.send('DOM.describeNode', {
objectId: root._remoteObject.objectId,
});
backendNodeId = node.backendNodeId;

@@ -35,3 +38,3 @@ }

if (backendNodeId) {
needle = defaultRoot.find(node => node._payload.backendDOMNodeId === backendNodeId);
needle = defaultRoot.find((node) => node.payload.backendDOMNodeId === backendNodeId);
if (!needle)

@@ -41,48 +44,42 @@ return null;

if (!interestingOnly)
return serializeTree(needle)[0];
return this.serializeTree(needle)[0];
const interestingNodes = new Set();
collectInterestingNodes(interestingNodes, defaultRoot, false);
this.collectInterestingNodes(interestingNodes, defaultRoot, false);
if (!interestingNodes.has(needle))
return null;
return serializeTree(needle, interestingNodes)[0];
return this.serializeTree(needle, interestingNodes)[0];
}
serializeTree(node, whitelistedNodes) {
const children = [];
for (const child of node.children)
children.push(...this.serializeTree(child, whitelistedNodes));
if (whitelistedNodes && !whitelistedNodes.has(node))
return children;
const serializedNode = node.serialize();
if (children.length)
serializedNode.children = children;
return [serializedNode];
}
collectInterestingNodes(collection, node, insideControl) {
if (node.isInteresting(insideControl))
collection.add(node);
if (node.isLeafNode())
return;
insideControl = insideControl || node.isControl();
for (const child of node.children)
this.collectInterestingNodes(collection, child, insideControl);
}
}
exports.Accessibility = Accessibility;
/**
* @param {!Set<!AXNode>} collection
* @param {!AXNode} node
* @param {boolean} insideControl
*/
function collectInterestingNodes(collection, node, insideControl) {
if (node.isInteresting(insideControl))
collection.add(node);
if (node.isLeafNode())
return;
insideControl = insideControl || node.isControl();
for (const child of node._children)
collectInterestingNodes(collection, child, insideControl);
}
function serializeTree(node, whitelistedNodes) {
const children = [];
for (const child of node._children)
children.push(...serializeTree(child, whitelistedNodes));
if (whitelistedNodes && !whitelistedNodes.has(node))
return children;
const serializedNode = node.serialize();
if (children.length)
serializedNode.children = children;
return [serializedNode];
}
class AXNode {
constructor(payload) {
this._children = [];
this.children = [];
this._richlyEditable = false;
this._editable = false;
this._focusable = false;
this._expanded = false;
this._hidden = false;
this._payload = payload;
this._name = this._payload.name ? this._payload.name.value : '';
this._role = this._payload.role ? this._payload.role.value : 'Unknown';
for (const property of this._payload.properties || []) {
this.payload = payload;
this._name = this.payload.name ? this.payload.name.value : '';
this._role = this.payload.role ? this.payload.role.value : 'Unknown';
for (const property of this.payload.properties || []) {
if (property.name === 'editable') {

@@ -94,4 +91,2 @@ this._richlyEditable = property.value.value === 'richtext';

this._focusable = property.value.value;
if (property.name === 'expanded')
this._expanded = property.value.value;
if (property.name === 'hidden')

@@ -106,8 +101,9 @@ this._hidden = property.value.value;

return true;
return this._role === 'textbox' || this._role === 'ComboBox' || this._role === 'searchbox';
return (this._role === 'textbox' ||
this._role === 'ComboBox' ||
this._role === 'searchbox');
}
_isTextOnlyObject() {
const role = this._role;
return (role === 'LineBreak' || role === 'text' ||
role === 'InlineTextBox');
return role === 'LineBreak' || role === 'text' || role === 'InlineTextBox';
}

@@ -117,3 +113,3 @@ _hasFocusableChild() {

this._cachedHasFocusableChild = false;
for (const child of this._children) {
for (const child of this.children) {
if (child._focusable || child._hasFocusableChild()) {

@@ -130,3 +126,3 @@ this._cachedHasFocusableChild = true;

return this;
for (const child of this._children) {
for (const child of this.children) {
const result = child.find(predicate);

@@ -139,3 +135,3 @@ if (result)

isLeafNode() {
if (!this._children.length)
if (!this.children.length)
return true;

@@ -201,6 +197,2 @@ // These types of objects may have children that we use as internal

}
/**
* @param {boolean} insideControl
* @return {boolean}
*/
isInteresting(insideControl) {

@@ -222,12 +214,12 @@ const role = this._role;

const properties = new Map();
for (const property of this._payload.properties || [])
for (const property of this.payload.properties || [])
properties.set(property.name.toLowerCase(), property.value.value);
if (this._payload.name)
properties.set('name', this._payload.name.value);
if (this._payload.value)
properties.set('value', this._payload.value.value);
if (this._payload.description)
properties.set('description', this._payload.description.value);
if (this.payload.name)
properties.set('name', this.payload.name.value);
if (this.payload.value)
properties.set('value', this.payload.value.value);
if (this.payload.description)
properties.set('description', this.payload.description.value);
const node = {
role: this._role
role: this._role,
};

@@ -270,6 +262,3 @@ const userStringProperties = [

}
const tristateProperties = [
'checked',
'pressed',
];
const tristateProperties = ['checked', 'pressed'];
for (const tristateProperty of tristateProperties) {

@@ -279,3 +268,4 @@ if (!properties.has(tristateProperty))

const value = properties.get(tristateProperty);
node[tristateProperty] = value === 'mixed' ? 'mixed' : value === 'true' ? true : false;
node[tristateProperty] =
value === 'mixed' ? 'mixed' : value === 'true' ? true : false;
}

@@ -309,3 +299,2 @@ const numericalProperties = [

static createTree(payloads) {
/** @type {!Map<string, !AXNode>} */
const nodeById = new Map();

@@ -315,4 +304,4 @@ for (const payload of payloads)

for (const node of nodeById.values()) {
for (const childId of node._payload.childIds || [])
node._children.push(nodeById.get(childId));
for (const childId of node.payload.childIds || [])
node.children.push(nodeById.get(childId));
}

@@ -319,0 +308,0 @@ return nodeById.values().next().value;

@@ -26,3 +26,3 @@ /**

CDPSession: require('./Connection').CDPSession,
ConsoleMessage: require('./Page').ConsoleMessage,
ConsoleMessage: require('./ConsoleMessage').ConsoleMessage,
Coverage: require('./Coverage').Coverage,

@@ -32,3 +32,3 @@ Dialog: require('./Dialog').Dialog,

ExecutionContext: require('./ExecutionContext').ExecutionContext,
FileChooser: require('./Page').FileChooser,
FileChooser: require('./FileChooser').FileChooser,
Frame: require('./FrameManager').Frame,

@@ -40,5 +40,5 @@ JSHandle: require('./JSHandle').JSHandle,

Puppeteer: require('./Puppeteer').Puppeteer,
Request: require('./NetworkManager').Request,
Response: require('./NetworkManager').Response,
SecurityDetails: require('./NetworkManager').SecurityDetails,
Request: require('./Request').Request,
Response: require('./Response').Response,
SecurityDetails: require('./SecurityDetails').SecurityDetails,
Target: require('./Target').Target,

@@ -45,0 +45,0 @@ TimeoutError: require('./Errors').TimeoutError,

@@ -18,6 +18,6 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.BrowserContext = exports.Browser = void 0;
const helper_1 = require("./helper");
const Target_1 = require("./Target");
const EventEmitter = require("events");
const TaskQueue_1 = require("./TaskQueue");
const Events_1 = require("./Events");

@@ -27,7 +27,5 @@ class Browser extends EventEmitter {

super();
this._screenshotTaskQueue = new TaskQueue_1.TaskQueue();
this._ignoreHTTPSErrors = ignoreHTTPSErrors;
this._defaultViewport = defaultViewport;
this._process = process;
this._screenshotTaskQueue = new TaskQueue_1.TaskQueue();
this._connection = connection;

@@ -66,6 +64,8 @@ this._closeCallback = closeCallback || function () { };

/**
* @param {?string} contextId
*/
* @param {?string} contextId
*/
async _disposeContext(contextId) {
await this._connection.send('Target.disposeBrowserContext', { browserContextId: contextId || undefined });
await this._connection.send('Target.disposeBrowserContext', {
browserContextId: contextId || undefined,
});
this._contexts.delete(contextId);

@@ -76,4 +76,6 @@ }

const { browserContextId } = targetInfo;
const context = (browserContextId && this._contexts.has(browserContextId)) ? this._contexts.get(browserContextId) : this._defaultContext;
const target = new Target_1.Target(targetInfo, context, () => this._connection.createSession(targetInfo), this._ignoreHTTPSErrors, this._defaultViewport, this._screenshotTaskQueue);
const context = browserContextId && this._contexts.has(browserContextId)
? this._contexts.get(browserContextId)
: this._defaultContext;
const target = new Target_1.Target(targetInfo, context, () => this._connection.createSession(targetInfo), this._ignoreHTTPSErrors, this._defaultViewport);
helper_1.assert(!this._targets.has(event.targetInfo.targetId), 'Target should not exist before targetCreated');

@@ -87,4 +89,4 @@ this._targets.set(event.targetInfo.targetId, target);

/**
* @param {{targetId: string}} event
*/
* @param {{targetId: string}} event
*/
async _targetDestroyed(event) {

@@ -97,8 +99,10 @@ const target = this._targets.get(event.targetId);

this.emit(Events_1.Events.Browser.TargetDestroyed, target);
target.browserContext().emit(Events_1.Events.BrowserContext.TargetDestroyed, target);
target
.browserContext()
.emit(Events_1.Events.BrowserContext.TargetDestroyed, target);
}
}
/**
* @param {!Protocol.Target.targetInfoChangedPayload} event
*/
* @param {!Protocol.Target.targetInfoChangedPayload} event
*/
_targetInfoChanged(event) {

@@ -122,3 +126,6 @@ const target = this._targets.get(event.targetInfo.targetId);

async _createPageInContext(contextId) {
const { targetId } = await this._connection.send('Target.createTarget', { url: 'about:blank', browserContextId: contextId || undefined });
const { targetId } = await this._connection.send('Target.createTarget', {
url: 'about:blank',
browserContextId: contextId || undefined,
});
const target = await this._targets.get(targetId);

@@ -130,12 +137,12 @@ helper_1.assert(await target._initializedPromise, 'Failed to create target for page');

targets() {
return Array.from(this._targets.values()).filter(target => target._isInitialized);
return Array.from(this._targets.values()).filter((target) => target._isInitialized);
}
target() {
return this.targets().find(target => target.type() === 'browser');
return this.targets().find((target) => target.type() === 'browser');
}
/**
* @param {function(!Target):boolean} predicate
* @param {{timeout?: number}=} options
* @return {!Promise<!Target>}
*/
* @param {function(!Target):boolean} predicate
* @param {{timeout?: number}=} options
* @return {!Promise<!Target>}
*/
async waitForTarget(predicate, options = {}) {

@@ -147,3 +154,3 @@ const { timeout = 30000 } = options;

let resolve;
const targetPromise = new Promise(x => resolve = x);
const targetPromise = new Promise((x) => (resolve = x));
this.on(Events_1.Events.Browser.TargetCreated, check);

@@ -166,3 +173,3 @@ this.on(Events_1.Events.Browser.TargetChanged, check);

async pages() {
const contextPages = await Promise.all(this.browserContexts().map(context => context.pages()));
const contextPages = await Promise.all(this.browserContexts().map((context) => context.pages()));
// Flatten array.

@@ -202,12 +209,14 @@ return contextPages.reduce((acc, x) => acc.concat(x), []);

targets() {
return this._browser.targets().filter(target => target.browserContext() === this);
return this._browser
.targets()
.filter((target) => target.browserContext() === this);
}
waitForTarget(predicate, options) {
return this._browser.waitForTarget(target => target.browserContext() === this && predicate(target), options);
return this._browser.waitForTarget((target) => target.browserContext() === this && predicate(target), options);
}
async pages() {
const pages = await Promise.all(this.targets()
.filter(target => target.type() === 'page')
.map(target => target.page()));
return pages.filter(page => !!page);
.filter((target) => target.type() === 'page')
.map((target) => target.page()));
return pages.filter((page) => !!page);
}

@@ -238,3 +247,3 @@ isIncognito() {

]);
permissions = permissions.map(permission => {
permissions = permissions.map((permission) => {
const protocolPermission = webPermissionToProtocol.get(permission);

@@ -245,6 +254,12 @@ if (!protocolPermission)

});
await this._connection.send('Browser.grantPermissions', { origin, browserContextId: this._id || undefined, permissions });
await this._connection.send('Browser.grantPermissions', {
origin,
browserContextId: this._id || undefined,
permissions,
});
}
async clearPermissionOverrides() {
await this._connection.send('Browser.resetPermissions', { browserContextId: this._id || undefined });
await this._connection.send('Browser.resetPermissions', {
browserContextId: this._id || undefined,
});
}

@@ -251,0 +266,0 @@ newPage() {

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.BrowserFetcher = void 0;
const os = require("os");

@@ -42,6 +43,6 @@ const fs = require("fs");

firefox: {
linux: '%s/firefox-%s.0a1.en-US.%s-x86_64.tar.bz2',
mac: '%s/firefox-%s.0a1.en-US.%s.dmg',
win32: '%s/firefox-%s.0a1.en-US.%s.zip',
win64: '%s/firefox-%s.0a1.en-US.%s.zip',
linux: '%s/firefox-%s.en-US.%s-x86_64.tar.bz2',
mac: '%s/firefox-%s.en-US.%s.dmg',
win32: '%s/firefox-%s.en-US.%s.zip',
win64: '%s/firefox-%s.en-US.%s.zip',
},

@@ -57,3 +58,3 @@ };

destination: '.local-firefox',
}
},
};

@@ -91,4 +92,4 @@ function archiveName(product, platform, revision) {

function existsAsync(filePath) {
return new Promise(resolve => {
fs.access(filePath, err => resolve(!err));
return new Promise((resolve) => {
fs.access(filePath, (err) => resolve(!err));
});

@@ -102,3 +103,5 @@ }

helper_1.assert(this._product === 'chrome' || this._product === 'firefox', `Unknown product: "${options.product}"`);
this._downloadsFolder = options.path || path.join(projectRoot, browserConfig[this._product].destination);
this._downloadsFolder =
options.path ||
path.join(projectRoot, browserConfig[this._product].destination);
this._downloadHost = options.host || browserConfig[this._product].host;

@@ -134,7 +137,7 @@ this.setPlatform(options.platform);

const url = downloadURL(this._product, this._platform, this._downloadHost, revision);
return new Promise(resolve => {
const request = httpRequest(url, 'HEAD', response => {
return new Promise((resolve) => {
const request = httpRequest(url, 'HEAD', (response) => {
resolve(response.statusCode === 200);
});
request.on('error', error => {
request.on('error', (error) => {
console.error(error);

@@ -173,6 +176,9 @@ resolve(false);

async localRevisions() {
if (!await existsAsync(this._downloadsFolder))
if (!(await existsAsync(this._downloadsFolder)))
return [];
const fileNames = await readdirAsync(this._downloadsFolder);
return fileNames.map(fileName => parseFolderPath(this._product, fileName)).filter(entry => entry && entry.platform === this._platform).map(entry => entry.revision);
return fileNames
.map((fileName) => parseFolderPath(this._product, fileName))
.filter((entry) => entry && entry.platform === this._platform)
.map((entry) => entry.revision);
}

@@ -182,3 +188,3 @@ async remove(revision) {

helper_1.assert(await existsAsync(folderPath), `Failed to remove: revision ${revision} is not downloaded`);
await new Promise(fulfill => removeRecursive(folderPath, fulfill));
await new Promise((fulfill) => removeRecursive(folderPath, fulfill));
}

@@ -213,4 +219,18 @@ revisionInfo(revision) {

const local = fs.existsSync(folderPath);
debugFetcher({ revision, executablePath, folderPath, local, url, product: this._product });
return { revision, executablePath, folderPath, local, url, product: this._product };
debugFetcher({
revision,
executablePath,
folderPath,
local,
url,
product: this._product,
});
return {
revision,
executablePath,
folderPath,
local,
url,
product: this._product,
};
}

@@ -247,4 +267,7 @@ /**

let totalBytes = 0;
const promise = new Promise((x, y) => { fulfill = x; reject = y; });
const request = httpRequest(url, 'GET', response => {
const promise = new Promise((x, y) => {
fulfill = x;
reject = y;
});
const request = httpRequest(url, 'GET', (response) => {
if (response.statusCode !== 200) {

@@ -259,9 +282,10 @@ const error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);

file.on('finish', () => fulfill());
file.on('error', error => reject(error));
file.on('error', (error) => reject(error));
response.pipe(file);
totalBytes = parseInt(/** @type {string} */ (response.headers['content-length']), 10);
totalBytes = parseInt(
/** @type {string} */ response.headers['content-length'], 10);
if (progressCallback)
response.on('data', onData);
});
request.on('error', error => reject(error));
request.on('error', (error) => reject(error));
return promise;

@@ -299,3 +323,5 @@ function onData(chunk) {

const readStream = fs.createReadStream(tarPath);
readStream.on('data', () => { process.stdout.write('\rExtracting...'); });
readStream.on('data', () => {
process.stdout.write('\rExtracting...');
});
readStream.pipe(bzip()).pipe(tarStream);

@@ -322,4 +348,5 @@ });

mountPath = volumes[0];
readdirAsync(mountPath).then(fileNames => {
const appName = fileNames.filter(item => typeof item === 'string' && item.endsWith('.app'))[0];
readdirAsync(mountPath)
.then((fileNames) => {
const appName = fileNames.filter((item) => typeof item === 'string' && item.endsWith('.app'))[0];
if (!appName)

@@ -329,3 +356,3 @@ return reject(new Error(`Cannot find app in ${mountPath}`));

debugFetcher(`Copying ${copyPath} to ${folderPath}`);
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, err => {
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, (err) => {
if (err)

@@ -336,3 +363,4 @@ reject(err);

});
}).catch(reject);
})
.catch(reject);
});

@@ -345,3 +373,3 @@ }

debugFetcher(`Unmounting ${mountPath}`);
childProcess.exec(unmountCommand, err => {
childProcess.exec(unmountCommand, (err) => {
if (err)

@@ -351,3 +379,7 @@ console.error(`Error unmounting dmg: ${err}`);

}
return new Promise(mountAndCopy).catch(error => { console.error(error); }).finally(unmount);
return new Promise(mountAndCopy)
.catch((error) => {
console.error(error);
})
.finally(unmount);
}

@@ -386,7 +418,7 @@ function httpRequest(url, method, response) {

};
const request = options.protocol === 'https:' ?
https.request(options, requestCallback) :
http.request(options, requestCallback);
const request = options.protocol === 'https:'
? https.request(options, requestCallback)
: http.request(options, requestCallback);
request.end();
return request;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CDPSession = exports.Connection = void 0;
/**

@@ -64,3 +65,3 @@ * Copyright 2017 Google Inc. All rights reserved.

if (this._delay)
await new Promise(f => setTimeout(f, this._delay));
await new Promise((f) => setTimeout(f, this._delay));
debugProtocol('◀ RECV ' + message);

@@ -123,3 +124,6 @@ const object = JSON.parse(message);

async createSession(targetInfo) {
const { sessionId } = await this.send('Target.attachToTarget', { targetId: targetInfo.targetId, flatten: true });
const { sessionId } = await this.send('Target.attachToTarget', {
targetId: targetInfo.targetId,
flatten: true,
});
return this._sessions.get(sessionId);

@@ -147,3 +151,3 @@ }

*/
params: params || {}
params: params || {},
});

@@ -171,3 +175,5 @@ return new Promise((resolve, reject) => {

throw new Error(`Session already detached. Most likely the ${this._targetType} has been closed.`);
await this._connection.send('Target.detachFromTarget', { sessionId: this._sessionId });
await this._connection.send('Target.detachFromTarget', {
sessionId: this._sessionId,
});
}

@@ -174,0 +180,0 @@ _onClosed() {

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Coverage = void 0;
const helper_1 = require("./helper");

@@ -52,3 +53,3 @@ const ExecutionContext_1 = require("./ExecutionContext");

helper_1.assert(!this._enabled, 'JSCoverage is already enabled');
const { resetOnNavigation = true, reportAnonymousScripts = false } = options;
const { resetOnNavigation = true, reportAnonymousScripts = false, } = options;
this._resetOnNavigation = resetOnNavigation;

@@ -65,5 +66,8 @@ this._reportAnonymousScripts = reportAnonymousScripts;

this._client.send('Profiler.enable'),
this._client.send('Profiler.startPreciseCoverage', { callCount: false, detailed: true }),
this._client.send('Profiler.startPreciseCoverage', {
callCount: false,
detailed: true,
}),
this._client.send('Debugger.enable'),
this._client.send('Debugger.setSkipAllPauses', { skip: true })
this._client.send('Debugger.setSkipAllPauses', { skip: true }),
]);

@@ -85,3 +89,5 @@ }

try {
const response = await this._client.send('Debugger.getScriptSource', { scriptId: event.scriptId });
const response = await this._client.send('Debugger.getScriptSource', {
scriptId: event.scriptId,
});
this._scriptURLs.set(event.scriptId, event.url);

@@ -162,3 +168,5 @@ this._scriptSources.set(event.scriptId, response.scriptSource);

try {
const response = await this._client.send('CSS.getStyleSheetText', { styleSheetId: header.styleSheetId });
const response = await this._client.send('CSS.getStyleSheetText', {
styleSheetId: header.styleSheetId,
});
this._stylesheetURLs.set(header.styleSheetId, header.sourceURL);

@@ -232,3 +240,5 @@ this._stylesheetSources.set(header.styleSheetId, response.text);

for (const point of points) {
if (hitCountStack.length && lastOffset < point.offset && hitCountStack[hitCountStack.length - 1] > 0) {
if (hitCountStack.length &&
lastOffset < point.offset &&
hitCountStack[hitCountStack.length - 1] > 0) {
const lastResult = results.length ? results[results.length - 1] : null;

@@ -247,3 +257,3 @@ if (lastResult && lastResult.end === lastOffset)

// Filter out empty ranges.
return results.filter(range => range.end - range.start > 1);
return results.filter((range) => range.end - range.start > 1);
}

@@ -18,855 +18,856 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.devicesMap = void 0;
const devices = [
{
'name': 'Blackberry PlayBook',
'userAgent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
'viewport': {
'width': 600,
'height': 1024,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Blackberry PlayBook',
userAgent: 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
viewport: {
width: 600,
height: 1024,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Blackberry PlayBook landscape',
'userAgent': 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
'viewport': {
'width': 1024,
'height': 600,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Blackberry PlayBook landscape',
userAgent: 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+',
viewport: {
width: 1024,
height: 600,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'BlackBerry Z30',
'userAgent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'BlackBerry Z30',
userAgent: 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'BlackBerry Z30 landscape',
'userAgent': 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'BlackBerry Z30 landscape',
userAgent: 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Galaxy Note 3',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Galaxy Note 3',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Galaxy Note 3 landscape',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Galaxy Note 3 landscape',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Galaxy Note II',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Galaxy Note II',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Galaxy Note II landscape',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Galaxy Note II landscape',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Galaxy S III',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Galaxy S III',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Galaxy S III landscape',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Galaxy S III landscape',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Galaxy S5',
'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Galaxy S5',
userAgent: 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Galaxy S5 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Galaxy S5 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPad',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 768,
'height': 1024,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPad',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 768,
height: 1024,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPad landscape',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 1024,
'height': 768,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPad landscape',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 1024,
height: 768,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPad Mini',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 768,
'height': 1024,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPad Mini',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 768,
height: 1024,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPad Mini landscape',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 1024,
'height': 768,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPad Mini landscape',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 1024,
height: 768,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPad Pro',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 1024,
'height': 1366,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPad Pro',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 1024,
height: 1366,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPad Pro landscape',
'userAgent': 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
'viewport': {
'width': 1366,
'height': 1024,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPad Pro landscape',
userAgent: 'Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1',
viewport: {
width: 1366,
height: 1024,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 4',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53',
'viewport': {
'width': 320,
'height': 480,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 4',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53',
viewport: {
width: 320,
height: 480,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 4 landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53',
'viewport': {
'width': 480,
'height': 320,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 4 landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53',
viewport: {
width: 480,
height: 320,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 5',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
'viewport': {
'width': 320,
'height': 568,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 5',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
viewport: {
width: 320,
height: 568,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 5 landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
'viewport': {
'width': 568,
'height': 320,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 5 landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
viewport: {
width: 568,
height: 320,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 6',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 375,
'height': 667,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 6',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 375,
height: 667,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 6 landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 667,
'height': 375,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 6 landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 667,
height: 375,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 6 Plus',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 414,
'height': 736,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 6 Plus',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 414,
height: 736,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 6 Plus landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 736,
'height': 414,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 6 Plus landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 736,
height: 414,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 7',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 375,
'height': 667,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 7',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 375,
height: 667,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 7 landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 667,
'height': 375,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 7 landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 667,
height: 375,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 7 Plus',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 414,
'height': 736,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 7 Plus',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 414,
height: 736,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 7 Plus landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 736,
'height': 414,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 7 Plus landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 736,
height: 414,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 8',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 375,
'height': 667,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 8',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 375,
height: 667,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 8 landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 667,
'height': 375,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 8 landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 667,
height: 375,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone 8 Plus',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 414,
'height': 736,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone 8 Plus',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 414,
height: 736,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone 8 Plus landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 736,
'height': 414,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone 8 Plus landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 736,
height: 414,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone SE',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
'viewport': {
'width': 320,
'height': 568,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone SE',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
viewport: {
width: 320,
height: 568,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone SE landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
'viewport': {
'width': 568,
'height': 320,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone SE landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
viewport: {
width: 568,
height: 320,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone X',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 375,
'height': 812,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone X',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 375,
height: 812,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone X landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
'viewport': {
'width': 812,
'height': 375,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone X landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
viewport: {
width: 812,
height: 375,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'iPhone XR',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1',
'viewport': {
'width': 414,
'height': 896,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'iPhone XR',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1',
viewport: {
width: 414,
height: 896,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'iPhone XR landscape',
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1',
'viewport': {
'width': 896,
'height': 414,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'iPhone XR landscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1',
viewport: {
width: 896,
height: 414,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'JioPhone 2',
'userAgent': 'Mozilla/5.0 (Mobile; LYF/F300B/LYF-F300B-001-01-15-130718-i;Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5',
'viewport': {
'width': 240,
'height': 320,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'JioPhone 2',
userAgent: 'Mozilla/5.0 (Mobile; LYF/F300B/LYF-F300B-001-01-15-130718-i;Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5',
viewport: {
width: 240,
height: 320,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'JioPhone 2 landscape',
'userAgent': 'Mozilla/5.0 (Mobile; LYF/F300B/LYF-F300B-001-01-15-130718-i;Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5',
'viewport': {
'width': 320,
'height': 240,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'JioPhone 2 landscape',
userAgent: 'Mozilla/5.0 (Mobile; LYF/F300B/LYF-F300B-001-01-15-130718-i;Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5',
viewport: {
width: 320,
height: 240,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Kindle Fire HDX',
'userAgent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
'viewport': {
'width': 800,
'height': 1280,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Kindle Fire HDX',
userAgent: 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
viewport: {
width: 800,
height: 1280,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Kindle Fire HDX landscape',
'userAgent': 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
'viewport': {
'width': 1280,
'height': 800,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Kindle Fire HDX landscape',
userAgent: 'Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true',
viewport: {
width: 1280,
height: 800,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'LG Optimus L70',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 384,
'height': 640,
'deviceScaleFactor': 1.25,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'LG Optimus L70',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 384,
height: 640,
deviceScaleFactor: 1.25,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'LG Optimus L70 landscape',
'userAgent': 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 640,
'height': 384,
'deviceScaleFactor': 1.25,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'LG Optimus L70 landscape',
userAgent: 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 640,
height: 384,
deviceScaleFactor: 1.25,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Microsoft Lumia 550',
'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Microsoft Lumia 550',
userAgent: 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Microsoft Lumia 950',
'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 4,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Microsoft Lumia 950',
userAgent: 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 4,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Microsoft Lumia 950 landscape',
'userAgent': 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 4,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Microsoft Lumia 950 landscape',
userAgent: 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 4,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 10',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
'viewport': {
'width': 800,
'height': 1280,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 10',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
viewport: {
width: 800,
height: 1280,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 10 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
'viewport': {
'width': 1280,
'height': 800,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 10 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
viewport: {
width: 1280,
height: 800,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 4',
'userAgent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 384,
'height': 640,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 4',
userAgent: 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 384,
height: 640,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 4 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 640,
'height': 384,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 4 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 640,
height: 384,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 5',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 360,
'height': 640,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 5',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 360,
height: 640,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 5 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 640,
'height': 360,
'deviceScaleFactor': 3,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 5 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 640,
height: 360,
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 5X',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 412,
'height': 732,
'deviceScaleFactor': 2.625,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 5X',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 412,
height: 732,
deviceScaleFactor: 2.625,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 5X landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 732,
'height': 412,
'deviceScaleFactor': 2.625,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 5X landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 732,
height: 412,
deviceScaleFactor: 2.625,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 6',
'userAgent': 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 412,
'height': 732,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 6',
userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 412,
height: 732,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 6 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 732,
'height': 412,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 6 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 732,
height: 412,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 6P',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 412,
'height': 732,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 6P',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 412,
height: 732,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 6P landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 732,
'height': 412,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 6P landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 732,
height: 412,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nexus 7',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
'viewport': {
'width': 600,
'height': 960,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nexus 7',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
viewport: {
width: 600,
height: 960,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nexus 7 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
'viewport': {
'width': 960,
'height': 600,
'deviceScaleFactor': 2,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nexus 7 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Safari/537.36',
viewport: {
width: 960,
height: 600,
deviceScaleFactor: 2,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nokia Lumia 520',
'userAgent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
'viewport': {
'width': 320,
'height': 533,
'deviceScaleFactor': 1.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nokia Lumia 520',
userAgent: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
viewport: {
width: 320,
height: 533,
deviceScaleFactor: 1.5,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nokia Lumia 520 landscape',
'userAgent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
'viewport': {
'width': 533,
'height': 320,
'deviceScaleFactor': 1.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nokia Lumia 520 landscape',
userAgent: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)',
viewport: {
width: 533,
height: 320,
deviceScaleFactor: 1.5,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Nokia N9',
'userAgent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
'viewport': {
'width': 480,
'height': 854,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Nokia N9',
userAgent: 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
viewport: {
width: 480,
height: 854,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Nokia N9 landscape',
'userAgent': 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
'viewport': {
'width': 854,
'height': 480,
'deviceScaleFactor': 1,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Nokia N9 landscape',
userAgent: 'Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13',
viewport: {
width: 854,
height: 480,
deviceScaleFactor: 1,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Pixel 2',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 411,
'height': 731,
'deviceScaleFactor': 2.625,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Pixel 2',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 411,
height: 731,
deviceScaleFactor: 2.625,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Pixel 2 landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 731,
'height': 411,
'deviceScaleFactor': 2.625,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
name: 'Pixel 2 landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 731,
height: 411,
deviceScaleFactor: 2.625,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
{
'name': 'Pixel 2 XL',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 411,
'height': 823,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': false
}
name: 'Pixel 2 XL',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 411,
height: 823,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: false,
},
},
{
'name': 'Pixel 2 XL landscape',
'userAgent': 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
'viewport': {
'width': 823,
'height': 411,
'deviceScaleFactor': 3.5,
'isMobile': true,
'hasTouch': true,
'isLandscape': true
}
}
name: 'Pixel 2 XL landscape',
userAgent: 'Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3765.0 Mobile Safari/537.36',
viewport: {
width: 823,
height: 411,
deviceScaleFactor: 3.5,
isMobile: true,
hasTouch: true,
isLandscape: true,
},
},
];

@@ -873,0 +874,0 @@ const devicesMap = {};

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Dialog = exports.DialogType = void 0;
const helper_1 = require("./helper");

@@ -30,36 +31,39 @@ /* TODO(jacktfranklin): protocol.d.ts defines this

})(DialogType = exports.DialogType || (exports.DialogType = {}));
class Dialog {
constructor(client, type, message, defaultValue = '') {
this._handled = false;
this._client = client;
this._type = type;
this._message = message;
this._defaultValue = defaultValue;
let Dialog = /** @class */ (() => {
class Dialog {
constructor(client, type, message, defaultValue = '') {
this._handled = false;
this._client = client;
this._type = type;
this._message = message;
this._defaultValue = defaultValue;
}
type() {
return this._type;
}
message() {
return this._message;
}
defaultValue() {
return this._defaultValue;
}
async accept(promptText) {
helper_1.assert(!this._handled, 'Cannot accept dialog which is already handled!');
this._handled = true;
await this._client.send('Page.handleJavaScriptDialog', {
accept: true,
promptText: promptText,
});
}
async dismiss() {
helper_1.assert(!this._handled, 'Cannot dismiss dialog which is already handled!');
this._handled = true;
await this._client.send('Page.handleJavaScriptDialog', {
accept: false,
});
}
}
type() {
return this._type;
}
message() {
return this._message;
}
defaultValue() {
return this._defaultValue;
}
async accept(promptText) {
helper_1.assert(!this._handled, 'Cannot accept dialog which is already handled!');
this._handled = true;
await this._client.send('Page.handleJavaScriptDialog', {
accept: true,
promptText: promptText
});
}
async dismiss() {
helper_1.assert(!this._handled, 'Cannot dismiss dialog which is already handled!');
this._handled = true;
await this._client.send('Page.handleJavaScriptDialog', {
accept: false
});
}
}
Dialog.Type = DialogType;
return Dialog;
})();
exports.Dialog = Dialog;
Dialog.Type = DialogType;

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.DOMWorld = void 0;
const fs = require("fs");

@@ -52,3 +53,3 @@ const helper_1 = require("./helper");

this._documentPromise = null;
this._contextPromise = new Promise(fulfill => {
this._contextPromise = new Promise((fulfill) => {
this._contextResolveCallback = fulfill;

@@ -147,3 +148,3 @@ });

// lifecycle event. @see https://crrev.com/608658
await this.evaluate(html => {
await this.evaluate((html) => {
document.open();

@@ -206,3 +207,3 @@ document.write(html);

let error = null;
script.onerror = e => error = e;
script.onerror = (e) => (error = e);
document.head.appendChild(script);

@@ -315,3 +316,3 @@ if (error)

const title = `${isXPath ? 'XPath' : 'selector'} "${selectorOrXPath}"${waitForHidden ? ' to be hidden' : ''}`;
const { updatedSelector, queryHandler } = QueryHandler_1.getQueryHandlerAndSelector(selectorOrXPath, (element, selector) => document.querySelector(selector));
const { updatedSelector, queryHandler, } = QueryHandler_1.getQueryHandlerAndSelector(selectorOrXPath, (element, selector) => document.querySelector(selector));
const waitTask = new WaitTask(this, predicate, queryHandler, title, polling, timeout, updatedSelector, isXPath, waitForVisible, waitForHidden);

@@ -334,3 +335,5 @@ const handle = await waitTask.promise;

? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
: predicateQueryHandler ? predicateQueryHandler(document, selectorOrXPath) : document.querySelector(selectorOrXPath);
: predicateQueryHandler
? predicateQueryHandler(document, selectorOrXPath)
: document.querySelector(selectorOrXPath);
if (!node)

@@ -340,6 +343,8 @@ return waitForHidden;

return node;
const element = (node.nodeType === Node.TEXT_NODE ? node.parentElement : node);
const element = node.nodeType === Node.TEXT_NODE
? node.parentElement
: node;
const style = window.getComputedStyle(element);
const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox();
const success = (waitForVisible === isVisible || waitForHidden === !isVisible);
const success = waitForVisible === isVisible || waitForHidden === !isVisible;
return success ? node : null;

@@ -419,3 +424,4 @@ function hasVisibleBoundingBox() {

// throw an error - ignore this predicate run altogether.
if (!error && await this._domWorld.evaluate(s => !s, success).catch(() => true)) {
if (!error &&
(await this._domWorld.evaluate((s) => !s, success).catch(() => true))) {
await success.dispose();

@@ -430,3 +436,4 @@ return;

// destroyed.
if (error && error.message.includes('Cannot find context with specified id'))
if (error &&
error.message.includes('Cannot find context with specified id'))
return;

@@ -448,3 +455,3 @@ if (error)

if (timeout)
setTimeout(() => timedOut = true, timeout);
setTimeout(() => (timedOut = true), timeout);
if (polling === 'raf')

@@ -464,3 +471,3 @@ return await pollRaf();

let fulfill;
const result = new Promise(x => fulfill = x);
const result = new Promise((x) => (fulfill = x));
const observer = new MutationObserver(() => {

@@ -480,3 +487,3 @@ if (timedOut) {

subtree: true,
attributes: true
attributes: true,
});

@@ -487,3 +494,3 @@ return result;

let fulfill;
const result = new Promise(x => fulfill = x);
const result = new Promise((x) => (fulfill = x));
onRaf();

@@ -505,3 +512,3 @@ return result;

let fulfill;
const result = new Promise(x => fulfill = x);
const result = new Promise((x) => (fulfill = x));
onTimeout();

@@ -508,0 +515,0 @@ return result;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EmulationManager = void 0;
class EmulationManager {

@@ -14,9 +15,17 @@ constructor(client) {

const deviceScaleFactor = viewport.deviceScaleFactor || 1;
const screenOrientation = viewport.isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' };
const screenOrientation = viewport.isLandscape
? { angle: 90, type: 'landscapePrimary' }
: { angle: 0, type: 'portraitPrimary' };
const hasTouch = viewport.hasTouch || false;
await Promise.all([
this._client.send('Emulation.setDeviceMetricsOverride', { mobile, width, height, deviceScaleFactor, screenOrientation }),
this._client.send('Emulation.setDeviceMetricsOverride', {
mobile,
width,
height,
deviceScaleFactor,
screenOrientation,
}),
this._client.send('Emulation.setTouchEmulationEnabled', {
enabled: hasTouch
})
enabled: hasTouch,
}),
]);

@@ -23,0 +32,0 @@ const reloadNeeded = this._emulatingMobile !== mobile || this._hasTouch !== hasTouch;

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.puppeteerErrors = exports.TimeoutError = void 0;
class CustomError extends Error {

@@ -20,0 +21,0 @@ constructor(message) {

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Events = void 0;
exports.Events = {

@@ -46,3 +47,3 @@ Page: {

TargetChanged: 'targetchanged',
Disconnected: 'disconnected'
Disconnected: 'disconnected',
},

@@ -49,0 +50,0 @@ BrowserContext: {

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.ExecutionContext = exports.EVALUATION_SCRIPT_URL = void 0;
const helper_1 = require("./helper");

@@ -43,4 +44,7 @@ const JSHandle_1 = require("./JSHandle");

const expression = pageFunction;
const expressionWithSourceUrl = SOURCE_URL_REGEX.test(expression) ? expression : expression + '\n' + suffix;
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', {
const expressionWithSourceUrl = SOURCE_URL_REGEX.test(expression)
? expression
: expression + '\n' + suffix;
const { exceptionDetails, result: remoteObject } = await this._client
.send('Runtime.evaluate', {
expression: expressionWithSourceUrl,

@@ -50,7 +54,10 @@ contextId,

awaitPromise: true,
userGesture: true
}).catch(rewriteError);
userGesture: true,
})
.catch(rewriteError);
if (exceptionDetails)
throw new Error('Evaluation failed: ' + helper_1.helper.getExceptionMessage(exceptionDetails));
return returnByValue ? helper_1.helper.valueFromRemoteObject(remoteObject) : JSHandle_1.createJSHandle(this, remoteObject);
return returnByValue
? helper_1.helper.valueFromRemoteObject(remoteObject)
: JSHandle_1.createJSHandle(this, remoteObject);
}

@@ -67,3 +74,4 @@ if (typeof pageFunction !== 'function')

if (functionText.startsWith('async '))
functionText = 'async function ' + functionText.substring('async '.length);
functionText =
'async function ' + functionText.substring('async '.length);
else

@@ -87,14 +95,17 @@ functionText = 'function ' + functionText;

awaitPromise: true,
userGesture: true
userGesture: true,
});
}
catch (error) {
if (error instanceof TypeError && error.message.startsWith('Converting circular structure to JSON'))
if (error instanceof TypeError &&
error.message.startsWith('Converting circular structure to JSON'))
error.message += ' Are you passing a nested JSHandle?';
throw error;
}
const { exceptionDetails, result: remoteObject } = await callFunctionOnPromise.catch(rewriteError);
const { exceptionDetails, result: remoteObject, } = await callFunctionOnPromise.catch(rewriteError);
if (exceptionDetails)
throw new Error('Evaluation failed: ' + helper_1.helper.getExceptionMessage(exceptionDetails));
return returnByValue ? helper_1.helper.valueFromRemoteObject(remoteObject) : JSHandle_1.createJSHandle(this, remoteObject);
return returnByValue
? helper_1.helper.valueFromRemoteObject(remoteObject)
: JSHandle_1.createJSHandle(this, remoteObject);
/**

@@ -106,3 +117,4 @@ * @param {*} arg

function convertArgument(arg) {
if (typeof arg === 'bigint') // eslint-disable-line valid-typeof
if (typeof arg === 'bigint')
// eslint-disable-line valid-typeof
return { unserializableValue: `${arg.toString()}n` };

@@ -117,3 +129,3 @@ if (Object.is(arg, -0))

return { unserializableValue: 'NaN' };
const objectHandle = arg && (arg instanceof JSHandle_1.JSHandle) ? arg : null;
const objectHandle = arg && arg instanceof JSHandle_1.JSHandle ? arg : null;
if (objectHandle) {

@@ -125,3 +137,5 @@ if (objectHandle._context !== this)

if (objectHandle._remoteObject.unserializableValue)
return { unserializableValue: objectHandle._remoteObject.unserializableValue };
return {
unserializableValue: objectHandle._remoteObject.unserializableValue,
};
if (!objectHandle._remoteObject.objectId)

@@ -136,5 +150,6 @@ return { value: objectHandle._remoteObject.value };

return { result: { type: 'undefined' } };
if (error.message.includes('Object couldn\'t be returned by value'))
if (error.message.includes("Object couldn't be returned by value"))
return { result: { type: 'undefined' } };
if (error.message.endsWith('Cannot find context with specified id') || error.message.endsWith('Inspected target navigated or closed'))
if (error.message.endsWith('Cannot find context with specified id') ||
error.message.endsWith('Inspected target navigated or closed'))
throw new Error('Execution context was destroyed, most likely because of a navigation.');

@@ -148,3 +163,3 @@ throw error;

const response = await this._client.send('Runtime.queryObjects', {
prototypeObjectId: prototypeHandle._remoteObject.objectId
prototypeObjectId: prototypeHandle._remoteObject.objectId,
});

@@ -151,0 +166,0 @@ return JSHandle_1.createJSHandle(this, response.objects);

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Frame = exports.FrameManager = void 0;
const EventEmitter = require("events");

@@ -37,11 +38,11 @@ const helper_1 = require("./helper");

this._timeoutSettings = timeoutSettings;
this._client.on('Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId));
this._client.on('Page.frameNavigated', event => this._onFrameNavigated(event.frame));
this._client.on('Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url));
this._client.on('Page.frameDetached', event => this._onFrameDetached(event.frameId));
this._client.on('Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId));
this._client.on('Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context));
this._client.on('Runtime.executionContextDestroyed', event => this._onExecutionContextDestroyed(event.executionContextId));
this._client.on('Page.frameAttached', (event) => this._onFrameAttached(event.frameId, event.parentFrameId));
this._client.on('Page.frameNavigated', (event) => this._onFrameNavigated(event.frame));
this._client.on('Page.navigatedWithinDocument', (event) => this._onFrameNavigatedWithinDocument(event.frameId, event.url));
this._client.on('Page.frameDetached', (event) => this._onFrameDetached(event.frameId));
this._client.on('Page.frameStoppedLoading', (event) => this._onFrameStoppedLoading(event.frameId));
this._client.on('Runtime.executionContextCreated', (event) => this._onExecutionContextCreated(event.context));
this._client.on('Runtime.executionContextDestroyed', (event) => this._onExecutionContextDestroyed(event.executionContextId));
this._client.on('Runtime.executionContextsCleared', () => this._onExecutionContextsCleared());
this._client.on('Page.lifecycleEvent', event => this._onLifecycleEvent(event));
this._client.on('Page.lifecycleEvent', (event) => this._onLifecycleEvent(event));
}

@@ -57,3 +58,5 @@ async initialize() {

this._client.send('Page.setLifecycleEventsEnabled', { enabled: true }),
this._client.send('Runtime.enable', {}).then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
this._client
.send('Runtime.enable', {})
.then(() => this._ensureIsolatedWorld(UTILITY_WORLD_NAME)),
this._networkManager.initialize(),

@@ -77,3 +80,5 @@ ]);

watcher.timeoutOrTerminationPromise(),
ensureNewDocumentNavigation ? watcher.newDocumentNavigationPromise() : watcher.sameDocumentNavigationPromise(),
ensureNewDocumentNavigation
? watcher.newDocumentNavigationPromise()
: watcher.sameDocumentNavigationPromise(),
]);

@@ -87,5 +92,11 @@ }

try {
const response = await client.send('Page.navigate', { url, referrer, frameId });
const response = await client.send('Page.navigate', {
url,
referrer,
frameId,
});
ensureNewDocumentNavigation = !!response.loaderId;
return response.errorText ? new Error(`${response.errorText} at ${url}`) : null;
return response.errorText
? new Error(`${response.errorText} at ${url}`)
: null;
}

@@ -104,3 +115,3 @@ catch (error) {

watcher.sameDocumentNavigationPromise(),
watcher.newDocumentNavigationPromise()
watcher.newDocumentNavigationPromise(),
]);

@@ -158,3 +169,5 @@ watcher.dispose();

const isMainFrame = !framePayload.parentId;
let frame = isMainFrame ? this._mainFrame : this._frames.get(framePayload.id);
let frame = isMainFrame
? this._mainFrame
: this._frames.get(framePayload.id);
helper_1.assert(isMainFrame || frame, 'We either navigate top level or have old version of the navigated frame');

@@ -192,7 +205,9 @@ // Detach all child frames first.

}),
await Promise.all(this.frames().map(frame => this._client.send('Page.createIsolatedWorld', {
await Promise.all(this.frames().map((frame) => this._client
.send('Page.createIsolatedWorld', {
frameId: frame._id,
grantUniveralAccess: true,
worldName: name,
}).catch(helper_1.debugError))); // frames might be removed before we send this
})
.catch(helper_1.debugError))); // frames might be removed before we send this
}

@@ -221,3 +236,4 @@ _onFrameNavigatedWithinDocument(frameId, url) {

}
else if (contextPayload.name === UTILITY_WORLD_NAME && !frame._secondaryWorld._hasContext()) {
else if (contextPayload.name === UTILITY_WORLD_NAME &&
!frame._secondaryWorld._hasContext()) {
// In case of multiple sessions to the same target, there's a race between

@@ -371,6 +387,6 @@ // connections so we might end up creating multiple isolated worlds.

if (helper_1.helper.isNumber(selectorOrFunctionOrTimeout))
return new Promise(fulfill => setTimeout(fulfill, selectorOrFunctionOrTimeout));
return new Promise((fulfill) => setTimeout(fulfill, selectorOrFunctionOrTimeout));
if (typeof selectorOrFunctionOrTimeout === 'function')
return this.waitForFunction(selectorOrFunctionOrTimeout, options, ...args);
return Promise.reject(new Error('Unsupported target type: ' + (typeof selectorOrFunctionOrTimeout)));
return Promise.reject(new Error('Unsupported target type: ' + typeof selectorOrFunctionOrTimeout));
}

@@ -377,0 +393,0 @@ async waitForSelector(selector, options) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.helper = exports.assert = exports.debugError = void 0;
/**

@@ -33,7 +34,11 @@ * Copyright 2017 Google Inc. All rights reserved.

if (exceptionDetails.exception)
return exceptionDetails.exception.description || exceptionDetails.exception.value;
return (exceptionDetails.exception.description || exceptionDetails.exception.value);
let message = exceptionDetails.text;
if (exceptionDetails.stackTrace) {
for (const callframe of exceptionDetails.stackTrace.callFrames) {
const location = callframe.url + ':' + callframe.lineNumber + ':' + callframe.columnNumber;
const location = callframe.url +
':' +
callframe.lineNumber +
':' +
callframe.columnNumber;
const functionName = callframe.functionName || '<anonymous>';

@@ -60,3 +65,4 @@ message += `\n at ${functionName} (${location})`;

default:
throw new Error('Unsupported unserializable value: ' + remoteObject.unserializableValue);
throw new Error('Unsupported unserializable value: ' +
remoteObject.unserializableValue);
}

@@ -69,3 +75,5 @@ }

return;
await client.send('Runtime.releaseObject', { objectId: remoteObject.objectId }).catch(error => {
await client
.send('Runtime.releaseObject', { objectId: remoteObject.objectId })
.catch((error) => {
// Exceptions might happen in case of a page been navigated or closed.

@@ -79,13 +87,19 @@ // Swallow these since they are harmless and we don't leak anything in this case.

const method = Reflect.get(classType.prototype, methodName);
if (methodName === 'constructor' || typeof methodName !== 'string' || methodName.startsWith('_') || typeof method !== 'function' || method.constructor.name !== 'AsyncFunction')
if (methodName === 'constructor' ||
typeof methodName !== 'string' ||
methodName.startsWith('_') ||
typeof method !== 'function' ||
method.constructor.name !== 'AsyncFunction')
continue;
Reflect.set(classType.prototype, methodName, function (...args) {
const syncStack = {
stack: ''
stack: '',
};
Error.captureStackTrace(syncStack);
return method.call(this, ...args).catch(error => {
return method.call(this, ...args).catch((error) => {
const stack = syncStack.stack.substring(syncStack.stack.indexOf('\n') + 1);
const clientStack = stack.substring(stack.indexOf('\n'));
if (error instanceof Error && error.stack && !error.stack.includes(clientStack))
if (error instanceof Error &&
error.stack &&
!error.stack.includes(clientStack))
error.stack += '\n -- ASYNC --\n' + stack;

@@ -118,3 +132,3 @@ throw error;

});
const listener = addEventListener(emitter, eventName, event => {
const listener = addEventListener(emitter, eventName, (event) => {
if (!predicate(event))

@@ -133,6 +147,6 @@ return;

}
const result = await Promise.race([promise, abortPromise]).then(r => {
const result = await Promise.race([promise, abortPromise]).then((r) => {
cleanup();
return r;
}, error => {
}, (error) => {
cleanup();

@@ -160,3 +174,3 @@ throw error;

const timeoutError = new Errors_1.TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`);
const timeoutPromise = new Promise((resolve, x) => reject = x);
const timeoutPromise = new Promise((resolve, x) => (reject = x));
let timeoutTimer = null;

@@ -163,0 +177,0 @@ if (timeout)

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Touchscreen = exports.Mouse = exports.Keyboard = void 0;
const helper_1 = require("./helper");

@@ -43,3 +44,3 @@ const USKeyboardLayout_1 = require("./USKeyboardLayout");

location: description.location,
isKeypad: description.location === 3
isKeypad: description.location === 3,
});

@@ -65,3 +66,3 @@ }

text: '',
location: 0
location: 0,
};

@@ -103,3 +104,3 @@ const definition = USKeyboardLayout_1.keyDefinitions[keyString];

code: description.code,
location: description.location
location: description.location,
});

@@ -121,3 +122,3 @@ }

if (delay)
await new Promise(f => setTimeout(f, delay));
await new Promise((f) => setTimeout(f, delay));
await this.sendCharacter(char);

@@ -131,3 +132,3 @@ }

if (delay)
await new Promise(f => setTimeout(f, options.delay));
await new Promise((f) => setTimeout(f, options.delay));
await this.up(key);

@@ -160,3 +161,3 @@ }

y: fromY + (this._y - fromY) * (i / steps),
modifiers: this._keyboard._modifiers
modifiers: this._keyboard._modifiers,
});

@@ -168,7 +169,4 @@ }

if (delay !== null) {
await Promise.all([
this.move(x, y),
this.down(options),
]);
await new Promise(f => setTimeout(f, delay));
await Promise.all([this.move(x, y), this.down(options)]);
await new Promise((f) => setTimeout(f, delay));
await this.up(options);

@@ -193,3 +191,3 @@ }

modifiers: this._keyboard._modifiers,
clickCount
clickCount,
});

@@ -209,3 +207,3 @@ }

modifiers: this._keyboard._modifiers,
clickCount
clickCount,
});

@@ -230,3 +228,3 @@ }

expression: 'new Promise(x => requestAnimationFrame(() => requestAnimationFrame(x)))',
awaitPromise: true
awaitPromise: true,
});

@@ -237,3 +235,3 @@ const touchPoints = [{ x: Math.round(x), y: Math.round(y) }];

touchPoints,
modifiers: this._keyboard._modifiers
modifiers: this._keyboard._modifiers,
});

@@ -243,3 +241,3 @@ await this._client.send('Input.dispatchTouchEvent', {

touchPoints: [],
modifiers: this._keyboard._modifiers
modifiers: this._keyboard._modifiers,
});

@@ -246,0 +244,0 @@ }

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.ElementHandle = exports.JSHandle = exports.createJSHandle = void 0;
const helper_1 = require("./helper");

@@ -60,3 +61,3 @@ const QueryHandler_1 = require("./QueryHandler");

objectId: this._remoteObject.objectId,
ownProperties: true
ownProperties: true,
});

@@ -115,3 +116,3 @@ const result = new Map();

const nodeInfo = await this._client.send('DOM.describeNode', {
objectId: this._remoteObject.objectId
objectId: this._remoteObject.objectId,
});

@@ -130,10 +131,14 @@ if (typeof nodeInfo.node.frameId !== 'string')

if (!pageJavascriptEnabled) {
// Chrome still supports behavior: instant but it's not in the spec so TS shouts
// We don't want to make this breaking change in Puppeteer yet so we'll ignore the line.
// @ts-ignore
element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
element.scrollIntoView({
block: 'center',
inline: 'center',
// Chrome still supports behavior: instant but it's not in the spec so TS shouts
// We don't want to make this breaking change in Puppeteer yet so we'll ignore the line.
// @ts-ignore
behavior: 'instant',
});
return false;
}
const visibleRatio = await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
const visibleRatio = await new Promise((resolve) => {
const observer = new IntersectionObserver((entries) => {
resolve(entries[0].intersectionRatio);

@@ -145,6 +150,10 @@ observer.disconnect();

if (visibleRatio !== 1.0) {
// Chrome still supports behavior: instant but it's not in the spec so TS shouts
// We don't want to make this breaking change in Puppeteer yet so we'll ignore the line.
// @ts-ignore
element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant' });
element.scrollIntoView({
block: 'center',
inline: 'center',
// Chrome still supports behavior: instant but it's not in the spec so TS shouts
// We don't want to make this breaking change in Puppeteer yet so we'll ignore the line.
// @ts-ignore
behavior: 'instant',
});
}

@@ -158,5 +167,7 @@ return false;

const [result, layoutMetrics] = await Promise.all([
this._client.send('DOM.getContentQuads', {
objectId: this._remoteObject.objectId
}).catch(helper_1.debugError),
this._client
.send('DOM.getContentQuads', {
objectId: this._remoteObject.objectId,
})
.catch(helper_1.debugError),
this._client.send('Page.getLayoutMetrics'),

@@ -168,3 +179,6 @@ ]);

const { clientWidth, clientHeight } = layoutMetrics.layoutViewport;
const quads = result.quads.map(quad => this._fromProtocolQuad(quad)).map(quad => this._intersectQuadWithViewport(quad, clientWidth, clientHeight)).filter(quad => computeQuadArea(quad) > 1);
const quads = result.quads
.map((quad) => this._fromProtocolQuad(quad))
.map((quad) => this._intersectQuadWithViewport(quad, clientWidth, clientHeight))
.filter((quad) => computeQuadArea(quad) > 1);
if (!quads.length)

@@ -182,9 +196,11 @@ throw new Error('Node is either not visible or not an HTMLElement');

x: x / 4,
y: y / 4
y: y / 4,
};
}
_getBoxModel() {
return this._client.send('DOM.getBoxModel', {
objectId: this._remoteObject.objectId
}).catch(error => helper_1.debugError(error));
return this._client
.send('DOM.getBoxModel', {
objectId: this._remoteObject.objectId,
})
.catch((error) => helper_1.debugError(error));
}

@@ -196,7 +212,7 @@ _fromProtocolQuad(quad) {

{ x: quad[4], y: quad[5] },
{ x: quad[6], y: quad[7] }
{ x: quad[6], y: quad[7] },
];
}
_intersectQuadWithViewport(quad, width, height) {
return quad.map(point => ({
return quad.map((point) => ({
x: Math.min(Math.max(point.x, 0), width),

@@ -218,7 +234,11 @@ y: Math.min(Math.max(point.y, 0), height),

for (const value of values)
helper_1.assert(helper_1.helper.isString(value), 'Values must be strings. Found value "' + value + '" of type "' + (typeof value) + '"');
helper_1.assert(helper_1.helper.isString(value), 'Values must be strings. Found value "' +
value +
'" of type "' +
typeof value +
'"');
/* TODO(jacktfranklin@): once ExecutionContext is TypeScript, and
* its evaluate function is properly typed with generics we can
* return here and remove the typecasting
*/
* its evaluate function is properly typed with generics we can
* return here and remove the typecasting
*/
return this.evaluate((element, values) => {

@@ -236,3 +256,5 @@ if (element.nodeName.toLowerCase() !== 'select')

element.dispatchEvent(new Event('change', { bubbles: true }));
return options.filter(option => option.selected).map(option => option.value);
return options
.filter((option) => option.selected)
.map((option) => option.value);
}, values);

@@ -279,3 +301,7 @@ }

else {
await this._client.send('DOM.setFileInputFiles', { objectId, files, backendNodeId });
await this._client.send('DOM.setFileInputFiles', {
objectId,
files,
backendNodeId,
});
}

@@ -289,3 +315,3 @@ }

async focus() {
await this.evaluate(element => element.focus());
await this.evaluate((element) => element.focus());
}

@@ -325,3 +351,3 @@ async type(text, options) {

width,
height
height,
};

@@ -334,3 +360,5 @@ }

const viewport = this._page.viewport();
if (viewport && (boundingBox.width > viewport.width || boundingBox.height > viewport.height)) {
if (viewport &&
(boundingBox.width > viewport.width ||
boundingBox.height > viewport.height)) {
const newViewport = {

@@ -348,3 +376,3 @@ width: Math.max(viewport.width, Math.ceil(boundingBox.width)),

helper_1.assert(boundingBox.height !== 0, 'Node has 0 height.');
const { layoutViewport: { pageX, pageY } } = await this._client.send('Page.getLayoutMetrics');
const { layoutViewport: { pageX, pageY }, } = await this._client.send('Page.getLayoutMetrics');
const clip = Object.assign({}, boundingBox);

@@ -354,3 +382,3 @@ clip.x += pageX;

const imageData = await this._page.screenshot(Object.assign({}, {
clip
clip,
}, options));

@@ -423,4 +451,4 @@ if (needsViewportReset)

return await this.evaluate(async (element) => {
const visibleRatio = await new Promise(resolve => {
const observer = new IntersectionObserver(entries => {
const visibleRatio = await new Promise((resolve) => {
const observer = new IntersectionObserver((entries) => {
resolve(entries[0].intersectionRatio);

@@ -427,0 +455,0 @@ observer.disconnect();

@@ -24,6 +24,2 @@ "use strict";

const fs = require("fs");
const readline = require("readline");
const debug = require("debug");
const removeFolder = require("rimraf");
const childProcess = require("child_process");
const BrowserFetcher_1 = require("./BrowserFetcher");

@@ -33,121 +29,6 @@ const Connection_1 = require("./Connection");

const helper_1 = require("./helper");
const Errors_1 = require("./Errors");
const WebSocketTransport_1 = require("./WebSocketTransport");
const PipeTransport_1 = require("./PipeTransport");
const BrowserRunner_1 = require("./launcher/BrowserRunner");
const mkdtempAsync = helper_1.helper.promisify(fs.mkdtemp);
const removeFolderAsync = helper_1.helper.promisify(removeFolder);
const writeFileAsync = helper_1.helper.promisify(fs.writeFile);
const debugLauncher = debug('puppeteer:launcher');
class BrowserRunner {
constructor(executablePath, processArguments, tempDirectory) {
this.proc = null;
this.connection = null;
this._closed = true;
this._listeners = [];
this._executablePath = executablePath;
this._processArguments = processArguments;
this._tempDirectory = tempDirectory;
}
start(options = {}) {
const { handleSIGINT, handleSIGTERM, handleSIGHUP, dumpio, env, pipe } = options;
let stdio = ['pipe', 'pipe', 'pipe'];
if (pipe) {
if (dumpio)
stdio = ['ignore', 'pipe', 'pipe', 'pipe', 'pipe'];
else
stdio = ['ignore', 'ignore', 'ignore', 'pipe', 'pipe'];
}
helper_1.assert(!this.proc, 'This process has previously been started.');
debugLauncher(`Calling ${this._executablePath} ${this._processArguments.join(' ')}`);
this.proc = childProcess.spawn(this._executablePath, this._processArguments, {
// On non-windows platforms, `detached: true` makes child process a leader of a new
// process group, making it possible to kill child process tree with `.kill(-pid)` command.
// @see https://nodejs.org/api/child_process.html#child_process_options_detached
detached: process.platform !== 'win32',
env,
stdio
});
if (dumpio) {
this.proc.stderr.pipe(process.stderr);
this.proc.stdout.pipe(process.stdout);
}
this._closed = false;
this._processClosing = new Promise(fulfill => {
this.proc.once('exit', () => {
this._closed = true;
// Cleanup as processes exit.
if (this._tempDirectory) {
removeFolderAsync(this._tempDirectory)
.then(() => fulfill())
.catch(error => console.error(error));
}
else {
fulfill();
}
});
});
this._listeners = [helper_1.helper.addEventListener(process, 'exit', this.kill.bind(this))];
if (handleSIGINT)
this._listeners.push(helper_1.helper.addEventListener(process, 'SIGINT', () => { this.kill(); process.exit(130); }));
if (handleSIGTERM)
this._listeners.push(helper_1.helper.addEventListener(process, 'SIGTERM', this.close.bind(this)));
if (handleSIGHUP)
this._listeners.push(helper_1.helper.addEventListener(process, 'SIGHUP', this.close.bind(this)));
}
close() {
if (this._closed)
return Promise.resolve();
helper_1.helper.removeEventListeners(this._listeners);
if (this._tempDirectory) {
this.kill();
}
else if (this.connection) {
// Attempt to close the browser gracefully
this.connection.send('Browser.close').catch(error => {
helper_1.debugError(error);
this.kill();
});
}
return this._processClosing;
}
kill() {
helper_1.helper.removeEventListeners(this._listeners);
if (this.proc && this.proc.pid && !this.proc.killed && !this._closed) {
try {
if (process.platform === 'win32')
childProcess.execSync(`taskkill /pid ${this.proc.pid} /T /F`);
else
process.kill(-this.proc.pid, 'SIGKILL');
}
catch (error) {
// the process might have already stopped
}
}
// Attempt to remove temporary profile directory to avoid littering.
try {
removeFolder.sync(this._tempDirectory);
}
catch (error) { }
}
/**
* @param {!({usePipe?: boolean, timeout: number, slowMo: number, preferredRevision: string})} options
*
* @return {!Promise<!Connection>}
*/
async setupConnection(options) {
const { usePipe, timeout, slowMo, preferredRevision } = options;
if (!usePipe) {
const browserWSEndpoint = await waitForWSEndpoint(this.proc, timeout, preferredRevision);
const transport = await WebSocketTransport_1.WebSocketTransport.create(browserWSEndpoint);
this.connection = new Connection_1.Connection(browserWSEndpoint, transport, slowMo);
}
else {
// stdio was assigned during start(), and the 'pipe' option there adds the 4th and 5th items to stdio array
const { 3: pipeWrite, 4: pipeRead } = this.proc.stdio;
const transport = new PipeTransport_1.PipeTransport(pipeWrite, pipeRead);
this.connection = new Connection_1.Connection('', transport, slowMo);
}
return this.connection;
}
}
class ChromeLauncher {

@@ -160,3 +41,3 @@ constructor(projectRoot, preferredRevision, isPuppeteerCore) {

async launch(options = {}) {
const { ignoreDefaultArgs = false, args = [], dumpio = false, executablePath = null, pipe = false, env = process.env, handleSIGINT = true, handleSIGTERM = true, handleSIGHUP = true, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, slowMo = 0, timeout = 30000 } = options;
const { ignoreDefaultArgs = false, args = [], dumpio = false, executablePath = null, pipe = false, env = process.env, handleSIGINT = true, handleSIGTERM = true, handleSIGHUP = true, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, slowMo = 0, timeout = 30000, } = options;
const profilePath = path.join(os.tmpdir(), 'puppeteer_dev_chrome_profile-');

@@ -167,9 +48,9 @@ const chromeArguments = [];

else if (Array.isArray(ignoreDefaultArgs))
chromeArguments.push(...this.defaultArgs(options).filter(arg => !ignoreDefaultArgs.includes(arg)));
chromeArguments.push(...this.defaultArgs(options).filter((arg) => !ignoreDefaultArgs.includes(arg)));
else
chromeArguments.push(...args);
let temporaryUserDataDir = null;
if (!chromeArguments.some(argument => argument.startsWith('--remote-debugging-')))
if (!chromeArguments.some((argument) => argument.startsWith('--remote-debugging-')))
chromeArguments.push(pipe ? '--remote-debugging-pipe' : '--remote-debugging-port=0');
if (!chromeArguments.some(arg => arg.startsWith('--user-data-dir'))) {
if (!chromeArguments.some((arg) => arg.startsWith('--user-data-dir'))) {
temporaryUserDataDir = await mkdtempAsync(profilePath);

@@ -186,8 +67,20 @@ chromeArguments.push(`--user-data-dir=${temporaryUserDataDir}`);

const usePipe = chromeArguments.includes('--remote-debugging-pipe');
const runner = new BrowserRunner(chromeExecutable, chromeArguments, temporaryUserDataDir);
runner.start({ handleSIGHUP, handleSIGTERM, handleSIGINT, dumpio, env, pipe: usePipe });
const runner = new BrowserRunner_1.BrowserRunner(chromeExecutable, chromeArguments, temporaryUserDataDir);
runner.start({
handleSIGHUP,
handleSIGTERM,
handleSIGINT,
dumpio,
env,
pipe: usePipe,
});
try {
const connection = await runner.setupConnection({ usePipe, timeout, slowMo, preferredRevision: this._preferredRevision });
const connection = await runner.setupConnection({
usePipe,
timeout,
slowMo,
preferredRevision: this._preferredRevision,
});
const browser = await Browser_1.Browser.create(connection, [], ignoreHTTPSErrors, defaultViewport, runner.proc, runner.close.bind(runner));
await browser.waitForTarget(t => t.type() === 'page');
await browser.waitForTarget((t) => t.type() === 'page');
return browser;

@@ -230,3 +123,3 @@ }

];
const { devtools = false, headless = !devtools, args = [], userDataDir = null } = options;
const { devtools = false, headless = !devtools, args = [], userDataDir = null, } = options;
if (userDataDir)

@@ -239,3 +132,3 @@ chromeArguments.push(`--user-data-dir=${userDataDir}`);

}
if (args.every(arg => arg.startsWith('-')))
if (args.every((arg) => arg.startsWith('-')))
chromeArguments.push('about:blank');

@@ -253,3 +146,6 @@ chromeArguments.push(...args);

const { browserWSEndpoint, browserURL, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, transport, slowMo = 0, } = options;
helper_1.assert(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) === 1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
helper_1.assert(Number(!!browserWSEndpoint) +
Number(!!browserURL) +
Number(!!transport) ===
1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
let connection = null;

@@ -279,3 +175,3 @@ if (transport) {

async launch(options = {}) {
const { ignoreDefaultArgs = false, args = [], dumpio = false, executablePath = null, pipe = false, env = process.env, handleSIGINT = true, handleSIGTERM = true, handleSIGHUP = true, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, slowMo = 0, timeout = 30000, extraPrefsFirefox = {} } = options;
const { ignoreDefaultArgs = false, args = [], dumpio = false, executablePath = null, pipe = false, env = process.env, handleSIGINT = true, handleSIGTERM = true, handleSIGHUP = true, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, slowMo = 0, timeout = 30000, extraPrefsFirefox = {}, } = options;
const firefoxArguments = [];

@@ -285,9 +181,10 @@ if (!ignoreDefaultArgs)

else if (Array.isArray(ignoreDefaultArgs))
firefoxArguments.push(...this.defaultArgs(options).filter(arg => !ignoreDefaultArgs.includes(arg)));
firefoxArguments.push(...this.defaultArgs(options).filter((arg) => !ignoreDefaultArgs.includes(arg)));
else
firefoxArguments.push(...args);
if (!firefoxArguments.some(argument => argument.startsWith('--remote-debugging-')))
if (!firefoxArguments.some((argument) => argument.startsWith('--remote-debugging-')))
firefoxArguments.push('--remote-debugging-port=0');
let temporaryUserDataDir = null;
if (!firefoxArguments.includes('-profile') && !firefoxArguments.includes('--profile')) {
if (!firefoxArguments.includes('-profile') &&
!firefoxArguments.includes('--profile')) {
temporaryUserDataDir = await this._createProfile(extraPrefsFirefox);

@@ -305,8 +202,20 @@ firefoxArguments.push('--profile');

}
const runner = new BrowserRunner(firefoxExecutable, firefoxArguments, temporaryUserDataDir);
runner.start({ handleSIGHUP, handleSIGTERM, handleSIGINT, dumpio, env, pipe });
const runner = new BrowserRunner_1.BrowserRunner(firefoxExecutable, firefoxArguments, temporaryUserDataDir);
runner.start({
handleSIGHUP,
handleSIGTERM,
handleSIGINT,
dumpio,
env,
pipe,
});
try {
const connection = await runner.setupConnection({ usePipe: pipe, timeout, slowMo, preferredRevision: this._preferredRevision });
const connection = await runner.setupConnection({
usePipe: pipe,
timeout,
slowMo,
preferredRevision: this._preferredRevision,
});
const browser = await Browser_1.Browser.create(connection, [], ignoreHTTPSErrors, defaultViewport, runner.proc, runner.close.bind(runner));
await browser.waitForTarget(t => t.type() === 'page');
await browser.waitForTarget((t) => t.type() === 'page');
return browser;

@@ -321,3 +230,6 @@ }

const { browserWSEndpoint, browserURL, ignoreHTTPSErrors = false, defaultViewport = { width: 800, height: 600 }, transport, slowMo = 0, } = options;
helper_1.assert(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) === 1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
helper_1.assert(Number(!!browserWSEndpoint) +
Number(!!browserURL) +
Number(!!transport) ===
1, 'Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect');
let connection = null;

@@ -345,3 +257,5 @@ if (transport) {

if (this._preferredRevision === 'latest') {
const browserFetcher = new BrowserFetcher_1.BrowserFetcher(this._projectRoot, { product: this.product });
const browserFetcher = new BrowserFetcher_1.BrowserFetcher(this._projectRoot, {
product: this.product,
});
const localRevisions = await browserFetcher.localRevisions();

@@ -356,7 +270,4 @@ if (localRevisions[0])

defaultArgs(options = {}) {
const firefoxArguments = [
'--no-remote',
'--foreground',
];
const { devtools = false, headless = !devtools, args = [], userDataDir = null } = options;
const firefoxArguments = ['--no-remote', '--foreground'];
const { devtools = false, headless = !devtools, args = [], userDataDir = null, } = options;
if (userDataDir) {

@@ -370,3 +281,3 @@ firefoxArguments.push('--profile');

firefoxArguments.push('--devtools');
if (args.every(arg => arg.startsWith('-')))
if (args.every((arg) => arg.startsWith('-')))
firefoxArguments.push('about:blank');

@@ -546,52 +457,14 @@ firefoxArguments.push(...args);

}
function waitForWSEndpoint(browserProcess, timeout, preferredRevision) {
return new Promise((resolve, reject) => {
const rl = readline.createInterface({ input: browserProcess.stderr });
let stderr = '';
const listeners = [
helper_1.helper.addEventListener(rl, 'line', onLine),
helper_1.helper.addEventListener(rl, 'close', () => onClose()),
helper_1.helper.addEventListener(browserProcess, 'exit', () => onClose()),
helper_1.helper.addEventListener(browserProcess, 'error', error => onClose(error))
];
const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;
/**
* @param {!Error=} error
*/
function onClose(error) {
cleanup();
reject(new Error([
'Failed to launch the browser process!' + (error ? ' ' + error.message : ''),
stderr,
'',
'TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md',
'',
].join('\n')));
}
function onTimeout() {
cleanup();
reject(new Errors_1.TimeoutError(`Timed out after ${timeout} ms while trying to connect to the browser! Only Chrome at revision r${preferredRevision} is guaranteed to work.`));
}
function onLine(line) {
stderr += line + '\n';
const match = line.match(/^DevTools listening on (ws:\/\/.*)$/);
if (!match)
return;
cleanup();
resolve(match[1]);
}
function cleanup() {
if (timeoutId)
clearTimeout(timeoutId);
helper_1.helper.removeEventListeners(listeners);
}
});
}
function getWSEndpoint(browserURL) {
let resolve, reject;
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
const endpointURL = URL.resolve(browserURL, '/json/version');
const protocol = endpointURL.startsWith('https') ? https : http;
const requestOptions = Object.assign(URL.parse(endpointURL), { method: 'GET' });
const request = protocol.request(requestOptions, res => {
const requestOptions = Object.assign(URL.parse(endpointURL), {
method: 'GET',
});
const request = protocol.request(requestOptions, (res) => {
let data = '';

@@ -605,3 +478,3 @@ if (res.statusCode !== 200) {

res.setEncoding('utf8');
res.on('data', chunk => data += chunk);
res.on('data', (chunk) => (data += chunk));
res.on('end', () => resolve(JSON.parse(data).webSocketDebuggerUrl));

@@ -611,4 +484,6 @@ });

request.end();
return promise.catch(error => {
error.message = `Failed to fetch browser webSocket url from ${endpointURL}: ` + error.message;
return promise.catch((error) => {
error.message =
`Failed to fetch browser webSocket url from ${endpointURL}: ` +
error.message;
throw error;

@@ -620,9 +495,16 @@ });

if (!launcher._isPuppeteerCore) {
const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH || process.env.npm_config_puppeteer_executable_path || process.env.npm_package_config_puppeteer_executable_path;
const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH ||
process.env.npm_config_puppeteer_executable_path ||
process.env.npm_package_config_puppeteer_executable_path;
if (executablePath) {
const missingText = !fs.existsSync(executablePath) ? 'Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: ' + executablePath : null;
const missingText = !fs.existsSync(executablePath)
? 'Tried to use PUPPETEER_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: ' +
executablePath
: null;
return { executablePath, missingText };
}
}
const browserFetcher = new BrowserFetcher_1.BrowserFetcher(launcher._projectRoot, { product: launcher.product });
const browserFetcher = new BrowserFetcher_1.BrowserFetcher(launcher._projectRoot, {
product: launcher.product,
});
if (!launcher._isPuppeteerCore && launcher.product === 'chrome') {

@@ -632,3 +514,6 @@ const revision = process.env['PUPPETEER_CHROMIUM_REVISION'];

const revisionInfo = browserFetcher.revisionInfo(revision);
const missingText = !revisionInfo.local ? 'Tried to use PUPPETEER_CHROMIUM_REVISION env variable to launch browser but did not find executable at: ' + revisionInfo.executablePath : null;
const missingText = !revisionInfo.local
? 'Tried to use PUPPETEER_CHROMIUM_REVISION env variable to launch browser but did not find executable at: ' +
revisionInfo.executablePath
: null;
return { executablePath: revisionInfo.executablePath, missingText };

@@ -638,3 +523,5 @@ }

const revisionInfo = browserFetcher.revisionInfo(launcher._preferredRevision);
const missingText = !revisionInfo.local ? `Could not find browser revision ${launcher._preferredRevision}. Run "npm install" or "yarn install" to download a browser binary.` : null;
const missingText = !revisionInfo.local
? `Could not find browser revision ${launcher._preferredRevision}. Run "npm install" or "yarn install" to download a browser binary.`
: null;
return { executablePath: revisionInfo.executablePath, missingText };

@@ -645,3 +532,6 @@ }

if (!product && !isPuppeteerCore)
product = process.env.PUPPETEER_PRODUCT || process.env.npm_config_puppeteer_product || process.env.npm_package_config_puppeteer_product;
product =
process.env.PUPPETEER_PRODUCT ||
process.env.npm_config_puppeteer_product ||
process.env.npm_package_config_puppeteer_product;
switch (product) {

@@ -652,2 +542,9 @@ case 'firefox':

default:
if (typeof product !== 'undefined' && product !== 'chrome') {
/* The user gave us an incorrect product name
* we'll default to launching Chrome, but log to the console
* to let the user know (they've probably typoed).
*/
console.warn(`Warning: unknown product name ${product}. Falling back to chrome.`);
}
return new ChromeLauncher(projectRoot, preferredRevision, isPuppeteerCore);

@@ -654,0 +551,0 @@ }

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.LifecycleWatcher = void 0;
const helper_1 = require("./helper");

@@ -34,3 +35,3 @@ const Events_1 = require("./Events");

waitUntil = [waitUntil];
this._expectedLifecycle = waitUntil.map(value => {
this._expectedLifecycle = waitUntil.map((value) => {
const protocolEvent = puppeteerToProtocolLifecycle.get(value);

@@ -52,13 +53,13 @@ helper_1.assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value);

];
this._sameDocumentNavigationPromise = new Promise(fulfill => {
this._sameDocumentNavigationPromise = new Promise((fulfill) => {
this._sameDocumentNavigationCompleteCallback = fulfill;
});
this._lifecyclePromise = new Promise(fulfill => {
this._lifecyclePromise = new Promise((fulfill) => {
this._lifecycleCallback = fulfill;
});
this._newDocumentNavigationPromise = new Promise(fulfill => {
this._newDocumentNavigationPromise = new Promise((fulfill) => {
this._newDocumentNavigationCompleteCallback = fulfill;
});
this._timeoutPromise = this._createTimeoutPromise();
this._terminationPromise = new Promise(fulfill => {
this._terminationPromise = new Promise((fulfill) => {
this._terminationCallback = fulfill;

@@ -102,4 +103,3 @@ });

const errorMessage = 'Navigation timeout of ' + this._timeout + ' ms exceeded';
return new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._timeout))
.then(() => new Errors_1.TimeoutError(errorMessage));
return new Promise((fulfill) => (this._maximumTimer = setTimeout(fulfill, this._timeout))).then(() => new Errors_1.TimeoutError(errorMessage));
}

@@ -117,3 +117,4 @@ _navigatedWithinDocument(frame) {

this._lifecycleCallback();
if (this._frame._loaderId === this._initialLoaderId && !this._hasSameDocumentNavigation)
if (this._frame._loaderId === this._initialLoaderId &&
!this._hasSameDocumentNavigation)
return;

@@ -120,0 +121,0 @@ if (this._hasSameDocumentNavigation)

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkManager = void 0;
/**

@@ -21,2 +22,4 @@ * Copyright 2017 Google Inc. All rights reserved.

const Events_1 = require("./Events");
const Request_1 = require("./Request");
const Response_1 = require("./Response");
class NetworkManager extends EventEmitter {

@@ -49,3 +52,5 @@ constructor(client, ignoreHTTPSErrors, frameManager) {

if (this._ignoreHTTPSErrors)
await this._client.send('Security.setIgnoreCertificateErrors', { ignore: true });
await this._client.send('Security.setIgnoreCertificateErrors', {
ignore: true,
});
}

@@ -63,3 +68,5 @@ async authenticate(credentials) {

}
await this._client.send('Network.setExtraHTTPHeaders', { headers: this._extraHTTPHeaders });
await this._client.send('Network.setExtraHTTPHeaders', {
headers: this._extraHTTPHeaders,
});
}

@@ -78,3 +85,3 @@ extraHTTPHeaders() {

downloadThroughput: -1,
uploadThroughput: -1
uploadThroughput: -1,
});

@@ -110,3 +117,3 @@ }

this._updateProtocolCacheDisabled(),
this._client.send('Fetch.disable')
this._client.send('Fetch.disable'),
]);

@@ -117,3 +124,3 @@ }

await this._client.send('Network.setCacheDisabled', {
cacheDisabled: this._userCacheDisabled || this._protocolRequestInterceptionEnabled
cacheDisabled: this._userCacheDisabled || this._protocolRequestInterceptionEnabled,
});

@@ -123,3 +130,4 @@ }

// Request interception doesn't happen for data URLs with Network Service.
if (this._protocolRequestInterceptionEnabled && !event.request.url.startsWith('data:')) {
if (this._protocolRequestInterceptionEnabled &&
!event.request.url.startsWith('data:')) {
const requestId = event.requestId;

@@ -150,13 +158,21 @@ const interceptionId = this._requestIdToInterceptionId.get(requestId);

}
const { username, password } = this._credentials || { username: undefined, password: undefined };
this._client.send('Fetch.continueWithAuth', {
const { username, password } = this._credentials || {
username: undefined,
password: undefined,
};
this._client
.send('Fetch.continueWithAuth', {
requestId: event.requestId,
authChallengeResponse: { response, username, password },
}).catch(helper_1.debugError);
})
.catch(helper_1.debugError);
}
_onRequestPaused(event) {
if (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled) {
this._client.send('Fetch.continueRequest', {
requestId: event.requestId
}).catch(helper_1.debugError);
if (!this._userRequestInterceptionEnabled &&
this._protocolRequestInterceptionEnabled) {
this._client
.send('Fetch.continueRequest', {
requestId: event.requestId,
})
.catch(helper_1.debugError);
}

@@ -184,4 +200,6 @@ const requestId = event.networkId;

}
const frame = event.frameId ? this._frameManager.frame(event.frameId) : null;
const request = new Request(this._client, frame, interceptionId, this._userRequestInterceptionEnabled, event, redirectChain);
const frame = event.frameId
? this._frameManager.frame(event.frameId)
: null;
const request = new Request_1.Request(this._client, frame, interceptionId, this._userRequestInterceptionEnabled, event, redirectChain);
this._requestIdToRequest.set(event.requestId, request);

@@ -196,6 +214,6 @@ this.emit(Events_1.Events.NetworkManager.Request, request);

_handleRequestRedirect(request, responsePayload) {
const response = new Response(this._client, request, responsePayload);
const response = new Response_1.Response(this._client, request, responsePayload);
request._response = response;
request._redirectChain.push(request);
response._bodyLoadedPromiseFulfill.call(null, new Error('Response body is unavailable for redirect responses'));
response._resolveBody(new Error('Response body is unavailable for redirect responses'));
this._requestIdToRequest.delete(request._requestId);

@@ -211,3 +229,3 @@ this._attemptedAuthentications.delete(request._interceptionId);

return;
const response = new Response(this._client, request, event.response);
const response = new Response_1.Response(this._client, request, event.response);
request._response = response;

@@ -225,3 +243,3 @@ this.emit(Events_1.Events.NetworkManager.Response, response);

if (request.response())
request.response()._bodyLoadedPromiseFulfill.call(null);
request.response()._resolveBody(null);
this._requestIdToRequest.delete(request._requestId);

@@ -240,3 +258,3 @@ this._attemptedAuthentications.delete(request._interceptionId);

if (response)
response._bodyLoadedPromiseFulfill.call(null);
response._resolveBody(null);
this._requestIdToRequest.delete(request._requestId);

@@ -248,321 +266,1 @@ this._attemptedAuthentications.delete(request._interceptionId);

exports.NetworkManager = NetworkManager;
class Request {
constructor(client, frame, interceptionId, allowInterception, event, redirectChain) {
this._interceptionHandled = false;
this._response = null;
this._failureText = null;
this._headers = {};
this._fromMemoryCache = false;
this._client = client;
this._requestId = event.requestId;
this._isNavigationRequest = event.requestId === event.loaderId && event.type === 'Document';
this._interceptionId = interceptionId;
this._allowInterception = allowInterception;
this._url = event.request.url;
this._resourceType = event.type.toLowerCase();
this._method = event.request.method;
this._postData = event.request.postData;
this._frame = frame;
this._redirectChain = redirectChain;
for (const key of Object.keys(event.request.headers))
this._headers[key.toLowerCase()] = event.request.headers[key];
}
url() {
return this._url;
}
resourceType() {
return this._resourceType;
}
method() {
return this._method;
}
postData() {
return this._postData;
}
headers() {
return this._headers;
}
response() {
return this._response;
}
frame() {
return this._frame;
}
isNavigationRequest() {
return this._isNavigationRequest;
}
redirectChain() {
return this._redirectChain.slice();
}
/**
* @return {?{errorText: string}}
*/
failure() {
if (!this._failureText)
return null;
return {
errorText: this._failureText
};
}
async continue(overrides = {}) {
// Request interception is not supported for data: urls.
if (this._url.startsWith('data:'))
return;
helper_1.assert(this._allowInterception, 'Request Interception is not enabled!');
helper_1.assert(!this._interceptionHandled, 'Request is already handled!');
const { url, method, postData, headers } = overrides;
this._interceptionHandled = true;
await this._client.send('Fetch.continueRequest', {
requestId: this._interceptionId,
url,
method,
postData,
headers: headers ? headersArray(headers) : undefined,
}).catch(error => {
// In certain cases, protocol will return error if the request was already canceled
// or the page was closed. We should tolerate these errors.
helper_1.debugError(error);
});
}
async respond(response) {
// Mocking responses for dataURL requests is not currently supported.
if (this._url.startsWith('data:'))
return;
helper_1.assert(this._allowInterception, 'Request Interception is not enabled!');
helper_1.assert(!this._interceptionHandled, 'Request is already handled!');
this._interceptionHandled = true;
const responseBody = response.body && helper_1.helper.isString(response.body) ? Buffer.from(response.body) : response.body || null;
const responseHeaders = {};
if (response.headers) {
for (const header of Object.keys(response.headers))
responseHeaders[header.toLowerCase()] = response.headers[header];
}
if (response.contentType)
responseHeaders['content-type'] = response.contentType;
if (responseBody && !('content-length' in responseHeaders))
responseHeaders['content-length'] = String(Buffer.byteLength(responseBody));
await this._client.send('Fetch.fulfillRequest', {
requestId: this._interceptionId,
responseCode: response.status || 200,
responsePhrase: STATUS_TEXTS[response.status || 200],
responseHeaders: headersArray(responseHeaders),
body: responseBody ? responseBody.toString('base64') : undefined,
}).catch(error => {
// In certain cases, protocol will return error if the request was already canceled
// or the page was closed. We should tolerate these errors.
helper_1.debugError(error);
});
}
async abort(errorCode = 'failed') {
// Request interception is not supported for data: urls.
if (this._url.startsWith('data:'))
return;
const errorReason = errorReasons[errorCode];
helper_1.assert(errorReason, 'Unknown error code: ' + errorCode);
helper_1.assert(this._allowInterception, 'Request Interception is not enabled!');
helper_1.assert(!this._interceptionHandled, 'Request is already handled!');
this._interceptionHandled = true;
await this._client.send('Fetch.failRequest', {
requestId: this._interceptionId,
errorReason
}).catch(error => {
// In certain cases, protocol will return error if the request was already canceled
// or the page was closed. We should tolerate these errors.
helper_1.debugError(error);
});
}
}
exports.Request = Request;
const errorReasons = {
'aborted': 'Aborted',
'accessdenied': 'AccessDenied',
'addressunreachable': 'AddressUnreachable',
'blockedbyclient': 'BlockedByClient',
'blockedbyresponse': 'BlockedByResponse',
'connectionaborted': 'ConnectionAborted',
'connectionclosed': 'ConnectionClosed',
'connectionfailed': 'ConnectionFailed',
'connectionrefused': 'ConnectionRefused',
'connectionreset': 'ConnectionReset',
'internetdisconnected': 'InternetDisconnected',
'namenotresolved': 'NameNotResolved',
'timedout': 'TimedOut',
'failed': 'Failed',
};
class Response {
constructor(client, request, responsePayload) {
this._contentPromise = null;
this._headers = {};
this._client = client;
this._request = request;
this._bodyLoadedPromise = new Promise(fulfill => {
this._bodyLoadedPromiseFulfill = fulfill;
});
this._remoteAddress = {
ip: responsePayload.remoteIPAddress,
port: responsePayload.remotePort,
};
this._status = responsePayload.status;
this._statusText = responsePayload.statusText;
this._url = request.url();
this._fromDiskCache = !!responsePayload.fromDiskCache;
this._fromServiceWorker = !!responsePayload.fromServiceWorker;
for (const key of Object.keys(responsePayload.headers))
this._headers[key.toLowerCase()] = responsePayload.headers[key];
this._securityDetails = responsePayload.securityDetails ? new SecurityDetails(responsePayload.securityDetails) : null;
}
remoteAddress() {
return this._remoteAddress;
}
url() {
return this._url;
}
ok() {
return this._status === 0 || (this._status >= 200 && this._status <= 299);
}
status() {
return this._status;
}
statusText() {
return this._statusText;
}
headers() {
return this._headers;
}
securityDetails() {
return this._securityDetails;
}
buffer() {
if (!this._contentPromise) {
this._contentPromise = this._bodyLoadedPromise.then(async (error) => {
if (error)
throw error;
const response = await this._client.send('Network.getResponseBody', {
requestId: this._request._requestId
});
return Buffer.from(response.body, response.base64Encoded ? 'base64' : 'utf8');
});
}
return this._contentPromise;
}
async text() {
const content = await this.buffer();
return content.toString('utf8');
}
async json() {
const content = await this.text();
return JSON.parse(content);
}
request() {
return this._request;
}
fromCache() {
return this._fromDiskCache || this._request._fromMemoryCache;
}
fromServiceWorker() {
return this._fromServiceWorker;
}
frame() {
return this._request.frame();
}
}
exports.Response = Response;
class SecurityDetails {
constructor(securityPayload) {
this._subjectName = securityPayload.subjectName;
this._issuer = securityPayload.issuer;
this._validFrom = securityPayload.validFrom;
this._validTo = securityPayload.validTo;
this._protocol = securityPayload.protocol;
}
subjectName() {
return this._subjectName;
}
issuer() {
return this._issuer;
}
validFrom() {
return this._validFrom;
}
validTo() {
return this._validTo;
}
protocol() {
return this._protocol;
}
}
exports.SecurityDetails = SecurityDetails;
function headersArray(headers) {
const result = [];
for (const name in headers) {
if (!Object.is(headers[name], undefined))
result.push({ name, value: headers[name] + '' });
}
return result;
}
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.
const STATUS_TEXTS = {
'100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'103': 'Early Hints',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'306': 'Switch Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a teapot',
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Too Early',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'510': 'Not Extended',
'511': 'Network Authentication Required',
};

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Page = void 0;
const fs = require("fs");

@@ -35,2 +36,4 @@ const EventEmitter = require("events");

const TimeoutSettings_1 = require("./TimeoutSettings");
const FileChooser_1 = require("./FileChooser");
const ConsoleMessage_1 = require("./ConsoleMessage");
const writeFileAsync = helper_1.helper.promisify(fs.writeFile);

@@ -50,4 +53,14 @@ const paperFormats = {

};
class ScreenshotTaskQueue {
constructor() {
this._chain = Promise.resolve(undefined);
}
postTask(task) {
const result = this._chain.then(task);
this._chain = result.catch(() => { });
return result;
}
}
class Page extends EventEmitter {
constructor(client, target, ignoreHTTPSErrors, screenshotTaskQueue) {
constructor(client, target, ignoreHTTPSErrors) {
super();

@@ -71,10 +84,12 @@ this._closed = false;

this._coverage = new Coverage_1.Coverage(client);
this._screenshotTaskQueue = screenshotTaskQueue;
this._screenshotTaskQueue = new ScreenshotTaskQueue();
this._viewport = null;
client.on('Target.attachedToTarget', event => {
client.on('Target.attachedToTarget', (event) => {
if (event.targetInfo.type !== 'worker') {
// If we don't detach from service workers, they will never die.
client.send('Target.detachFromTarget', {
sessionId: event.sessionId
}).catch(helper_1.debugError);
client
.send('Target.detachFromTarget', {
sessionId: event.sessionId,
})
.catch(helper_1.debugError);
return;

@@ -87,3 +102,3 @@ }

});
client.on('Target.detachedFromTarget', event => {
client.on('Target.detachedFromTarget', (event) => {
const worker = this._workers.get(event.sessionId);

@@ -95,21 +110,21 @@ if (!worker)

});
this._frameManager.on(Events_1.Events.FrameManager.FrameAttached, event => this.emit(Events_1.Events.Page.FrameAttached, event));
this._frameManager.on(Events_1.Events.FrameManager.FrameDetached, event => this.emit(Events_1.Events.Page.FrameDetached, event));
this._frameManager.on(Events_1.Events.FrameManager.FrameNavigated, event => this.emit(Events_1.Events.Page.FrameNavigated, event));
this._frameManager.on(Events_1.Events.FrameManager.FrameAttached, (event) => this.emit(Events_1.Events.Page.FrameAttached, event));
this._frameManager.on(Events_1.Events.FrameManager.FrameDetached, (event) => this.emit(Events_1.Events.Page.FrameDetached, event));
this._frameManager.on(Events_1.Events.FrameManager.FrameNavigated, (event) => this.emit(Events_1.Events.Page.FrameNavigated, event));
const networkManager = this._frameManager.networkManager();
networkManager.on(Events_1.Events.NetworkManager.Request, event => this.emit(Events_1.Events.Page.Request, event));
networkManager.on(Events_1.Events.NetworkManager.Response, event => this.emit(Events_1.Events.Page.Response, event));
networkManager.on(Events_1.Events.NetworkManager.RequestFailed, event => this.emit(Events_1.Events.Page.RequestFailed, event));
networkManager.on(Events_1.Events.NetworkManager.RequestFinished, event => this.emit(Events_1.Events.Page.RequestFinished, event));
networkManager.on(Events_1.Events.NetworkManager.Request, (event) => this.emit(Events_1.Events.Page.Request, event));
networkManager.on(Events_1.Events.NetworkManager.Response, (event) => this.emit(Events_1.Events.Page.Response, event));
networkManager.on(Events_1.Events.NetworkManager.RequestFailed, (event) => this.emit(Events_1.Events.Page.RequestFailed, event));
networkManager.on(Events_1.Events.NetworkManager.RequestFinished, (event) => this.emit(Events_1.Events.Page.RequestFinished, event));
this._fileChooserInterceptors = new Set();
client.on('Page.domContentEventFired', () => this.emit(Events_1.Events.Page.DOMContentLoaded));
client.on('Page.loadEventFired', () => this.emit(Events_1.Events.Page.Load));
client.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
client.on('Runtime.bindingCalled', event => this._onBindingCalled(event));
client.on('Page.javascriptDialogOpening', event => this._onDialog(event));
client.on('Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails));
client.on('Runtime.consoleAPICalled', (event) => this._onConsoleAPI(event));
client.on('Runtime.bindingCalled', (event) => this._onBindingCalled(event));
client.on('Page.javascriptDialogOpening', (event) => this._onDialog(event));
client.on('Runtime.exceptionThrown', (exception) => this._handleException(exception.exceptionDetails));
client.on('Inspector.targetCrashed', () => this._onTargetCrashed());
client.on('Performance.metrics', event => this._emitMetrics(event));
client.on('Log.entryAdded', event => this._onLogEntryAdded(event));
client.on('Page.fileChooserOpened', event => this._onFileChooser(event));
client.on('Performance.metrics', (event) => this._emitMetrics(event));
client.on('Log.entryAdded', (event) => this._onLogEntryAdded(event));
client.on('Page.fileChooserOpened', (event) => this._onFileChooser(event));
this._target._isClosedPromise.then(() => {

@@ -120,4 +135,4 @@ this.emit(Events_1.Events.Page.Close);

}
static async create(client, target, ignoreHTTPSErrors, defaultViewport, screenshotTaskQueue) {
const page = new Page(client, target, ignoreHTTPSErrors, screenshotTaskQueue);
static async create(client, target, ignoreHTTPSErrors, defaultViewport) {
const page = new Page(client, target, ignoreHTTPSErrors);
await page._initialize();

@@ -131,3 +146,7 @@ if (defaultViewport)

this._frameManager.initialize(),
this._client.send('Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: false, flatten: true }),
this._client.send('Target.setAutoAttach', {
autoAttach: true,
waitForDebuggerOnStart: false,
flatten: true,
}),
this._client.send('Performance.enable', {}),

@@ -145,3 +164,3 @@ this._client.send('Log.enable', {}),

this._fileChooserInterceptors.clear();
const fileChooser = new FileChooser(this._client, element, event);
const fileChooser = new FileChooser_1.FileChooser(element, event);
for (const interceptor of interceptors)

@@ -152,8 +171,12 @@ interceptor.call(null, fileChooser);

if (!this._fileChooserInterceptors.size)
await this._client.send('Page.setInterceptFileChooserDialog', { enabled: true });
const { timeout = this._timeoutSettings.timeout(), } = options;
await this._client.send('Page.setInterceptFileChooserDialog', {
enabled: true,
});
const { timeout = this._timeoutSettings.timeout() } = options;
let callback;
const promise = new Promise(x => callback = x);
const promise = new Promise((x) => (callback = x));
this._fileChooserInterceptors.add(callback);
return helper_1.helper.waitWithTimeout(promise, 'waiting for file chooser', timeout).catch(error => {
return helper_1.helper
.waitWithTimeout(promise, 'waiting for file chooser', timeout)
.catch((error) => {
this._fileChooserInterceptors.delete(callback);

@@ -171,3 +194,7 @@ throw error;

throw new Error(`Invalid accuracy "${accuracy}": precondition 0 <= ACCURACY failed.`);
await this._client.send('Emulation.setGeolocationOverride', { longitude, latitude, accuracy });
await this._client.send('Emulation.setGeolocationOverride', {
longitude,
latitude,
accuracy,
});
}

@@ -189,5 +216,5 @@ target() {

if (args)
args.map(arg => helper_1.helper.releaseObject(this._client, arg));
args.map((arg) => helper_1.helper.releaseObject(this._client, arg));
if (source !== 'worker')
this.emit(Events_1.Events.Page.Console, new ConsoleMessage(level, text, [], { url, lineNumber }));
this.emit(Events_1.Events.Page.Console, new ConsoleMessage_1.ConsoleMessage(level, text, [], { url, lineNumber }));
}

@@ -255,3 +282,3 @@ mainFrame() {

const originalCookies = (await this._client.send('Network.getCookies', {
urls: urls.length ? urls : [this.url()]
urls: urls.length ? urls : [this.url()],
})).cookies;

@@ -278,3 +305,3 @@ const unsupportedCookieAttributes = ['priority'];

const startsWithHTTP = pageURL.startsWith('http');
const items = cookies.map(cookie => {
const items = cookies.map((cookie) => {
const item = Object.assign({}, cookie);

@@ -303,4 +330,6 @@ if (!item.url && startsWithHTTP)

await this._client.send('Runtime.addBinding', { name: name });
await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source: expression });
await Promise.all(this.frames().map(frame => frame.evaluate(expression).catch(helper_1.debugError)));
await this._client.send('Page.addScriptToEvaluateOnNewDocument', {
source: expression,
});
await Promise.all(this.frames().map((frame) => frame.evaluate(expression).catch(helper_1.debugError)));
function addPageBinding(bindingName) {

@@ -343,3 +372,3 @@ /* Cast window to any here as we're about to add properties to it

title: event.title,
metrics: this._buildMetricsObject(event.metrics)
metrics: this._buildMetricsObject(event.metrics),
});

@@ -379,3 +408,3 @@ }

const context = this._frameManager.executionContextById(event.executionContextId);
const values = event.args.map(arg => JSHandle_1.createJSHandle(context, arg));
const values = event.args.map((arg) => JSHandle_1.createJSHandle(context, arg));
this._addConsoleMessage(event.type, values, event.stackTrace);

@@ -396,3 +425,8 @@ }

}
this._client.send('Runtime.evaluate', { expression, contextId: event.executionContextId }).catch(helper_1.debugError);
this._client
.send('Runtime.evaluate', {
expression,
contextId: event.executionContextId,
})
.catch(helper_1.debugError);
function deliverResult(name, seq, result) {

@@ -415,3 +449,3 @@ window[name]['callbacks'].get(seq).resolve(result);

if (!this.listenerCount(Events_1.Events.Page.Console)) {
args.forEach(arg => arg.dispose());
args.forEach((arg) => arg.dispose());
return;

@@ -427,8 +461,10 @@ }

}
const location = stackTrace && stackTrace.callFrames.length ? {
url: stackTrace.callFrames[0].url,
lineNumber: stackTrace.callFrames[0].lineNumber,
columnNumber: stackTrace.callFrames[0].columnNumber,
} : {};
const message = new ConsoleMessage(type, textTokens.join(' '), args, location);
const location = stackTrace && stackTrace.callFrames.length
? {
url: stackTrace.callFrames[0].url,
lineNumber: stackTrace.callFrames[0].lineNumber,
columnNumber: stackTrace.callFrames[0].columnNumber,
}
: {};
const message = new ConsoleMessage_1.ConsoleMessage(type, textTokens.join(' '), args, location);
this.emit(Events_1.Events.Page.Console, message);

@@ -463,6 +499,3 @@ }

async reload(options) {
const result = await Promise.all([
this.waitForNavigation(options),
this._client.send('Page.reload')
]);
const result = await Promise.all([this.waitForNavigation(options), this._client.send('Page.reload')]);
return result[0];

@@ -475,12 +508,12 @@ }

if (!this._disconnectPromise)
this._disconnectPromise = new Promise(fulfill => this._client.once(Events_1.Events.CDPSession.Disconnected, () => fulfill(new Error('Target closed'))));
this._disconnectPromise = new Promise((fulfill) => this._client.once(Events_1.Events.CDPSession.Disconnected, () => fulfill(new Error('Target closed'))));
return this._disconnectPromise;
}
async waitForRequest(urlOrPredicate, options = {}) {
const { timeout = this._timeoutSettings.timeout(), } = options;
return helper_1.helper.waitForEvent(this._frameManager.networkManager(), Events_1.Events.NetworkManager.Request, request => {
const { timeout = this._timeoutSettings.timeout() } = options;
return helper_1.helper.waitForEvent(this._frameManager.networkManager(), Events_1.Events.NetworkManager.Request, (request) => {
if (helper_1.helper.isString(urlOrPredicate))
return (urlOrPredicate === request.url());
return urlOrPredicate === request.url();
if (typeof urlOrPredicate === 'function')
return !!(urlOrPredicate(request));
return !!urlOrPredicate(request);
return false;

@@ -490,8 +523,8 @@ }, timeout, this._sessionClosePromise());

async waitForResponse(urlOrPredicate, options = {}) {
const { timeout = this._timeoutSettings.timeout(), } = options;
return helper_1.helper.waitForEvent(this._frameManager.networkManager(), Events_1.Events.NetworkManager.Response, response => {
const { timeout = this._timeoutSettings.timeout() } = options;
return helper_1.helper.waitForEvent(this._frameManager.networkManager(), Events_1.Events.NetworkManager.Response, (response) => {
if (helper_1.helper.isString(urlOrPredicate))
return (urlOrPredicate === response.url());
return urlOrPredicate === response.url();
if (typeof urlOrPredicate === 'function')
return !!(urlOrPredicate(response));
return !!urlOrPredicate(response);
return false;

@@ -523,3 +556,3 @@ }, timeout, this._sessionClosePromise());

this.setViewport(options.viewport),
this.setUserAgent(options.userAgent)
this.setUserAgent(options.userAgent),
]);

@@ -531,3 +564,5 @@ }

this._javascriptEnabled = enabled;
await this._client.send('Emulation.setScriptExecutionDisabled', { value: !enabled });
await this._client.send('Emulation.setScriptExecutionDisabled', {
value: !enabled,
});
}

@@ -539,3 +574,5 @@ async setBypassCSP(enabled) {

helper_1.assert(type === 'screen' || type === 'print' || type === null, 'Unsupported media type: ' + type);
await this._client.send('Emulation.setEmulatedMedia', { media: type || '' });
await this._client.send('Emulation.setEmulatedMedia', {
media: type || '',
});
}

@@ -546,3 +583,3 @@ async emulateMediaFeatures(features) {

if (Array.isArray(features)) {
features.every(mediaFeature => {
features.every((mediaFeature) => {
const name = mediaFeature.name;

@@ -552,3 +589,5 @@ helper_1.assert(/^prefers-(?:color-scheme|reduced-motion)$/.test(name), 'Unsupported media feature: ' + name);

});
await this._client.send('Emulation.setEmulatedMedia', { features: features });
await this._client.send('Emulation.setEmulatedMedia', {
features: features,
});
}

@@ -558,3 +597,5 @@ }

try {
await this._client.send('Emulation.setTimezoneOverride', { timezoneId: timezoneId || '' });
await this._client.send('Emulation.setTimezoneOverride', {
timezoneId: timezoneId || '',
});
}

@@ -577,7 +618,11 @@ catch (error) {

async evaluate(pageFunction, ...args) {
return this._frameManager.mainFrame().evaluate(pageFunction, ...args);
return this._frameManager
.mainFrame()
.evaluate(pageFunction, ...args);
}
async evaluateOnNewDocument(pageFunction, ...args) {
const source = helper_1.helper.evaluationString(pageFunction, ...args);
await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source });
await this._client.send('Page.addScriptToEvaluateOnNewDocument', {
source,
});
}

@@ -606,20 +651,30 @@ async setCacheEnabled(enabled = true) {

if (options.quality) {
helper_1.assert(screenshotType === 'jpeg', 'options.quality is unsupported for the ' + screenshotType + ' screenshots');
helper_1.assert(typeof options.quality === 'number', 'Expected options.quality to be a number but found ' + (typeof options.quality));
helper_1.assert(screenshotType === 'jpeg', 'options.quality is unsupported for the ' +
screenshotType +
' screenshots');
helper_1.assert(typeof options.quality === 'number', 'Expected options.quality to be a number but found ' +
typeof options.quality);
helper_1.assert(Number.isInteger(options.quality), 'Expected options.quality to be an integer');
helper_1.assert(options.quality >= 0 && options.quality <= 100, 'Expected options.quality to be between 0 and 100 (inclusive), got ' + options.quality);
helper_1.assert(options.quality >= 0 && options.quality <= 100, 'Expected options.quality to be between 0 and 100 (inclusive), got ' +
options.quality);
}
helper_1.assert(!options.clip || !options.fullPage, 'options.clip and options.fullPage are exclusive');
if (options.clip) {
helper_1.assert(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' + (typeof options.clip.x));
helper_1.assert(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' + (typeof options.clip.y));
helper_1.assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' + (typeof options.clip.width));
helper_1.assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' + (typeof options.clip.height));
helper_1.assert(typeof options.clip.x === 'number', 'Expected options.clip.x to be a number but found ' +
typeof options.clip.x);
helper_1.assert(typeof options.clip.y === 'number', 'Expected options.clip.y to be a number but found ' +
typeof options.clip.y);
helper_1.assert(typeof options.clip.width === 'number', 'Expected options.clip.width to be a number but found ' +
typeof options.clip.width);
helper_1.assert(typeof options.clip.height === 'number', 'Expected options.clip.height to be a number but found ' +
typeof options.clip.height);
helper_1.assert(options.clip.width !== 0, 'Expected options.clip.width not to be 0.');
helper_1.assert(options.clip.height !== 0, 'Expected options.clip.height not to be 0.');
}
return this._screenshotTaskQueue.postTask(this._screenshotTask.bind(this, screenshotType, options));
return this._screenshotTaskQueue.postTask(() => this._screenshotTask(screenshotType, options));
}
async _screenshotTask(format, options) {
await this._client.send('Target.activateTarget', { targetId: this._target._targetId });
await this._client.send('Target.activateTarget', {
targetId: this._target._targetId,
});
let clip = options.clip ? processClip(options.clip) : undefined;

@@ -633,9 +688,23 @@ if (options.fullPage) {

const { isMobile = false, deviceScaleFactor = 1, isLandscape = false } = this._viewport || {};
const screenOrientation = isLandscape ? { angle: 90, type: 'landscapePrimary' } : { angle: 0, type: 'portraitPrimary' };
await this._client.send('Emulation.setDeviceMetricsOverride', { mobile: isMobile, width, height, deviceScaleFactor, screenOrientation });
const screenOrientation = isLandscape
? { angle: 90, type: 'landscapePrimary' }
: { angle: 0, type: 'portraitPrimary' };
await this._client.send('Emulation.setDeviceMetricsOverride', {
mobile: isMobile,
width,
height,
deviceScaleFactor,
screenOrientation,
});
}
const shouldSetDefaultBackground = options.omitBackground && format === 'png';
if (shouldSetDefaultBackground)
await this._client.send('Emulation.setDefaultBackgroundColorOverride', { color: { r: 0, g: 0, b: 0, a: 0 } });
const result = await this._client.send('Page.captureScreenshot', { format, quality: options.quality, clip });
await this._client.send('Emulation.setDefaultBackgroundColorOverride', {
color: { r: 0, g: 0, b: 0, a: 0 },
});
const result = await this._client.send('Page.captureScreenshot', {
format,
quality: options.quality,
clip,
});
if (shouldSetDefaultBackground)

@@ -645,3 +714,5 @@ await this._client.send('Emulation.setDefaultBackgroundColorOverride');

await this.setViewport(this._viewport);
const buffer = options.encoding === 'base64' ? result.data : Buffer.from(result.data, 'base64');
const buffer = options.encoding === 'base64'
? result.data
: Buffer.from(result.data, 'base64');
if (options.path)

@@ -659,3 +730,3 @@ await writeFileAsync(options.path, buffer);

async pdf(options = {}) {
const { scale = 1, displayHeaderFooter = false, headerTemplate = '', footerTemplate = '', printBackground = false, landscape = false, pageRanges = '', preferCSSPageSize = false, margin = {}, path = null } = options;
const { scale = 1, displayHeaderFooter = false, headerTemplate = '', footerTemplate = '', printBackground = false, landscape = false, pageRanges = '', preferCSSPageSize = false, margin = {}, path = null, } = options;
let paperWidth = 8.5;

@@ -671,3 +742,4 @@ let paperHeight = 11;

paperWidth = convertPrintParameterToInches(options.width) || paperWidth;
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
paperHeight =
convertPrintParameterToInches(options.height) || paperHeight;
}

@@ -693,3 +765,3 @@ const marginTop = convertPrintParameterToInches(margin.top) || 0;

pageRanges,
preferCSSPageSize
preferCSSPageSize,
});

@@ -708,3 +780,5 @@ return await helper_1.helper.readProtocolStream(this._client, result.stream, path);

else {
await this._client._connection.send('Target.closeTarget', { targetId: this._target._targetId });
await this._client._connection.send('Target.closeTarget', {
targetId: this._target._targetId,
});
await this._target._isClosedPromise;

@@ -767,6 +841,6 @@ }

const unitToPixels = {
'px': 1,
'in': 96,
'cm': 37.8,
'mm': 3.78
px: 1,
in: 96,
cm: 37.8,
mm: 3.78,
};

@@ -779,6 +853,6 @@ function convertPrintParameterToInches(parameter) {

// Treat numbers as pixel values to be aligned with phantom's paperSize.
pixels = /** @type {number} */ (parameter);
pixels = /** @type {number} */ parameter;
}
else if (helper_1.helper.isString(parameter)) {
const text = /** @type {string} */ (parameter);
const text = /** @type {string} */ parameter;
let unit = text.substring(text.length - 2).toLowerCase();

@@ -800,47 +874,5 @@ let valueText = '';

else {
throw new Error('page.pdf() Cannot handle parameter type: ' + (typeof parameter));
throw new Error('page.pdf() Cannot handle parameter type: ' + typeof parameter);
}
return pixels / 96;
}
class ConsoleMessage {
constructor(type, text, args, location = {}) {
this._type = type;
this._text = text;
this._args = args;
this._location = location;
}
type() {
return this._type;
}
text() {
return this._text;
}
args() {
return this._args;
}
location() {
return this._location;
}
}
exports.ConsoleMessage = ConsoleMessage;
class FileChooser {
constructor(client, element, event) {
this._handled = false;
this._client = client;
this._element = element;
this._multiple = event.mode !== 'selectSingle';
}
isMultiple() {
return this._multiple;
}
async accept(filePaths) {
helper_1.assert(!this._handled, 'Cannot accept FileChooser which is already handled!');
this._handled = true;
await this._element.uploadFile(...filePaths);
}
async cancel() {
helper_1.assert(!this._handled, 'Cannot cancel FileChooser which is already handled!');
this._handled = true;
}
}
exports.FileChooser = FileChooser;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PipeTransport = void 0;
/**

@@ -24,3 +25,3 @@ * Copyright 2018 Google Inc. All rights reserved.

this._eventListeners = [
helper_1.helper.addEventListener(pipeRead, 'data', buffer => this._dispatch(buffer)),
helper_1.helper.addEventListener(pipeRead, 'data', (buffer) => this._dispatch(buffer)),
helper_1.helper.addEventListener(pipeRead, 'close', () => {

@@ -27,0 +28,0 @@ if (this.onclose)

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Puppeteer = void 0;
/**

@@ -54,3 +55,5 @@ * Copyright 2017 Google Inc. All rights reserved.

get _launcher() {
if (!this._lazyLauncher || this._lazyLauncher.product !== this._productName || this._changedProduct) {
if (!this._lazyLauncher ||
this._lazyLauncher.product !== this._productName ||
this._changedProduct) {
// @ts-ignore

@@ -57,0 +60,0 @@ // eslint-disable-next-line @typescript-eslint/no-var-requires

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getQueryHandlerAndSelector = exports.clearQueryHandlers = exports.customQueryHandlers = exports.unregisterCustomQueryHandler = exports.registerCustomQueryHandler = void 0;
const _customQueryHandlers = new Map();

@@ -56,3 +57,3 @@ function registerCustomQueryHandler(name, handler) {

updatedSelector,
queryHandler
queryHandler,
};

@@ -66,3 +67,3 @@ }

getQueryHandlerAndSelector,
clearQueryHandlers
clearQueryHandlers,
};

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Target = void 0;
const Events_1 = require("./Events");

@@ -23,3 +24,3 @@ const Page_1 = require("./Page");

class Target {
constructor(targetInfo, browserContext, sessionFactory, ignoreHTTPSErrors, defaultViewport, screenshotTaskQueue) {
constructor(targetInfo, browserContext, sessionFactory, ignoreHTTPSErrors, defaultViewport) {
this._targetInfo = targetInfo;

@@ -31,3 +32,2 @@ this._browserContext = browserContext;

this._defaultViewport = defaultViewport;
this._screenshotTaskQueue = screenshotTaskQueue;
/** @type {?Promise<!Puppeteer.Page>} */

@@ -37,3 +37,3 @@ this._pagePromise = null;

this._workerPromise = null;
this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill).then(async (success) => {
this._initializedPromise = new Promise((fulfill) => (this._initializedCallback = fulfill)).then(async (success) => {
if (!success)

@@ -51,4 +51,5 @@ return false;

});
this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
this._isClosedPromise = new Promise((fulfill) => (this._closedCallback = fulfill));
this._isInitialized =
this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
if (this._isInitialized)

@@ -61,5 +62,6 @@ this._initializedCallback(true);

async page() {
if ((this._targetInfo.type === 'page' || this._targetInfo.type === 'background_page') && !this._pagePromise) {
this._pagePromise = this._sessionFactory()
.then(client => Page_1.Page.create(client, this, this._ignoreHTTPSErrors, this._defaultViewport, this._screenshotTaskQueue));
if ((this._targetInfo.type === 'page' ||
this._targetInfo.type === 'background_page') &&
!this._pagePromise) {
this._pagePromise = this._sessionFactory().then((client) => Page_1.Page.create(client, this, this._ignoreHTTPSErrors, this._defaultViewport));
}

@@ -69,8 +71,8 @@ return this._pagePromise;

async worker() {
if (this._targetInfo.type !== 'service_worker' && this._targetInfo.type !== 'shared_worker')
if (this._targetInfo.type !== 'service_worker' &&
this._targetInfo.type !== 'shared_worker')
return null;
if (!this._workerPromise) {
// TODO(einbinder): Make workers send their console logs.
this._workerPromise = this._sessionFactory()
.then(client => new Worker_1.Worker(client, this._targetInfo.url, () => { } /* consoleAPICalled */, () => { } /* exceptionThrown */));
this._workerPromise = this._sessionFactory().then((client) => new Worker_1.Worker(client, this._targetInfo.url, () => { } /* consoleAPICalled */, () => { } /* exceptionThrown */));
}

@@ -84,3 +86,7 @@ return this._workerPromise;

const type = this._targetInfo.type;
if (type === 'page' || type === 'background_page' || type === 'service_worker' || type === 'shared_worker' || type === 'browser')
if (type === 'page' ||
type === 'background_page' ||
type === 'service_worker' ||
type === 'shared_worker' ||
type === 'browser')
return type;

@@ -103,3 +109,4 @@ return 'other';

this._targetInfo = targetInfo;
if (!this._isInitialized && (this._targetInfo.type !== 'page' || this._targetInfo.url !== '')) {
if (!this._isInitialized &&
(this._targetInfo.type !== 'page' || this._targetInfo.url !== '')) {
this._isInitialized = true;

@@ -106,0 +113,0 @@ this._initializedCallback(true);

@@ -18,2 +18,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.TimeoutSettings = void 0;
const DEFAULT_TIMEOUT = 30000;

@@ -20,0 +21,0 @@ class TimeoutSettings {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tracing = void 0;
/**

@@ -28,6 +29,14 @@ * Copyright 2017 Google Inc. All rights reserved.

const defaultCategories = [
'-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline',
'disabled-by-default-devtools.timeline.frame', 'toplevel',
'blink.console', 'blink.user_timing', 'latencyInfo', 'disabled-by-default-devtools.timeline.stack',
'disabled-by-default-v8.cpu_profiler', 'disabled-by-default-v8.cpu_profiler.hires'
'-*',
'devtools.timeline',
'v8.execute',
'disabled-by-default-devtools.timeline',
'disabled-by-default-devtools.timeline.frame',
'toplevel',
'blink.console',
'blink.user_timing',
'latencyInfo',
'disabled-by-default-devtools.timeline.stack',
'disabled-by-default-v8.cpu_profiler',
'disabled-by-default-v8.cpu_profiler.hires',
];

@@ -41,3 +50,3 @@ const { path = null, screenshots = false, categories = defaultCategories, } = options;

transferMode: 'ReturnAsStream',
categories: categories.join(',')
categories: categories.join(','),
});

@@ -47,5 +56,7 @@ }

let fulfill;
const contentPromise = new Promise(x => fulfill = x);
this._client.once('Tracing.tracingComplete', event => {
helper_1.helper.readProtocolStream(this._client, event.stream, this._path).then(fulfill);
const contentPromise = new Promise((x) => (fulfill = x));
this._client.once('Tracing.tracingComplete', (event) => {
helper_1.helper
.readProtocolStream(this._client, event.stream, this._path)
.then(fulfill);
});

@@ -52,0 +63,0 @@ await this._client.send('Tracing.end');

@@ -18,258 +18,387 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.keyDefinitions = void 0;
exports.keyDefinitions = {
'0': { 'keyCode': 48, 'key': '0', 'code': 'Digit0' },
'1': { 'keyCode': 49, 'key': '1', 'code': 'Digit1' },
'2': { 'keyCode': 50, 'key': '2', 'code': 'Digit2' },
'3': { 'keyCode': 51, 'key': '3', 'code': 'Digit3' },
'4': { 'keyCode': 52, 'key': '4', 'code': 'Digit4' },
'5': { 'keyCode': 53, 'key': '5', 'code': 'Digit5' },
'6': { 'keyCode': 54, 'key': '6', 'code': 'Digit6' },
'7': { 'keyCode': 55, 'key': '7', 'code': 'Digit7' },
'8': { 'keyCode': 56, 'key': '8', 'code': 'Digit8' },
'9': { 'keyCode': 57, 'key': '9', 'code': 'Digit9' },
'Power': { 'key': 'Power', 'code': 'Power' },
'Eject': { 'key': 'Eject', 'code': 'Eject' },
'Abort': { 'keyCode': 3, 'code': 'Abort', 'key': 'Cancel' },
'Help': { 'keyCode': 6, 'code': 'Help', 'key': 'Help' },
'Backspace': { 'keyCode': 8, 'code': 'Backspace', 'key': 'Backspace' },
'Tab': { 'keyCode': 9, 'code': 'Tab', 'key': 'Tab' },
'Numpad5': { 'keyCode': 12, 'shiftKeyCode': 101, 'key': 'Clear', 'code': 'Numpad5', 'shiftKey': '5', 'location': 3 },
'NumpadEnter': { 'keyCode': 13, 'code': 'NumpadEnter', 'key': 'Enter', 'text': '\r', 'location': 3 },
'Enter': { 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r' },
'\r': { 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r' },
'\n': { 'keyCode': 13, 'code': 'Enter', 'key': 'Enter', 'text': '\r' },
'ShiftLeft': { 'keyCode': 16, 'code': 'ShiftLeft', 'key': 'Shift', 'location': 1 },
'ShiftRight': { 'keyCode': 16, 'code': 'ShiftRight', 'key': 'Shift', 'location': 2 },
'ControlLeft': { 'keyCode': 17, 'code': 'ControlLeft', 'key': 'Control', 'location': 1 },
'ControlRight': { 'keyCode': 17, 'code': 'ControlRight', 'key': 'Control', 'location': 2 },
'AltLeft': { 'keyCode': 18, 'code': 'AltLeft', 'key': 'Alt', 'location': 1 },
'AltRight': { 'keyCode': 18, 'code': 'AltRight', 'key': 'Alt', 'location': 2 },
'Pause': { 'keyCode': 19, 'code': 'Pause', 'key': 'Pause' },
'CapsLock': { 'keyCode': 20, 'code': 'CapsLock', 'key': 'CapsLock' },
'Escape': { 'keyCode': 27, 'code': 'Escape', 'key': 'Escape' },
'Convert': { 'keyCode': 28, 'code': 'Convert', 'key': 'Convert' },
'NonConvert': { 'keyCode': 29, 'code': 'NonConvert', 'key': 'NonConvert' },
'Space': { 'keyCode': 32, 'code': 'Space', 'key': ' ' },
'Numpad9': { 'keyCode': 33, 'shiftKeyCode': 105, 'key': 'PageUp', 'code': 'Numpad9', 'shiftKey': '9', 'location': 3 },
'PageUp': { 'keyCode': 33, 'code': 'PageUp', 'key': 'PageUp' },
'Numpad3': { 'keyCode': 34, 'shiftKeyCode': 99, 'key': 'PageDown', 'code': 'Numpad3', 'shiftKey': '3', 'location': 3 },
'PageDown': { 'keyCode': 34, 'code': 'PageDown', 'key': 'PageDown' },
'End': { 'keyCode': 35, 'code': 'End', 'key': 'End' },
'Numpad1': { 'keyCode': 35, 'shiftKeyCode': 97, 'key': 'End', 'code': 'Numpad1', 'shiftKey': '1', 'location': 3 },
'Home': { 'keyCode': 36, 'code': 'Home', 'key': 'Home' },
'Numpad7': { 'keyCode': 36, 'shiftKeyCode': 103, 'key': 'Home', 'code': 'Numpad7', 'shiftKey': '7', 'location': 3 },
'ArrowLeft': { 'keyCode': 37, 'code': 'ArrowLeft', 'key': 'ArrowLeft' },
'Numpad4': { 'keyCode': 37, 'shiftKeyCode': 100, 'key': 'ArrowLeft', 'code': 'Numpad4', 'shiftKey': '4', 'location': 3 },
'Numpad8': { 'keyCode': 38, 'shiftKeyCode': 104, 'key': 'ArrowUp', 'code': 'Numpad8', 'shiftKey': '8', 'location': 3 },
'ArrowUp': { 'keyCode': 38, 'code': 'ArrowUp', 'key': 'ArrowUp' },
'ArrowRight': { 'keyCode': 39, 'code': 'ArrowRight', 'key': 'ArrowRight' },
'Numpad6': { 'keyCode': 39, 'shiftKeyCode': 102, 'key': 'ArrowRight', 'code': 'Numpad6', 'shiftKey': '6', 'location': 3 },
'Numpad2': { 'keyCode': 40, 'shiftKeyCode': 98, 'key': 'ArrowDown', 'code': 'Numpad2', 'shiftKey': '2', 'location': 3 },
'ArrowDown': { 'keyCode': 40, 'code': 'ArrowDown', 'key': 'ArrowDown' },
'Select': { 'keyCode': 41, 'code': 'Select', 'key': 'Select' },
'Open': { 'keyCode': 43, 'code': 'Open', 'key': 'Execute' },
'PrintScreen': { 'keyCode': 44, 'code': 'PrintScreen', 'key': 'PrintScreen' },
'Insert': { 'keyCode': 45, 'code': 'Insert', 'key': 'Insert' },
'Numpad0': { 'keyCode': 45, 'shiftKeyCode': 96, 'key': 'Insert', 'code': 'Numpad0', 'shiftKey': '0', 'location': 3 },
'Delete': { 'keyCode': 46, 'code': 'Delete', 'key': 'Delete' },
'NumpadDecimal': { 'keyCode': 46, 'shiftKeyCode': 110, 'code': 'NumpadDecimal', 'key': '\u0000', 'shiftKey': '.', 'location': 3 },
'Digit0': { 'keyCode': 48, 'code': 'Digit0', 'shiftKey': ')', 'key': '0' },
'Digit1': { 'keyCode': 49, 'code': 'Digit1', 'shiftKey': '!', 'key': '1' },
'Digit2': { 'keyCode': 50, 'code': 'Digit2', 'shiftKey': '@', 'key': '2' },
'Digit3': { 'keyCode': 51, 'code': 'Digit3', 'shiftKey': '#', 'key': '3' },
'Digit4': { 'keyCode': 52, 'code': 'Digit4', 'shiftKey': '$', 'key': '4' },
'Digit5': { 'keyCode': 53, 'code': 'Digit5', 'shiftKey': '%', 'key': '5' },
'Digit6': { 'keyCode': 54, 'code': 'Digit6', 'shiftKey': '^', 'key': '6' },
'Digit7': { 'keyCode': 55, 'code': 'Digit7', 'shiftKey': '&', 'key': '7' },
'Digit8': { 'keyCode': 56, 'code': 'Digit8', 'shiftKey': '*', 'key': '8' },
'Digit9': { 'keyCode': 57, 'code': 'Digit9', 'shiftKey': '\(', 'key': '9' },
'KeyA': { 'keyCode': 65, 'code': 'KeyA', 'shiftKey': 'A', 'key': 'a' },
'KeyB': { 'keyCode': 66, 'code': 'KeyB', 'shiftKey': 'B', 'key': 'b' },
'KeyC': { 'keyCode': 67, 'code': 'KeyC', 'shiftKey': 'C', 'key': 'c' },
'KeyD': { 'keyCode': 68, 'code': 'KeyD', 'shiftKey': 'D', 'key': 'd' },
'KeyE': { 'keyCode': 69, 'code': 'KeyE', 'shiftKey': 'E', 'key': 'e' },
'KeyF': { 'keyCode': 70, 'code': 'KeyF', 'shiftKey': 'F', 'key': 'f' },
'KeyG': { 'keyCode': 71, 'code': 'KeyG', 'shiftKey': 'G', 'key': 'g' },
'KeyH': { 'keyCode': 72, 'code': 'KeyH', 'shiftKey': 'H', 'key': 'h' },
'KeyI': { 'keyCode': 73, 'code': 'KeyI', 'shiftKey': 'I', 'key': 'i' },
'KeyJ': { 'keyCode': 74, 'code': 'KeyJ', 'shiftKey': 'J', 'key': 'j' },
'KeyK': { 'keyCode': 75, 'code': 'KeyK', 'shiftKey': 'K', 'key': 'k' },
'KeyL': { 'keyCode': 76, 'code': 'KeyL', 'shiftKey': 'L', 'key': 'l' },
'KeyM': { 'keyCode': 77, 'code': 'KeyM', 'shiftKey': 'M', 'key': 'm' },
'KeyN': { 'keyCode': 78, 'code': 'KeyN', 'shiftKey': 'N', 'key': 'n' },
'KeyO': { 'keyCode': 79, 'code': 'KeyO', 'shiftKey': 'O', 'key': 'o' },
'KeyP': { 'keyCode': 80, 'code': 'KeyP', 'shiftKey': 'P', 'key': 'p' },
'KeyQ': { 'keyCode': 81, 'code': 'KeyQ', 'shiftKey': 'Q', 'key': 'q' },
'KeyR': { 'keyCode': 82, 'code': 'KeyR', 'shiftKey': 'R', 'key': 'r' },
'KeyS': { 'keyCode': 83, 'code': 'KeyS', 'shiftKey': 'S', 'key': 's' },
'KeyT': { 'keyCode': 84, 'code': 'KeyT', 'shiftKey': 'T', 'key': 't' },
'KeyU': { 'keyCode': 85, 'code': 'KeyU', 'shiftKey': 'U', 'key': 'u' },
'KeyV': { 'keyCode': 86, 'code': 'KeyV', 'shiftKey': 'V', 'key': 'v' },
'KeyW': { 'keyCode': 87, 'code': 'KeyW', 'shiftKey': 'W', 'key': 'w' },
'KeyX': { 'keyCode': 88, 'code': 'KeyX', 'shiftKey': 'X', 'key': 'x' },
'KeyY': { 'keyCode': 89, 'code': 'KeyY', 'shiftKey': 'Y', 'key': 'y' },
'KeyZ': { 'keyCode': 90, 'code': 'KeyZ', 'shiftKey': 'Z', 'key': 'z' },
'MetaLeft': { 'keyCode': 91, 'code': 'MetaLeft', 'key': 'Meta', 'location': 1 },
'MetaRight': { 'keyCode': 92, 'code': 'MetaRight', 'key': 'Meta', 'location': 2 },
'ContextMenu': { 'keyCode': 93, 'code': 'ContextMenu', 'key': 'ContextMenu' },
'NumpadMultiply': { 'keyCode': 106, 'code': 'NumpadMultiply', 'key': '*', 'location': 3 },
'NumpadAdd': { 'keyCode': 107, 'code': 'NumpadAdd', 'key': '+', 'location': 3 },
'NumpadSubtract': { 'keyCode': 109, 'code': 'NumpadSubtract', 'key': '-', 'location': 3 },
'NumpadDivide': { 'keyCode': 111, 'code': 'NumpadDivide', 'key': '/', 'location': 3 },
'F1': { 'keyCode': 112, 'code': 'F1', 'key': 'F1' },
'F2': { 'keyCode': 113, 'code': 'F2', 'key': 'F2' },
'F3': { 'keyCode': 114, 'code': 'F3', 'key': 'F3' },
'F4': { 'keyCode': 115, 'code': 'F4', 'key': 'F4' },
'F5': { 'keyCode': 116, 'code': 'F5', 'key': 'F5' },
'F6': { 'keyCode': 117, 'code': 'F6', 'key': 'F6' },
'F7': { 'keyCode': 118, 'code': 'F7', 'key': 'F7' },
'F8': { 'keyCode': 119, 'code': 'F8', 'key': 'F8' },
'F9': { 'keyCode': 120, 'code': 'F9', 'key': 'F9' },
'F10': { 'keyCode': 121, 'code': 'F10', 'key': 'F10' },
'F11': { 'keyCode': 122, 'code': 'F11', 'key': 'F11' },
'F12': { 'keyCode': 123, 'code': 'F12', 'key': 'F12' },
'F13': { 'keyCode': 124, 'code': 'F13', 'key': 'F13' },
'F14': { 'keyCode': 125, 'code': 'F14', 'key': 'F14' },
'F15': { 'keyCode': 126, 'code': 'F15', 'key': 'F15' },
'F16': { 'keyCode': 127, 'code': 'F16', 'key': 'F16' },
'F17': { 'keyCode': 128, 'code': 'F17', 'key': 'F17' },
'F18': { 'keyCode': 129, 'code': 'F18', 'key': 'F18' },
'F19': { 'keyCode': 130, 'code': 'F19', 'key': 'F19' },
'F20': { 'keyCode': 131, 'code': 'F20', 'key': 'F20' },
'F21': { 'keyCode': 132, 'code': 'F21', 'key': 'F21' },
'F22': { 'keyCode': 133, 'code': 'F22', 'key': 'F22' },
'F23': { 'keyCode': 134, 'code': 'F23', 'key': 'F23' },
'F24': { 'keyCode': 135, 'code': 'F24', 'key': 'F24' },
'NumLock': { 'keyCode': 144, 'code': 'NumLock', 'key': 'NumLock' },
'ScrollLock': { 'keyCode': 145, 'code': 'ScrollLock', 'key': 'ScrollLock' },
'AudioVolumeMute': { 'keyCode': 173, 'code': 'AudioVolumeMute', 'key': 'AudioVolumeMute' },
'AudioVolumeDown': { 'keyCode': 174, 'code': 'AudioVolumeDown', 'key': 'AudioVolumeDown' },
'AudioVolumeUp': { 'keyCode': 175, 'code': 'AudioVolumeUp', 'key': 'AudioVolumeUp' },
'MediaTrackNext': { 'keyCode': 176, 'code': 'MediaTrackNext', 'key': 'MediaTrackNext' },
'MediaTrackPrevious': { 'keyCode': 177, 'code': 'MediaTrackPrevious', 'key': 'MediaTrackPrevious' },
'MediaStop': { 'keyCode': 178, 'code': 'MediaStop', 'key': 'MediaStop' },
'MediaPlayPause': { 'keyCode': 179, 'code': 'MediaPlayPause', 'key': 'MediaPlayPause' },
'Semicolon': { 'keyCode': 186, 'code': 'Semicolon', 'shiftKey': ':', 'key': ';' },
'Equal': { 'keyCode': 187, 'code': 'Equal', 'shiftKey': '+', 'key': '=' },
'NumpadEqual': { 'keyCode': 187, 'code': 'NumpadEqual', 'key': '=', 'location': 3 },
'Comma': { 'keyCode': 188, 'code': 'Comma', 'shiftKey': '\<', 'key': ',' },
'Minus': { 'keyCode': 189, 'code': 'Minus', 'shiftKey': '_', 'key': '-' },
'Period': { 'keyCode': 190, 'code': 'Period', 'shiftKey': '>', 'key': '.' },
'Slash': { 'keyCode': 191, 'code': 'Slash', 'shiftKey': '?', 'key': '/' },
'Backquote': { 'keyCode': 192, 'code': 'Backquote', 'shiftKey': '~', 'key': '`' },
'BracketLeft': { 'keyCode': 219, 'code': 'BracketLeft', 'shiftKey': '{', 'key': '[' },
'Backslash': { 'keyCode': 220, 'code': 'Backslash', 'shiftKey': '|', 'key': '\\' },
'BracketRight': { 'keyCode': 221, 'code': 'BracketRight', 'shiftKey': '}', 'key': ']' },
'Quote': { 'keyCode': 222, 'code': 'Quote', 'shiftKey': '"', 'key': '\'' },
'AltGraph': { 'keyCode': 225, 'code': 'AltGraph', 'key': 'AltGraph' },
'Props': { 'keyCode': 247, 'code': 'Props', 'key': 'CrSel' },
'Cancel': { 'keyCode': 3, 'key': 'Cancel', 'code': 'Abort' },
'Clear': { 'keyCode': 12, 'key': 'Clear', 'code': 'Numpad5', 'location': 3 },
'Shift': { 'keyCode': 16, 'key': 'Shift', 'code': 'ShiftLeft', 'location': 1 },
'Control': { 'keyCode': 17, 'key': 'Control', 'code': 'ControlLeft', 'location': 1 },
'Alt': { 'keyCode': 18, 'key': 'Alt', 'code': 'AltLeft', 'location': 1 },
'Accept': { 'keyCode': 30, 'key': 'Accept' },
'ModeChange': { 'keyCode': 31, 'key': 'ModeChange' },
' ': { 'keyCode': 32, 'key': ' ', 'code': 'Space' },
'Print': { 'keyCode': 42, 'key': 'Print' },
'Execute': { 'keyCode': 43, 'key': 'Execute', 'code': 'Open' },
'\u0000': { 'keyCode': 46, 'key': '\u0000', 'code': 'NumpadDecimal', 'location': 3 },
'a': { 'keyCode': 65, 'key': 'a', 'code': 'KeyA' },
'b': { 'keyCode': 66, 'key': 'b', 'code': 'KeyB' },
'c': { 'keyCode': 67, 'key': 'c', 'code': 'KeyC' },
'd': { 'keyCode': 68, 'key': 'd', 'code': 'KeyD' },
'e': { 'keyCode': 69, 'key': 'e', 'code': 'KeyE' },
'f': { 'keyCode': 70, 'key': 'f', 'code': 'KeyF' },
'g': { 'keyCode': 71, 'key': 'g', 'code': 'KeyG' },
'h': { 'keyCode': 72, 'key': 'h', 'code': 'KeyH' },
'i': { 'keyCode': 73, 'key': 'i', 'code': 'KeyI' },
'j': { 'keyCode': 74, 'key': 'j', 'code': 'KeyJ' },
'k': { 'keyCode': 75, 'key': 'k', 'code': 'KeyK' },
'l': { 'keyCode': 76, 'key': 'l', 'code': 'KeyL' },
'm': { 'keyCode': 77, 'key': 'm', 'code': 'KeyM' },
'n': { 'keyCode': 78, 'key': 'n', 'code': 'KeyN' },
'o': { 'keyCode': 79, 'key': 'o', 'code': 'KeyO' },
'p': { 'keyCode': 80, 'key': 'p', 'code': 'KeyP' },
'q': { 'keyCode': 81, 'key': 'q', 'code': 'KeyQ' },
'r': { 'keyCode': 82, 'key': 'r', 'code': 'KeyR' },
's': { 'keyCode': 83, 'key': 's', 'code': 'KeyS' },
't': { 'keyCode': 84, 'key': 't', 'code': 'KeyT' },
'u': { 'keyCode': 85, 'key': 'u', 'code': 'KeyU' },
'v': { 'keyCode': 86, 'key': 'v', 'code': 'KeyV' },
'w': { 'keyCode': 87, 'key': 'w', 'code': 'KeyW' },
'x': { 'keyCode': 88, 'key': 'x', 'code': 'KeyX' },
'y': { 'keyCode': 89, 'key': 'y', 'code': 'KeyY' },
'z': { 'keyCode': 90, 'key': 'z', 'code': 'KeyZ' },
'Meta': { 'keyCode': 91, 'key': 'Meta', 'code': 'MetaLeft', 'location': 1 },
'*': { 'keyCode': 106, 'key': '*', 'code': 'NumpadMultiply', 'location': 3 },
'+': { 'keyCode': 107, 'key': '+', 'code': 'NumpadAdd', 'location': 3 },
'-': { 'keyCode': 109, 'key': '-', 'code': 'NumpadSubtract', 'location': 3 },
'/': { 'keyCode': 111, 'key': '/', 'code': 'NumpadDivide', 'location': 3 },
';': { 'keyCode': 186, 'key': ';', 'code': 'Semicolon' },
'=': { 'keyCode': 187, 'key': '=', 'code': 'Equal' },
',': { 'keyCode': 188, 'key': ',', 'code': 'Comma' },
'.': { 'keyCode': 190, 'key': '.', 'code': 'Period' },
'`': { 'keyCode': 192, 'key': '`', 'code': 'Backquote' },
'[': { 'keyCode': 219, 'key': '[', 'code': 'BracketLeft' },
'\\': { 'keyCode': 220, 'key': '\\', 'code': 'Backslash' },
']': { 'keyCode': 221, 'key': ']', 'code': 'BracketRight' },
'\'': { 'keyCode': 222, 'key': '\'', 'code': 'Quote' },
'Attn': { 'keyCode': 246, 'key': 'Attn' },
'CrSel': { 'keyCode': 247, 'key': 'CrSel', 'code': 'Props' },
'ExSel': { 'keyCode': 248, 'key': 'ExSel' },
'EraseEof': { 'keyCode': 249, 'key': 'EraseEof' },
'Play': { 'keyCode': 250, 'key': 'Play' },
'ZoomOut': { 'keyCode': 251, 'key': 'ZoomOut' },
')': { 'keyCode': 48, 'key': ')', 'code': 'Digit0' },
'!': { 'keyCode': 49, 'key': '!', 'code': 'Digit1' },
'@': { 'keyCode': 50, 'key': '@', 'code': 'Digit2' },
'#': { 'keyCode': 51, 'key': '#', 'code': 'Digit3' },
'$': { 'keyCode': 52, 'key': '$', 'code': 'Digit4' },
'%': { 'keyCode': 53, 'key': '%', 'code': 'Digit5' },
'^': { 'keyCode': 54, 'key': '^', 'code': 'Digit6' },
'&': { 'keyCode': 55, 'key': '&', 'code': 'Digit7' },
'(': { 'keyCode': 57, 'key': '\(', 'code': 'Digit9' },
'A': { 'keyCode': 65, 'key': 'A', 'code': 'KeyA' },
'B': { 'keyCode': 66, 'key': 'B', 'code': 'KeyB' },
'C': { 'keyCode': 67, 'key': 'C', 'code': 'KeyC' },
'D': { 'keyCode': 68, 'key': 'D', 'code': 'KeyD' },
'E': { 'keyCode': 69, 'key': 'E', 'code': 'KeyE' },
'F': { 'keyCode': 70, 'key': 'F', 'code': 'KeyF' },
'G': { 'keyCode': 71, 'key': 'G', 'code': 'KeyG' },
'H': { 'keyCode': 72, 'key': 'H', 'code': 'KeyH' },
'I': { 'keyCode': 73, 'key': 'I', 'code': 'KeyI' },
'J': { 'keyCode': 74, 'key': 'J', 'code': 'KeyJ' },
'K': { 'keyCode': 75, 'key': 'K', 'code': 'KeyK' },
'L': { 'keyCode': 76, 'key': 'L', 'code': 'KeyL' },
'M': { 'keyCode': 77, 'key': 'M', 'code': 'KeyM' },
'N': { 'keyCode': 78, 'key': 'N', 'code': 'KeyN' },
'O': { 'keyCode': 79, 'key': 'O', 'code': 'KeyO' },
'P': { 'keyCode': 80, 'key': 'P', 'code': 'KeyP' },
'Q': { 'keyCode': 81, 'key': 'Q', 'code': 'KeyQ' },
'R': { 'keyCode': 82, 'key': 'R', 'code': 'KeyR' },
'S': { 'keyCode': 83, 'key': 'S', 'code': 'KeyS' },
'T': { 'keyCode': 84, 'key': 'T', 'code': 'KeyT' },
'U': { 'keyCode': 85, 'key': 'U', 'code': 'KeyU' },
'V': { 'keyCode': 86, 'key': 'V', 'code': 'KeyV' },
'W': { 'keyCode': 87, 'key': 'W', 'code': 'KeyW' },
'X': { 'keyCode': 88, 'key': 'X', 'code': 'KeyX' },
'Y': { 'keyCode': 89, 'key': 'Y', 'code': 'KeyY' },
'Z': { 'keyCode': 90, 'key': 'Z', 'code': 'KeyZ' },
':': { 'keyCode': 186, 'key': ':', 'code': 'Semicolon' },
'<': { 'keyCode': 188, 'key': '\<', 'code': 'Comma' },
'_': { 'keyCode': 189, 'key': '_', 'code': 'Minus' },
'>': { 'keyCode': 190, 'key': '>', 'code': 'Period' },
'?': { 'keyCode': 191, 'key': '?', 'code': 'Slash' },
'~': { 'keyCode': 192, 'key': '~', 'code': 'Backquote' },
'{': { 'keyCode': 219, 'key': '{', 'code': 'BracketLeft' },
'|': { 'keyCode': 220, 'key': '|', 'code': 'Backslash' },
'}': { 'keyCode': 221, 'key': '}', 'code': 'BracketRight' },
'"': { 'keyCode': 222, 'key': '"', 'code': 'Quote' },
'SoftLeft': { 'key': 'SoftLeft', 'code': 'SoftLeft', 'location': 4 },
'SoftRight': { 'key': 'SoftRight', 'code': 'SoftRight', 'location': 4 },
'Camera': { 'keyCode': 44, 'key': 'Camera', 'code': 'Camera', 'location': 4 },
'Call': { 'key': 'Call', 'code': 'Call', 'location': 4 },
'EndCall': { 'keyCode': 95, 'key': 'EndCall', 'code': 'EndCall', 'location': 4 },
'VolumeDown': { 'keyCode': 182, 'key': 'VolumeDown', 'code': 'VolumeDown', 'location': 4 },
'VolumeUp': { 'keyCode': 183, 'key': 'VolumeUp', 'code': 'VolumeUp', 'location': 4 },
'0': { keyCode: 48, key: '0', code: 'Digit0' },
'1': { keyCode: 49, key: '1', code: 'Digit1' },
'2': { keyCode: 50, key: '2', code: 'Digit2' },
'3': { keyCode: 51, key: '3', code: 'Digit3' },
'4': { keyCode: 52, key: '4', code: 'Digit4' },
'5': { keyCode: 53, key: '5', code: 'Digit5' },
'6': { keyCode: 54, key: '6', code: 'Digit6' },
'7': { keyCode: 55, key: '7', code: 'Digit7' },
'8': { keyCode: 56, key: '8', code: 'Digit8' },
'9': { keyCode: 57, key: '9', code: 'Digit9' },
Power: { key: 'Power', code: 'Power' },
Eject: { key: 'Eject', code: 'Eject' },
Abort: { keyCode: 3, code: 'Abort', key: 'Cancel' },
Help: { keyCode: 6, code: 'Help', key: 'Help' },
Backspace: { keyCode: 8, code: 'Backspace', key: 'Backspace' },
Tab: { keyCode: 9, code: 'Tab', key: 'Tab' },
Numpad5: {
keyCode: 12,
shiftKeyCode: 101,
key: 'Clear',
code: 'Numpad5',
shiftKey: '5',
location: 3,
},
NumpadEnter: {
keyCode: 13,
code: 'NumpadEnter',
key: 'Enter',
text: '\r',
location: 3,
},
Enter: { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
'\r': { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
'\n': { keyCode: 13, code: 'Enter', key: 'Enter', text: '\r' },
ShiftLeft: { keyCode: 16, code: 'ShiftLeft', key: 'Shift', location: 1 },
ShiftRight: { keyCode: 16, code: 'ShiftRight', key: 'Shift', location: 2 },
ControlLeft: {
keyCode: 17,
code: 'ControlLeft',
key: 'Control',
location: 1,
},
ControlRight: {
keyCode: 17,
code: 'ControlRight',
key: 'Control',
location: 2,
},
AltLeft: { keyCode: 18, code: 'AltLeft', key: 'Alt', location: 1 },
AltRight: { keyCode: 18, code: 'AltRight', key: 'Alt', location: 2 },
Pause: { keyCode: 19, code: 'Pause', key: 'Pause' },
CapsLock: { keyCode: 20, code: 'CapsLock', key: 'CapsLock' },
Escape: { keyCode: 27, code: 'Escape', key: 'Escape' },
Convert: { keyCode: 28, code: 'Convert', key: 'Convert' },
NonConvert: { keyCode: 29, code: 'NonConvert', key: 'NonConvert' },
Space: { keyCode: 32, code: 'Space', key: ' ' },
Numpad9: {
keyCode: 33,
shiftKeyCode: 105,
key: 'PageUp',
code: 'Numpad9',
shiftKey: '9',
location: 3,
},
PageUp: { keyCode: 33, code: 'PageUp', key: 'PageUp' },
Numpad3: {
keyCode: 34,
shiftKeyCode: 99,
key: 'PageDown',
code: 'Numpad3',
shiftKey: '3',
location: 3,
},
PageDown: { keyCode: 34, code: 'PageDown', key: 'PageDown' },
End: { keyCode: 35, code: 'End', key: 'End' },
Numpad1: {
keyCode: 35,
shiftKeyCode: 97,
key: 'End',
code: 'Numpad1',
shiftKey: '1',
location: 3,
},
Home: { keyCode: 36, code: 'Home', key: 'Home' },
Numpad7: {
keyCode: 36,
shiftKeyCode: 103,
key: 'Home',
code: 'Numpad7',
shiftKey: '7',
location: 3,
},
ArrowLeft: { keyCode: 37, code: 'ArrowLeft', key: 'ArrowLeft' },
Numpad4: {
keyCode: 37,
shiftKeyCode: 100,
key: 'ArrowLeft',
code: 'Numpad4',
shiftKey: '4',
location: 3,
},
Numpad8: {
keyCode: 38,
shiftKeyCode: 104,
key: 'ArrowUp',
code: 'Numpad8',
shiftKey: '8',
location: 3,
},
ArrowUp: { keyCode: 38, code: 'ArrowUp', key: 'ArrowUp' },
ArrowRight: { keyCode: 39, code: 'ArrowRight', key: 'ArrowRight' },
Numpad6: {
keyCode: 39,
shiftKeyCode: 102,
key: 'ArrowRight',
code: 'Numpad6',
shiftKey: '6',
location: 3,
},
Numpad2: {
keyCode: 40,
shiftKeyCode: 98,
key: 'ArrowDown',
code: 'Numpad2',
shiftKey: '2',
location: 3,
},
ArrowDown: { keyCode: 40, code: 'ArrowDown', key: 'ArrowDown' },
Select: { keyCode: 41, code: 'Select', key: 'Select' },
Open: { keyCode: 43, code: 'Open', key: 'Execute' },
PrintScreen: { keyCode: 44, code: 'PrintScreen', key: 'PrintScreen' },
Insert: { keyCode: 45, code: 'Insert', key: 'Insert' },
Numpad0: {
keyCode: 45,
shiftKeyCode: 96,
key: 'Insert',
code: 'Numpad0',
shiftKey: '0',
location: 3,
},
Delete: { keyCode: 46, code: 'Delete', key: 'Delete' },
NumpadDecimal: {
keyCode: 46,
shiftKeyCode: 110,
code: 'NumpadDecimal',
key: '\u0000',
shiftKey: '.',
location: 3,
},
Digit0: { keyCode: 48, code: 'Digit0', shiftKey: ')', key: '0' },
Digit1: { keyCode: 49, code: 'Digit1', shiftKey: '!', key: '1' },
Digit2: { keyCode: 50, code: 'Digit2', shiftKey: '@', key: '2' },
Digit3: { keyCode: 51, code: 'Digit3', shiftKey: '#', key: '3' },
Digit4: { keyCode: 52, code: 'Digit4', shiftKey: '$', key: '4' },
Digit5: { keyCode: 53, code: 'Digit5', shiftKey: '%', key: '5' },
Digit6: { keyCode: 54, code: 'Digit6', shiftKey: '^', key: '6' },
Digit7: { keyCode: 55, code: 'Digit7', shiftKey: '&', key: '7' },
Digit8: { keyCode: 56, code: 'Digit8', shiftKey: '*', key: '8' },
Digit9: { keyCode: 57, code: 'Digit9', shiftKey: '(', key: '9' },
KeyA: { keyCode: 65, code: 'KeyA', shiftKey: 'A', key: 'a' },
KeyB: { keyCode: 66, code: 'KeyB', shiftKey: 'B', key: 'b' },
KeyC: { keyCode: 67, code: 'KeyC', shiftKey: 'C', key: 'c' },
KeyD: { keyCode: 68, code: 'KeyD', shiftKey: 'D', key: 'd' },
KeyE: { keyCode: 69, code: 'KeyE', shiftKey: 'E', key: 'e' },
KeyF: { keyCode: 70, code: 'KeyF', shiftKey: 'F', key: 'f' },
KeyG: { keyCode: 71, code: 'KeyG', shiftKey: 'G', key: 'g' },
KeyH: { keyCode: 72, code: 'KeyH', shiftKey: 'H', key: 'h' },
KeyI: { keyCode: 73, code: 'KeyI', shiftKey: 'I', key: 'i' },
KeyJ: { keyCode: 74, code: 'KeyJ', shiftKey: 'J', key: 'j' },
KeyK: { keyCode: 75, code: 'KeyK', shiftKey: 'K', key: 'k' },
KeyL: { keyCode: 76, code: 'KeyL', shiftKey: 'L', key: 'l' },
KeyM: { keyCode: 77, code: 'KeyM', shiftKey: 'M', key: 'm' },
KeyN: { keyCode: 78, code: 'KeyN', shiftKey: 'N', key: 'n' },
KeyO: { keyCode: 79, code: 'KeyO', shiftKey: 'O', key: 'o' },
KeyP: { keyCode: 80, code: 'KeyP', shiftKey: 'P', key: 'p' },
KeyQ: { keyCode: 81, code: 'KeyQ', shiftKey: 'Q', key: 'q' },
KeyR: { keyCode: 82, code: 'KeyR', shiftKey: 'R', key: 'r' },
KeyS: { keyCode: 83, code: 'KeyS', shiftKey: 'S', key: 's' },
KeyT: { keyCode: 84, code: 'KeyT', shiftKey: 'T', key: 't' },
KeyU: { keyCode: 85, code: 'KeyU', shiftKey: 'U', key: 'u' },
KeyV: { keyCode: 86, code: 'KeyV', shiftKey: 'V', key: 'v' },
KeyW: { keyCode: 87, code: 'KeyW', shiftKey: 'W', key: 'w' },
KeyX: { keyCode: 88, code: 'KeyX', shiftKey: 'X', key: 'x' },
KeyY: { keyCode: 89, code: 'KeyY', shiftKey: 'Y', key: 'y' },
KeyZ: { keyCode: 90, code: 'KeyZ', shiftKey: 'Z', key: 'z' },
MetaLeft: { keyCode: 91, code: 'MetaLeft', key: 'Meta', location: 1 },
MetaRight: { keyCode: 92, code: 'MetaRight', key: 'Meta', location: 2 },
ContextMenu: { keyCode: 93, code: 'ContextMenu', key: 'ContextMenu' },
NumpadMultiply: {
keyCode: 106,
code: 'NumpadMultiply',
key: '*',
location: 3,
},
NumpadAdd: { keyCode: 107, code: 'NumpadAdd', key: '+', location: 3 },
NumpadSubtract: {
keyCode: 109,
code: 'NumpadSubtract',
key: '-',
location: 3,
},
NumpadDivide: { keyCode: 111, code: 'NumpadDivide', key: '/', location: 3 },
F1: { keyCode: 112, code: 'F1', key: 'F1' },
F2: { keyCode: 113, code: 'F2', key: 'F2' },
F3: { keyCode: 114, code: 'F3', key: 'F3' },
F4: { keyCode: 115, code: 'F4', key: 'F4' },
F5: { keyCode: 116, code: 'F5', key: 'F5' },
F6: { keyCode: 117, code: 'F6', key: 'F6' },
F7: { keyCode: 118, code: 'F7', key: 'F7' },
F8: { keyCode: 119, code: 'F8', key: 'F8' },
F9: { keyCode: 120, code: 'F9', key: 'F9' },
F10: { keyCode: 121, code: 'F10', key: 'F10' },
F11: { keyCode: 122, code: 'F11', key: 'F11' },
F12: { keyCode: 123, code: 'F12', key: 'F12' },
F13: { keyCode: 124, code: 'F13', key: 'F13' },
F14: { keyCode: 125, code: 'F14', key: 'F14' },
F15: { keyCode: 126, code: 'F15', key: 'F15' },
F16: { keyCode: 127, code: 'F16', key: 'F16' },
F17: { keyCode: 128, code: 'F17', key: 'F17' },
F18: { keyCode: 129, code: 'F18', key: 'F18' },
F19: { keyCode: 130, code: 'F19', key: 'F19' },
F20: { keyCode: 131, code: 'F20', key: 'F20' },
F21: { keyCode: 132, code: 'F21', key: 'F21' },
F22: { keyCode: 133, code: 'F22', key: 'F22' },
F23: { keyCode: 134, code: 'F23', key: 'F23' },
F24: { keyCode: 135, code: 'F24', key: 'F24' },
NumLock: { keyCode: 144, code: 'NumLock', key: 'NumLock' },
ScrollLock: { keyCode: 145, code: 'ScrollLock', key: 'ScrollLock' },
AudioVolumeMute: {
keyCode: 173,
code: 'AudioVolumeMute',
key: 'AudioVolumeMute',
},
AudioVolumeDown: {
keyCode: 174,
code: 'AudioVolumeDown',
key: 'AudioVolumeDown',
},
AudioVolumeUp: { keyCode: 175, code: 'AudioVolumeUp', key: 'AudioVolumeUp' },
MediaTrackNext: {
keyCode: 176,
code: 'MediaTrackNext',
key: 'MediaTrackNext',
},
MediaTrackPrevious: {
keyCode: 177,
code: 'MediaTrackPrevious',
key: 'MediaTrackPrevious',
},
MediaStop: { keyCode: 178, code: 'MediaStop', key: 'MediaStop' },
MediaPlayPause: {
keyCode: 179,
code: 'MediaPlayPause',
key: 'MediaPlayPause',
},
Semicolon: { keyCode: 186, code: 'Semicolon', shiftKey: ':', key: ';' },
Equal: { keyCode: 187, code: 'Equal', shiftKey: '+', key: '=' },
NumpadEqual: { keyCode: 187, code: 'NumpadEqual', key: '=', location: 3 },
Comma: { keyCode: 188, code: 'Comma', shiftKey: '<', key: ',' },
Minus: { keyCode: 189, code: 'Minus', shiftKey: '_', key: '-' },
Period: { keyCode: 190, code: 'Period', shiftKey: '>', key: '.' },
Slash: { keyCode: 191, code: 'Slash', shiftKey: '?', key: '/' },
Backquote: { keyCode: 192, code: 'Backquote', shiftKey: '~', key: '`' },
BracketLeft: { keyCode: 219, code: 'BracketLeft', shiftKey: '{', key: '[' },
Backslash: { keyCode: 220, code: 'Backslash', shiftKey: '|', key: '\\' },
BracketRight: { keyCode: 221, code: 'BracketRight', shiftKey: '}', key: ']' },
Quote: { keyCode: 222, code: 'Quote', shiftKey: '"', key: "'" },
AltGraph: { keyCode: 225, code: 'AltGraph', key: 'AltGraph' },
Props: { keyCode: 247, code: 'Props', key: 'CrSel' },
Cancel: { keyCode: 3, key: 'Cancel', code: 'Abort' },
Clear: { keyCode: 12, key: 'Clear', code: 'Numpad5', location: 3 },
Shift: { keyCode: 16, key: 'Shift', code: 'ShiftLeft', location: 1 },
Control: { keyCode: 17, key: 'Control', code: 'ControlLeft', location: 1 },
Alt: { keyCode: 18, key: 'Alt', code: 'AltLeft', location: 1 },
Accept: { keyCode: 30, key: 'Accept' },
ModeChange: { keyCode: 31, key: 'ModeChange' },
' ': { keyCode: 32, key: ' ', code: 'Space' },
Print: { keyCode: 42, key: 'Print' },
Execute: { keyCode: 43, key: 'Execute', code: 'Open' },
'\u0000': { keyCode: 46, key: '\u0000', code: 'NumpadDecimal', location: 3 },
a: { keyCode: 65, key: 'a', code: 'KeyA' },
b: { keyCode: 66, key: 'b', code: 'KeyB' },
c: { keyCode: 67, key: 'c', code: 'KeyC' },
d: { keyCode: 68, key: 'd', code: 'KeyD' },
e: { keyCode: 69, key: 'e', code: 'KeyE' },
f: { keyCode: 70, key: 'f', code: 'KeyF' },
g: { keyCode: 71, key: 'g', code: 'KeyG' },
h: { keyCode: 72, key: 'h', code: 'KeyH' },
i: { keyCode: 73, key: 'i', code: 'KeyI' },
j: { keyCode: 74, key: 'j', code: 'KeyJ' },
k: { keyCode: 75, key: 'k', code: 'KeyK' },
l: { keyCode: 76, key: 'l', code: 'KeyL' },
m: { keyCode: 77, key: 'm', code: 'KeyM' },
n: { keyCode: 78, key: 'n', code: 'KeyN' },
o: { keyCode: 79, key: 'o', code: 'KeyO' },
p: { keyCode: 80, key: 'p', code: 'KeyP' },
q: { keyCode: 81, key: 'q', code: 'KeyQ' },
r: { keyCode: 82, key: 'r', code: 'KeyR' },
s: { keyCode: 83, key: 's', code: 'KeyS' },
t: { keyCode: 84, key: 't', code: 'KeyT' },
u: { keyCode: 85, key: 'u', code: 'KeyU' },
v: { keyCode: 86, key: 'v', code: 'KeyV' },
w: { keyCode: 87, key: 'w', code: 'KeyW' },
x: { keyCode: 88, key: 'x', code: 'KeyX' },
y: { keyCode: 89, key: 'y', code: 'KeyY' },
z: { keyCode: 90, key: 'z', code: 'KeyZ' },
Meta: { keyCode: 91, key: 'Meta', code: 'MetaLeft', location: 1 },
'*': { keyCode: 106, key: '*', code: 'NumpadMultiply', location: 3 },
'+': { keyCode: 107, key: '+', code: 'NumpadAdd', location: 3 },
'-': { keyCode: 109, key: '-', code: 'NumpadSubtract', location: 3 },
'/': { keyCode: 111, key: '/', code: 'NumpadDivide', location: 3 },
';': { keyCode: 186, key: ';', code: 'Semicolon' },
'=': { keyCode: 187, key: '=', code: 'Equal' },
',': { keyCode: 188, key: ',', code: 'Comma' },
'.': { keyCode: 190, key: '.', code: 'Period' },
'`': { keyCode: 192, key: '`', code: 'Backquote' },
'[': { keyCode: 219, key: '[', code: 'BracketLeft' },
'\\': { keyCode: 220, key: '\\', code: 'Backslash' },
']': { keyCode: 221, key: ']', code: 'BracketRight' },
"'": { keyCode: 222, key: "'", code: 'Quote' },
Attn: { keyCode: 246, key: 'Attn' },
CrSel: { keyCode: 247, key: 'CrSel', code: 'Props' },
ExSel: { keyCode: 248, key: 'ExSel' },
EraseEof: { keyCode: 249, key: 'EraseEof' },
Play: { keyCode: 250, key: 'Play' },
ZoomOut: { keyCode: 251, key: 'ZoomOut' },
')': { keyCode: 48, key: ')', code: 'Digit0' },
'!': { keyCode: 49, key: '!', code: 'Digit1' },
'@': { keyCode: 50, key: '@', code: 'Digit2' },
'#': { keyCode: 51, key: '#', code: 'Digit3' },
$: { keyCode: 52, key: '$', code: 'Digit4' },
'%': { keyCode: 53, key: '%', code: 'Digit5' },
'^': { keyCode: 54, key: '^', code: 'Digit6' },
'&': { keyCode: 55, key: '&', code: 'Digit7' },
'(': { keyCode: 57, key: '(', code: 'Digit9' },
A: { keyCode: 65, key: 'A', code: 'KeyA' },
B: { keyCode: 66, key: 'B', code: 'KeyB' },
C: { keyCode: 67, key: 'C', code: 'KeyC' },
D: { keyCode: 68, key: 'D', code: 'KeyD' },
E: { keyCode: 69, key: 'E', code: 'KeyE' },
F: { keyCode: 70, key: 'F', code: 'KeyF' },
G: { keyCode: 71, key: 'G', code: 'KeyG' },
H: { keyCode: 72, key: 'H', code: 'KeyH' },
I: { keyCode: 73, key: 'I', code: 'KeyI' },
J: { keyCode: 74, key: 'J', code: 'KeyJ' },
K: { keyCode: 75, key: 'K', code: 'KeyK' },
L: { keyCode: 76, key: 'L', code: 'KeyL' },
M: { keyCode: 77, key: 'M', code: 'KeyM' },
N: { keyCode: 78, key: 'N', code: 'KeyN' },
O: { keyCode: 79, key: 'O', code: 'KeyO' },
P: { keyCode: 80, key: 'P', code: 'KeyP' },
Q: { keyCode: 81, key: 'Q', code: 'KeyQ' },
R: { keyCode: 82, key: 'R', code: 'KeyR' },
S: { keyCode: 83, key: 'S', code: 'KeyS' },
T: { keyCode: 84, key: 'T', code: 'KeyT' },
U: { keyCode: 85, key: 'U', code: 'KeyU' },
V: { keyCode: 86, key: 'V', code: 'KeyV' },
W: { keyCode: 87, key: 'W', code: 'KeyW' },
X: { keyCode: 88, key: 'X', code: 'KeyX' },
Y: { keyCode: 89, key: 'Y', code: 'KeyY' },
Z: { keyCode: 90, key: 'Z', code: 'KeyZ' },
':': { keyCode: 186, key: ':', code: 'Semicolon' },
'<': { keyCode: 188, key: '<', code: 'Comma' },
_: { keyCode: 189, key: '_', code: 'Minus' },
'>': { keyCode: 190, key: '>', code: 'Period' },
'?': { keyCode: 191, key: '?', code: 'Slash' },
'~': { keyCode: 192, key: '~', code: 'Backquote' },
'{': { keyCode: 219, key: '{', code: 'BracketLeft' },
'|': { keyCode: 220, key: '|', code: 'Backslash' },
'}': { keyCode: 221, key: '}', code: 'BracketRight' },
'"': { keyCode: 222, key: '"', code: 'Quote' },
SoftLeft: { key: 'SoftLeft', code: 'SoftLeft', location: 4 },
SoftRight: { key: 'SoftRight', code: 'SoftRight', location: 4 },
Camera: { keyCode: 44, key: 'Camera', code: 'Camera', location: 4 },
Call: { key: 'Call', code: 'Call', location: 4 },
EndCall: { keyCode: 95, key: 'EndCall', code: 'EndCall', location: 4 },
VolumeDown: {
keyCode: 182,
key: 'VolumeDown',
code: 'VolumeDown',
location: 4,
},
VolumeUp: { keyCode: 183, key: 'VolumeUp', code: 'VolumeUp', location: 4 },
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketTransport = void 0;
/**

@@ -22,3 +23,3 @@ * Copyright 2018 Google Inc. All rights reserved.

this._ws = ws;
this._ws.addEventListener('message', event => {
this._ws.addEventListener('message', (event) => {
if (this.onmessage)

@@ -25,0 +26,0 @@ this.onmessage.call(null, event.data);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Worker = void 0;
/**

@@ -27,7 +28,7 @@ * Copyright 2018 Google Inc. All rights reserved.

this._url = url;
this._executionContextPromise = new Promise(x => this._executionContextCallback = x);
this._executionContextPromise = new Promise((x) => (this._executionContextCallback = x));
let jsHandleFactory;
this._client.once('Runtime.executionContextCreated', async (event) => {
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
jsHandleFactory = remoteObject => new JSHandle_1.JSHandle(executionContext, client, remoteObject);
jsHandleFactory = (remoteObject) => new JSHandle_1.JSHandle(executionContext, client, remoteObject);
const executionContext = new ExecutionContext_1.ExecutionContext(client, event.context, null);

@@ -38,4 +39,4 @@ this._executionContextCallback(executionContext);

this._client.send('Runtime.enable', {}).catch(helper_1.debugError);
this._client.on('Runtime.consoleAPICalled', event => consoleAPICalled(event.type, event.args.map(jsHandleFactory), event.stackTrace));
this._client.on('Runtime.exceptionThrown', exception => exceptionThrown(exception.exceptionDetails));
this._client.on('Runtime.consoleAPICalled', (event) => consoleAPICalled(event.type, event.args.map(jsHandleFactory), event.stackTrace));
this._client.on('Runtime.exceptionThrown', (exception) => exceptionThrown(exception.exceptionDetails));
}

@@ -42,0 +43,0 @@ url() {

{
"name": "puppeteer-core",
"version": "3.0.4",
"version": "3.1.0",
"description": "A high-level API to control headless Chrome over the DevTools Protocol",

@@ -11,3 +11,3 @@ "main": "index.js",

"puppeteer": {
"chromium_revision": "737027",
"chromium_revision": "756035",
"firefox_revision": "latest"

@@ -27,2 +27,3 @@ },

"eslint": "([ \"$CI\" = true ] && eslint --ext js --ext ts --quiet -f codeframe . || eslint --ext js --ext ts .)",
"eslint-fix": "eslint --ext js --ext ts --fix .",
"lint": "npm run eslint && npm run tsc && npm run doc",

@@ -63,2 +64,3 @@ "doc": "node utils/doclint/cli.js",

"@types/node": "^10.17.14",
"@types/proxy-from-env": "^1.0.1",
"@types/rimraf": "^2.0.2",

@@ -72,3 +74,5 @@ "@types/tar-fs": "^1.16.2",

"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-mocha": "^6.3.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-unicorn": "^19.0.1",

@@ -83,4 +87,6 @@ "esprima": "^4.0.0",

"pngjs": "^5.0.0",
"prettier": "^2.0.5",
"sinon": "^9.0.2",
"text-diff": "^1.0.1",
"typescript": "3.8.3"
"typescript": "3.9.2"
},

@@ -87,0 +93,0 @@ "browser": {

@@ -9,3 +9,3 @@ # Puppeteer

###### [API](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md) | [FAQ](#faq) | [Contributing](https://github.com/puppeteer/puppeteer/blob/master/CONTRIBUTING.md) | [Troubleshooting](https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md)
###### [API](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md) | [FAQ](#faq) | [Contributing](https://github.com/puppeteer/puppeteer/blob/master/CONTRIBUTING.md) | [Troubleshooting](https://github.com/puppeteer/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, or to download a different browser, see [Environment variables](https://github.com/puppeteer/puppeteer/blob/v3.0.4/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, or to download a different browser, see [Environment variables](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#environment-variables).

@@ -68,3 +68,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/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#).
of `Browser`, open pages, and then manipulate them with [Puppeteer's API](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#).

@@ -94,3 +94,3 @@ **Example** - navigating to https://example.com and saving a screenshot as *example.png*:

Puppeteer sets an initial page size to 800×600px, which defines the screenshot size. The page size can be customized with [`Page.setViewport()`](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#pagesetviewportviewport).
Puppeteer sets an initial page size to 800×600px, which defines the screenshot size. The page size can be customized with [`Page.setViewport()`](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#pagesetviewportviewport).

@@ -120,3 +120,3 @@ **Example** - create a PDF.

See [`Page.pdf()`](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#pagepdfoptions) for more information about creating pdfs.
See [`Page.pdf()`](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#pagepdfoptions) for more information about creating pdfs.

@@ -156,3 +156,3 @@ **Example** - evaluate script in the context of the page

See [`Page.evaluate()`](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#pageevaluatepagefunction-args) for more information on `evaluate` and related methods like `evaluateOnNewDocument` and `exposeFunction`.
See [`Page.evaluate()`](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#pageevaluatepagefunction-args) for more information on `evaluate` and related methods like `evaluateOnNewDocument` and `exposeFunction`.

@@ -166,3 +166,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/puppeteer/puppeteer/blob/v3.0.4/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/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#puppeteerlaunchoptions) when launching a browser:

@@ -183,3 +183,3 @@ ```js

You can also use Puppeteer with Firefox Nightly (experimental support). See [`Puppeteer.launch()`](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#puppeteerlaunchoptions) for more information.
You can also use Puppeteer with Firefox Nightly (experimental support). See [`Puppeteer.launch()`](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#puppeteerlaunchoptions) for more information.

@@ -196,3 +196,3 @@ 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.

- [API Documentation](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md)
- [API Documentation](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md)
- [Examples](https://github.com/puppeteer/puppeteer/tree/master/examples/)

@@ -324,3 +324,3 @@ - [Community list of Puppeteer resources](https://github.com/transitive-bullshit/awesome-puppeteer)

From Puppeteer v2.1.0 onwards you can specify [`puppeteer.launch({product: 'firefox'})`](https://github.com/puppeteer/puppeteer/blob/v3.0.4/docs/api.md#puppeteerlaunchoptions) to run your Puppeteer scripts in Firefox Nightly, without any additional custom patches. While [an older experiment](https://www.npmjs.com/package/puppeteer-firefox) required a patched version of Firefox, [the current approach](https://wiki.mozilla.org/Remote) works with “stock” Firefox.
From Puppeteer v2.1.0 onwards you can specify [`puppeteer.launch({product: 'firefox'})`](https://github.com/puppeteer/puppeteer/blob/v3.1.0/docs/api.md#puppeteerlaunchoptions) to run your Puppeteer scripts in Firefox Nightly, without any additional custom patches. While [an older experiment](https://www.npmjs.com/package/puppeteer-firefox) required a patched version of Firefox, [the current approach](https://wiki.mozilla.org/Remote) works with “stock” Firefox.

@@ -421,3 +421,3 @@ We will continue to collaborate with other browser vendors to bring Puppeteer support to browsers such as Safari.

* 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/puppeteer/puppeteer/blob/v3.0.4/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/puppeteer/puppeteer/blob/v3.1.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).

@@ -424,0 +424,0 @@

@@ -20,3 +20,3 @@ /**

const fs = require('fs');
const {promisify} = require('util');
const { promisify } = require('util');

@@ -26,3 +26,6 @@ const exec = promisify(child_process.exec);

const fileExists = async filePath => fsAccess(filePath).then(() => true).catch(() => false);
const fileExists = async (filePath) =>
fsAccess(filePath)
.then(() => true)
.catch(() => false);
/*

@@ -42,3 +45,3 @@

async function compileTypeScript() {
return exec('npm run tsc').catch(error => {
return exec('npm run tsc').catch((error) => {
console.error('Error running TypeScript', error);

@@ -59,5 +62,4 @@ process.exit(1);

// It's being run as node typescript-if-required.js, not require('..')
if (require.main === module)
compileTypeScriptIfRequired();
if (require.main === module) compileTypeScriptIfRequired();
module.exports = compileTypeScriptIfRequired;

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