puppeteer-core
Advanced tools
Comparing version 3.0.1 to 3.0.2
@@ -21,3 +21,2 @@ /** | ||
for (const className in api) { | ||
// Puppeteer-web excludes certain classes from bundle, e.g. BrowserFetcher. | ||
if (typeof api[className] === 'function') | ||
@@ -30,3 +29,2 @@ helper.installAsyncStackHooks(api[className]); | ||
// If node does not support async await, use the compiled version. | ||
const Puppeteer = require('./lib/Puppeteer'); | ||
@@ -33,0 +31,0 @@ const packageJson = require('./package.json'); |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,55 +17,7 @@ * Copyright 2018 Google Inc. All rights reserved. | ||
*/ | ||
// Used as a TypeDef | ||
// eslint-disable-next-line no-unused-vars | ||
const { CDPSession } = require('./Connection'); | ||
// Used as a TypeDef | ||
// eslint-disable-next-line no-unused-vars | ||
const { ElementHandle } = require('./JSHandle'); | ||
/** | ||
* @typedef {Object} SerializedAXNode | ||
* @property {string} role | ||
* | ||
* @property {string=} name | ||
* @property {string|number=} value | ||
* @property {string=} description | ||
* | ||
* @property {string=} keyshortcuts | ||
* @property {string=} roledescription | ||
* @property {string=} valuetext | ||
* | ||
* @property {boolean=} disabled | ||
* @property {boolean=} expanded | ||
* @property {boolean=} focused | ||
* @property {boolean=} modal | ||
* @property {boolean=} multiline | ||
* @property {boolean=} multiselectable | ||
* @property {boolean=} readonly | ||
* @property {boolean=} required | ||
* @property {boolean=} selected | ||
* | ||
* @property {boolean|"mixed"=} checked | ||
* @property {boolean|"mixed"=} pressed | ||
* | ||
* @property {number=} level | ||
* @property {number=} valuemin | ||
* @property {number=} valuemax | ||
* | ||
* @property {string=} autocomplete | ||
* @property {string=} haspopup | ||
* @property {string=} invalid | ||
* @property {string=} orientation | ||
* | ||
* @property {Array<SerializedAXNode>=} children | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class Accessibility { | ||
/** | ||
* @param {!CDPSession} client | ||
*/ | ||
constructor(client) { | ||
this._client = client; | ||
} | ||
/** | ||
* @param {{interestingOnly?: boolean, root?: ?ElementHandle}=} options | ||
* @return {!Promise<!SerializedAXNode>} | ||
*/ | ||
async snapshot(options = {}) { | ||
@@ -87,3 +40,2 @@ const { interestingOnly = true, root = null, } = options; | ||
return serializeTree(needle)[0]; | ||
/** @type {!Set<!AXNode>} */ | ||
const interestingNodes = new Set(); | ||
@@ -96,2 +48,3 @@ collectInterestingNodes(interestingNodes, defaultRoot, false); | ||
} | ||
exports.Accessibility = Accessibility; | ||
/** | ||
@@ -111,9 +64,3 @@ * @param {!Set<!AXNode>} collection | ||
} | ||
/** | ||
* @param {!AXNode} node | ||
* @param {!Set<!AXNode>=} whitelistedNodes | ||
* @return {!Array<!SerializedAXNode>} | ||
*/ | ||
function serializeTree(node, whitelistedNodes) { | ||
/** @type {!Array<!SerializedAXNode>} */ | ||
const children = []; | ||
@@ -130,8 +77,3 @@ for (const child of node._children) | ||
class AXNode { | ||
/** | ||
* @param {!Protocol.Accessibility.AXNode} payload | ||
*/ | ||
constructor(payload) { | ||
this._payload = payload; | ||
/** @type {!Array<!AXNode>} */ | ||
this._children = []; | ||
@@ -143,5 +85,5 @@ this._richlyEditable = 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'; | ||
this._cachedHasFocusableChild; | ||
for (const property of this._payload.properties || []) { | ||
@@ -160,5 +102,2 @@ if (property.name === 'editable') { | ||
} | ||
/** | ||
* @return {boolean} | ||
*/ | ||
_isPlainTextField() { | ||
@@ -171,5 +110,2 @@ if (this._richlyEditable) | ||
} | ||
/** | ||
* @return {boolean} | ||
*/ | ||
_isTextOnlyObject() { | ||
@@ -180,5 +116,2 @@ const role = this._role; | ||
} | ||
/** | ||
* @return {boolean} | ||
*/ | ||
_hasFocusableChild() { | ||
@@ -196,6 +129,2 @@ if (this._cachedHasFocusableChild === undefined) { | ||
} | ||
/** | ||
* @param {function(AXNode):boolean} predicate | ||
* @return {?AXNode} | ||
*/ | ||
find(predicate) { | ||
@@ -211,5 +140,2 @@ if (predicate(this)) | ||
} | ||
/** | ||
* @return {boolean} | ||
*/ | ||
isLeafNode() { | ||
@@ -250,5 +176,2 @@ if (!this._children.length) | ||
} | ||
/** | ||
* @return {boolean} | ||
*/ | ||
isControl() { | ||
@@ -299,7 +222,3 @@ switch (this._role) { | ||
} | ||
/** | ||
* @return {!SerializedAXNode} | ||
*/ | ||
serialize() { | ||
/** @type {!Map<string, number|string|boolean>} */ | ||
const properties = new Map(); | ||
@@ -314,9 +233,5 @@ for (const property of this._payload.properties || []) | ||
properties.set('description', this._payload.description.value); | ||
/** @type {SerializedAXNode} */ | ||
const node = { | ||
role: this._role | ||
}; | ||
/** @enum {'name'|'value'|'description'|'keyshortcuts'|'roledescription'|'valuetext'} */ | ||
let UserStringProperties; // eslint-disable-line no-unused-vars | ||
/** @type {!Array<UserStringProperties>} */ | ||
const userStringProperties = [ | ||
@@ -330,6 +245,3 @@ 'name', | ||
]; | ||
/** | ||
* @param {UserStringProperties} key | ||
*/ | ||
const getUserStringPropertyValue = key => /** @type string */ (properties.get(key)); | ||
const getUserStringPropertyValue = (key) => properties.get(key); | ||
for (const userStringProperty of userStringProperties) { | ||
@@ -340,5 +252,2 @@ if (!properties.has(userStringProperty)) | ||
} | ||
/** @enum {'disabled'|'expanded'|'focused'|'modal'|'multiline'|'multiselectable'|'readonly'|'required'|'selected'} */ | ||
let BooleanProperties; // eslint-disable-line no-unused-vars | ||
/** @type {!Array<BooleanProperties>} */ | ||
const booleanProperties = [ | ||
@@ -355,6 +264,3 @@ 'disabled', | ||
]; | ||
/** | ||
* @param {BooleanProperties} key | ||
*/ | ||
const getBooleanPropertyValue = key => /** @type boolean */ (properties.get(key)); | ||
const getBooleanPropertyValue = (key) => properties.get(key); | ||
for (const booleanProperty of booleanProperties) { | ||
@@ -370,5 +276,2 @@ // WebArea's treat focus differently than other nodes. They report whether their frame has focus, | ||
} | ||
/** @enum {'checked'|'pressed'} */ | ||
let TristateProperties; // eslint-disable-line no-unused-vars | ||
/** @type {!Array<TristateProperties>} */ | ||
const tristateProperties = [ | ||
@@ -384,5 +287,2 @@ 'checked', | ||
} | ||
/** @enum {'level'|'valuemax'|'valuemin'} */ | ||
let NumericalProperties; // eslint-disable-line no-unused-vars | ||
/** @type {!Array<NumericalProperties>} */ | ||
const numericalProperties = [ | ||
@@ -393,6 +293,3 @@ 'level', | ||
]; | ||
/** | ||
* @param {NumericalProperties} key | ||
*/ | ||
const getNumericalPropertyValue = key => /** @type number */ (properties.get(key)); | ||
const getNumericalPropertyValue = (key) => properties.get(key); | ||
for (const numericalProperty of numericalProperties) { | ||
@@ -403,5 +300,2 @@ if (!properties.has(numericalProperty)) | ||
} | ||
/** @enum {'autocomplete'|'haspopup'|'invalid'|'orientation'} */ | ||
let TokenProperties; // eslint-disable-line no-unused-vars | ||
/** @type {!Array<TokenProperties>} */ | ||
const tokenProperties = [ | ||
@@ -413,6 +307,3 @@ 'autocomplete', | ||
]; | ||
/** | ||
* @param {TokenProperties} key | ||
*/ | ||
const getTokenPropertyValue = key => /** @type string */ (properties.get(key)); | ||
const getTokenPropertyValue = (key) => properties.get(key); | ||
for (const tokenProperty of tokenProperties) { | ||
@@ -426,6 +317,2 @@ const value = getTokenPropertyValue(tokenProperty); | ||
} | ||
/** | ||
* @param {!Array<!Protocol.Accessibility.AXNode>} payloads | ||
* @return {!AXNode} | ||
*/ | ||
static createTree(payloads) { | ||
@@ -443,2 +330,1 @@ /** @type {!Map<string, !AXNode>} */ | ||
} | ||
module.exports = { Accessibility }; |
@@ -20,3 +20,3 @@ /** | ||
BrowserContext: require('./Browser').BrowserContext, | ||
BrowserFetcher: require('./BrowserFetcher'), | ||
BrowserFetcher: require('./BrowserFetcher').BrowserFetcher, | ||
CDPSession: require('./Connection').CDPSession, | ||
@@ -41,4 +41,4 @@ ConsoleMessage: require('./Page').ConsoleMessage, | ||
Touchscreen: require('./Input').Touchscreen, | ||
Tracing: require('./Tracing'), | ||
Tracing: require('./Tracing').Tracing, | ||
Worker: require('./Worker').Worker, | ||
}; |
@@ -309,4 +309,4 @@ /** | ||
['accessibility-events', 'accessibilityEvents'], | ||
['clipboard-read', 'clipboardRead'], | ||
['clipboard-write', 'clipboardWrite'], | ||
['clipboard-read', 'clipboardReadWrite'], | ||
['clipboard-write', 'clipboardReadWrite'], | ||
['payment-handler', 'paymentHandler'], | ||
@@ -313,0 +313,0 @@ // chrome-specific permissions we have. |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,16 +17,18 @@ * Copyright 2017 Google Inc. All rights reserved. | ||
*/ | ||
const os = require('os'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
const childProcess = require('child_process'); | ||
const extract = require('extract-zip'); | ||
const debugFetcher = require('debug')(`puppeteer:fetcher`); | ||
const URL = require('url'); | ||
const { helper, assert } = require('./helper'); | ||
const removeRecursive = require('rimraf'); | ||
// @ts-ignore | ||
const ProxyAgent = require('https-proxy-agent'); | ||
// @ts-ignore | ||
const getProxyForUrl = require('proxy-from-env').getProxyForUrl; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const os = require("os"); | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const util = require("util"); | ||
const childProcess = require("child_process"); | ||
const https = require("https"); | ||
const http = require("http"); | ||
const extract = require("extract-zip"); | ||
const debug = require("debug"); | ||
const removeRecursive = require("rimraf"); | ||
const URL = require("url"); | ||
const ProxyAgent = require("https-proxy-agent"); | ||
const proxy_from_env_1 = require("proxy-from-env"); | ||
const helper_1 = require("./helper"); | ||
const debugFetcher = debug(`puppeteer:fetcher`); | ||
const downloadURLs = { | ||
@@ -55,8 +58,2 @@ chrome: { | ||
}; | ||
/** | ||
* @param {string} product | ||
* @param {string} platform | ||
* @param {string} revision | ||
* @return {string} | ||
*/ | ||
function archiveName(product, platform, revision) { | ||
@@ -76,3 +73,2 @@ if (product === 'chrome') { | ||
} | ||
return null; | ||
} | ||
@@ -90,69 +86,57 @@ /** | ||
} | ||
const readdirAsync = helper.promisify(fs.readdir.bind(fs)); | ||
const mkdirAsync = helper.promisify(fs.mkdir.bind(fs)); | ||
const unlinkAsync = helper.promisify(fs.unlink.bind(fs)); | ||
const chmodAsync = helper.promisify(fs.chmod.bind(fs)); | ||
const readdirAsync = helper_1.helper.promisify(fs.readdir.bind(fs)); | ||
const mkdirAsync = helper_1.helper.promisify(fs.mkdir.bind(fs)); | ||
const unlinkAsync = helper_1.helper.promisify(fs.unlink.bind(fs)); | ||
const chmodAsync = helper_1.helper.promisify(fs.chmod.bind(fs)); | ||
function existsAsync(filePath) { | ||
let fulfill = null; | ||
const promise = new Promise(x => fulfill = x); | ||
fs.access(filePath, err => fulfill(!err)); | ||
return promise; | ||
return new Promise(resolve => { | ||
fs.access(filePath, err => resolve(!err)); | ||
}); | ||
} | ||
/** | ||
*/ | ||
class BrowserFetcher { | ||
/** | ||
* @param {string} projectRoot | ||
* @param {!BrowserFetcher.Options=} options | ||
*/ | ||
constructor(projectRoot, options = {}) { | ||
this._product = (options.product || 'chrome').toLowerCase(); | ||
assert(this._product === 'chrome' || this._product === 'firefox', `Unknown product: "${options.product}"`); | ||
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._downloadHost = options.host || browserConfig[this._product].host; | ||
this._platform = options.platform || ''; | ||
if (!this._platform) { | ||
const platform = os.platform(); | ||
if (platform === 'darwin') | ||
this._platform = 'mac'; | ||
else if (platform === 'linux') | ||
this._platform = 'linux'; | ||
else if (platform === 'win32') | ||
this._platform = os.arch() === 'x64' ? 'win64' : 'win32'; | ||
assert(this._platform, 'Unsupported platform: ' + os.platform()); | ||
this.setPlatform(options.platform); | ||
helper_1.assert(downloadURLs[this._product][this._platform], 'Unsupported platform: ' + this._platform); | ||
} | ||
setPlatform(platformFromOptions) { | ||
if (platformFromOptions) { | ||
this._platform = platformFromOptions; | ||
return; | ||
} | ||
assert(downloadURLs[this._product][this._platform], 'Unsupported platform: ' + this._platform); | ||
const platform = os.platform(); | ||
if (platform === 'darwin') | ||
this._platform = 'mac'; | ||
else if (platform === 'linux') | ||
this._platform = 'linux'; | ||
else if (platform === 'win32') | ||
this._platform = os.arch() === 'x64' ? 'win64' : 'win32'; | ||
else | ||
helper_1.assert(this._platform, 'Unsupported platform: ' + os.platform()); | ||
} | ||
/** | ||
* @return {string} | ||
*/ | ||
platform() { | ||
return this._platform; | ||
} | ||
/** | ||
* @return {string} | ||
*/ | ||
product() { | ||
return this._product; | ||
} | ||
/** | ||
* @return {string} | ||
*/ | ||
host() { | ||
return this._downloadHost; | ||
} | ||
/** | ||
* @param {string} revision | ||
* @return {!Promise<boolean>} | ||
*/ | ||
canDownload(revision) { | ||
const url = downloadURL(this._product, this._platform, this._downloadHost, revision); | ||
let resolve; | ||
const promise = new Promise(x => resolve = x); | ||
const request = httpRequest(url, 'HEAD', response => { | ||
resolve(response.statusCode === 200); | ||
return new Promise(resolve => { | ||
const request = httpRequest(url, 'HEAD', response => { | ||
resolve(response.statusCode === 200); | ||
}); | ||
request.on('error', error => { | ||
console.error(error); | ||
resolve(false); | ||
}); | ||
}); | ||
request.on('error', error => { | ||
console.error(error); | ||
resolve(false); | ||
}); | ||
return promise; | ||
} | ||
@@ -186,5 +170,2 @@ /** | ||
} | ||
/** | ||
* @return {!Promise<!Array<string>>} | ||
*/ | ||
async localRevisions() { | ||
@@ -196,14 +177,7 @@ if (!await existsAsync(this._downloadsFolder)) | ||
} | ||
/** | ||
* @param {string} revision | ||
*/ | ||
async remove(revision) { | ||
const folderPath = this._getFolderPath(revision); | ||
assert(await existsAsync(folderPath), `Failed to remove: revision ${revision} is not downloaded`); | ||
helper_1.assert(await existsAsync(folderPath), `Failed to remove: revision ${revision} is not downloaded`); | ||
await new Promise(fulfill => removeRecursive(folderPath, fulfill)); | ||
} | ||
/** | ||
* @param {string} revision | ||
* @return {!BrowserFetcher.RevisionInfo} | ||
*/ | ||
revisionInfo(revision) { | ||
@@ -248,7 +222,3 @@ const folderPath = this._getFolderPath(revision); | ||
} | ||
module.exports = BrowserFetcher; | ||
/** | ||
* @param {string} folderPath | ||
* @return {?{product: string, platform: string, revision: string}} | ||
*/ | ||
exports.BrowserFetcher = BrowserFetcher; | ||
function parseFolderPath(product, folderPath) { | ||
@@ -299,9 +269,2 @@ const name = path.basename(folderPath); | ||
} | ||
/** | ||
* Install from a zip, tar.bz2 or dmg file. | ||
* | ||
* @param {string} archivePath | ||
* @param {string} folderPath | ||
* @return {!Promise<?Error>} | ||
*/ | ||
function install(archivePath, folderPath) { | ||
@@ -318,13 +281,40 @@ debugFetcher(`Installing ${archivePath} to ${folderPath}`); | ||
} | ||
/** | ||
* @param {string} zipPath | ||
* @param {string} folderPath | ||
* @return {!Promise<?Error>} | ||
*/ | ||
async function extractZip(zipPath, folderPath) { | ||
try { | ||
await extract(zipPath, { dir: folderPath }); | ||
const nodeVersion = process.version; | ||
/* There is currently a bug with extract-zip and Node v14.0.0 that | ||
* causes extractZip to silently fail: | ||
* https://github.com/puppeteer/puppeteer/issues/5719 | ||
* | ||
* Rather than silenty fail if the user is on Node 14 we instead | ||
* detect that and throw an error directing the user to that bug. The | ||
* rejection message below is surfaced to the user in the command | ||
* line. | ||
* | ||
* The issue seems to be in streams never resolving so we wrap the | ||
* call in a timeout and give it 10s to resolve before deciding on | ||
* an error. | ||
* | ||
* If the user is on Node < 14 we maintain the behaviour we had before | ||
* this patch. | ||
*/ | ||
if (nodeVersion.startsWith('v14.')) { | ||
let timeoutReject; | ||
const timeoutPromise = new Promise((resolve, reject) => { timeoutReject = reject; }); | ||
const timeoutToken = setTimeout(() => { | ||
const error = new Error(`Puppeteer currently does not work on Node v14 due to an upstream bug. Please see: https://github.com/puppeteer/puppeteer/issues/5719 for details.`); | ||
timeoutReject(error); | ||
}, 10 * 1000); | ||
await Promise.race([ | ||
extract(zipPath, { dir: folderPath }), | ||
timeoutPromise | ||
]); | ||
clearTimeout(timeoutToken); | ||
} | ||
catch (error) { | ||
return error; | ||
else { | ||
try { | ||
await extract(zipPath, { dir: folderPath }); | ||
} | ||
catch (error) { | ||
return error; | ||
} | ||
} | ||
@@ -338,4 +328,5 @@ } | ||
function extractTar(tarPath, folderPath) { | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const tar = require('tar-fs'); | ||
// @ts-ignore | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const bzip = require('unbzip2-stream'); | ||
@@ -362,3 +353,3 @@ return new Promise((fulfill, reject) => { | ||
const mountCommand = `hdiutil attach -nobrowse -noautoopen "${dmgPath}"`; | ||
childProcess.exec(mountCommand, (err, stdout, stderr) => { | ||
childProcess.exec(mountCommand, (err, stdout) => { | ||
if (err) | ||
@@ -376,3 +367,3 @@ return reject(err); | ||
debugFetcher(`Copying ${copyPath} to ${folderPath}`); | ||
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, (err, stdout) => { | ||
childProcess.exec(`cp -R "${copyPath}" "${folderPath}"`, err => { | ||
if (err) | ||
@@ -399,6 +390,8 @@ reject(err); | ||
function httpRequest(url, method, response) { | ||
/** @type {Object} */ | ||
let options = URL.parse(url); | ||
options.method = method; | ||
const proxyURL = getProxyForUrl(url); | ||
const urlParsed = URL.parse(url); | ||
let options = { | ||
...urlParsed, | ||
method, | ||
}; | ||
const proxyURL = proxy_from_env_1.getProxyForUrl(url); | ||
if (proxyURL) { | ||
@@ -414,10 +407,12 @@ if (url.startsWith('http:')) { | ||
else { | ||
/** @type {Object} */ | ||
const parsedProxyURL = URL.parse(proxyURL); | ||
parsedProxyURL.secureProxy = parsedProxyURL.protocol === 'https:'; | ||
options.agent = new ProxyAgent(parsedProxyURL); | ||
const proxyOptions = { | ||
...parsedProxyURL, | ||
secureProxy: parsedProxyURL.protocol === 'https:', | ||
}; | ||
options.agent = new ProxyAgent(proxyOptions); | ||
options.rejectUnauthorized = false; | ||
} | ||
} | ||
const requestCallback = res => { | ||
const requestCallback = (res) => { | ||
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) | ||
@@ -429,22 +424,6 @@ httpRequest(res.headers.location, method, response); | ||
const request = options.protocol === 'https:' ? | ||
require('https').request(options, requestCallback) : | ||
require('http').request(options, requestCallback); | ||
https.request(options, requestCallback) : | ||
http.request(options, requestCallback); | ||
request.end(); | ||
return request; | ||
} | ||
/** | ||
* @typedef {Object} BrowserFetcher.Options | ||
* @property {string=} platform | ||
* @property {string=} product | ||
* @property {string=} path | ||
* @property {string=} host | ||
*/ | ||
/** | ||
* @typedef {Object} BrowserFetcher.RevisionInfo | ||
* @property {string} folderPath | ||
* @property {string} executablePath | ||
* @property {string} url | ||
* @property {boolean} local | ||
* @property {string} revision | ||
* @property {string} product | ||
*/ |
@@ -188,3 +188,3 @@ /** | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
*/ | ||
@@ -191,0 +191,0 @@ async setContent(html, options = {}) { |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,2 +17,3 @@ * Copyright 2018 Google Inc. All rights reserved. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class CustomError extends Error { | ||
@@ -26,4 +28,2 @@ constructor(message) { | ||
} | ||
module.exports = { | ||
TimeoutError, | ||
}; | ||
exports.TimeoutError = TimeoutError; |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,3 +17,4 @@ * Copyright 2019 Google Inc. All rights reserved. | ||
*/ | ||
const Events = { | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Events = { | ||
Page: { | ||
@@ -73,2 +75,1 @@ Close: 'close', | ||
}; | ||
module.exports = { Events }; |
import { Browser as RealBrowser, BrowserContext as RealBrowserContext} from './Browser.js'; | ||
import {Target as RealTarget} from './Target.js'; | ||
import {Page as RealPage} from './Page.js'; | ||
import {Mouse as RealMouse, Keyboard as RealKeyboard, Touchscreen as RealTouchscreen} from './Input.js'; | ||
import {Frame as RealFrame, FrameManager as RealFrameManager} from './FrameManager.js'; | ||
@@ -11,5 +10,2 @@ import {DOMWorld as RealDOMWorld} from './DOMWorld.js'; | ||
module Puppeteer { | ||
export class Mouse extends RealMouse {} | ||
export class Keyboard extends RealKeyboard {} | ||
export class Touchscreen extends RealTouchscreen {} | ||
export class Browser extends RealBrowser {} | ||
@@ -26,2 +22,8 @@ export class BrowserContext extends RealBrowserContext {} | ||
/* TODO(jacktfranklin@): once DOMWorld, Page, and FrameManager are in TS | ||
* we can remove this and instead use the type defined in LifeCycleWatcher | ||
*/ | ||
export type PuppeteerLifeCycleEvent = 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'; | ||
export interface ConnectionTransport { | ||
@@ -28,0 +30,0 @@ send(string); |
@@ -84,3 +84,3 @@ /** | ||
* @param {string} url | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -127,3 +127,3 @@ */ | ||
* @param {!Puppeteer.Frame} frame | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -374,3 +374,3 @@ */ | ||
* @param {string} url | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -382,3 +382,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -458,3 +458,3 @@ */ | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
*/ | ||
@@ -461,0 +461,0 @@ async setContent(html, options = {}) { |
@@ -18,10 +18,9 @@ "use strict"; | ||
*/ | ||
const Errors = require("./Errors"); | ||
const Errors_1 = require("./Errors"); | ||
const debug = require("debug"); | ||
const fs = require("fs"); | ||
const promisify = require("./promisify"); | ||
const { TimeoutError } = Errors; | ||
const openAsync = promisify(fs.open); | ||
const writeAsync = promisify(fs.write); | ||
const closeAsync = promisify(fs.close); | ||
const util_1 = require("util"); | ||
const openAsync = util_1.promisify(fs.open); | ||
const writeAsync = util_1.promisify(fs.write); | ||
const closeAsync = util_1.promisify(fs.close); | ||
exports.debugError = debug('puppeteer:error'); | ||
@@ -123,3 +122,3 @@ function assert(value, message) { | ||
eventTimeout = setTimeout(() => { | ||
rejectCallback(new TimeoutError('Timeout exceeded while waiting for event')); | ||
rejectCallback(new Errors_1.TimeoutError('Timeout exceeded while waiting for event')); | ||
}, timeout); | ||
@@ -156,3 +155,3 @@ } | ||
let reject; | ||
const timeoutError = new TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`); | ||
const timeoutError = new Errors_1.TimeoutError(`waiting for ${taskName} failed: timeout ${timeout}ms exceeded`); | ||
const timeoutPromise = new Promise((resolve, x) => reject = x); | ||
@@ -196,3 +195,3 @@ let timeoutTimer = null; | ||
exports.helper = { | ||
promisify, | ||
promisify: util_1.promisify, | ||
evaluationString, | ||
@@ -199,0 +198,0 @@ readProtocolStream, |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,28 +17,11 @@ * Copyright 2017 Google Inc. All rights reserved. | ||
*/ | ||
const { assert } = require('./helper'); | ||
// CDPSession is used only as a typedef | ||
// eslint-disable-next-line no-unused-vars | ||
const { CDPSession } = require('./Connection'); | ||
const { keyDefinitions } = require('./USKeyboardLayout'); | ||
/** | ||
* @typedef {Object} KeyDescription | ||
* @property {number} keyCode | ||
* @property {string} key | ||
* @property {string} text | ||
* @property {string} code | ||
* @property {number} location | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const helper_1 = require("./helper"); | ||
const USKeyboardLayout_1 = require("./USKeyboardLayout"); | ||
class Keyboard { | ||
/** | ||
* @param {!CDPSession} client | ||
*/ | ||
constructor(client) { | ||
this._client = client; | ||
this._modifiers = 0; | ||
this._pressedKeys = new Set(); | ||
this._client = client; | ||
} | ||
/** | ||
* @param {string} key | ||
* @param {{text?: string}=} options | ||
*/ | ||
async down(key, options = { text: undefined }) { | ||
@@ -62,6 +46,2 @@ const description = this._keyDescriptionForString(key); | ||
} | ||
/** | ||
* @param {string} key | ||
* @return {number} | ||
*/ | ||
_modifierBit(key) { | ||
@@ -78,6 +58,2 @@ if (key === 'Alt') | ||
} | ||
/** | ||
* @param {string} keyString | ||
* @return {KeyDescription} | ||
*/ | ||
_keyDescriptionForString(keyString) { | ||
@@ -92,4 +68,4 @@ const shift = this._modifiers & 8; | ||
}; | ||
const definition = keyDefinitions[keyString]; | ||
assert(definition, `Unknown key: "${keyString}"`); | ||
const definition = USKeyboardLayout_1.keyDefinitions[keyString]; | ||
helper_1.assert(definition, `Unknown key: "${keyString}"`); | ||
if (definition.key) | ||
@@ -118,5 +94,2 @@ description.key = definition.key; | ||
} | ||
/** | ||
* @param {string} key | ||
*/ | ||
async up(key) { | ||
@@ -135,16 +108,12 @@ const description = this._keyDescriptionForString(key); | ||
} | ||
/** | ||
* @param {string} char | ||
*/ | ||
async sendCharacter(char) { | ||
await this._client.send('Input.insertText', { text: char }); | ||
} | ||
/** | ||
* @param {string} text | ||
* @param {{delay: (number|undefined)}=} options | ||
*/ | ||
charIsKey(char) { | ||
return !!USKeyboardLayout_1.keyDefinitions[char]; | ||
} | ||
async type(text, options) { | ||
const delay = (options && options.delay) || null; | ||
for (const char of text) { | ||
if (keyDefinitions[char]) { | ||
if (this.charIsKey(char)) { | ||
await this.press(char, { delay }); | ||
@@ -159,6 +128,2 @@ } | ||
} | ||
/** | ||
* @param {string} key | ||
* @param {!{delay?: number, text?: string}=} options | ||
*/ | ||
async press(key, options = {}) { | ||
@@ -172,2 +137,3 @@ const { delay = null } = options; | ||
} | ||
exports.Keyboard = Keyboard; | ||
class Mouse { | ||
@@ -179,14 +145,8 @@ /** | ||
constructor(client, keyboard) { | ||
this._client = client; | ||
this._keyboard = keyboard; | ||
this._x = 0; | ||
this._y = 0; | ||
/** @type {'none'|'left'|'right'|'middle'} */ | ||
this._button = 'none'; | ||
this._client = client; | ||
this._keyboard = keyboard; | ||
} | ||
/** | ||
* @param {number} x | ||
* @param {number} y | ||
* @param {!{steps?: number}=} options | ||
*/ | ||
async move(x, y, options = {}) { | ||
@@ -207,7 +167,2 @@ const { steps = 1 } = options; | ||
} | ||
/** | ||
* @param {number} x | ||
* @param {number} y | ||
* @param {!{delay?: number, button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
async click(x, y, options = {}) { | ||
@@ -231,5 +186,2 @@ const { delay = null } = options; | ||
} | ||
/** | ||
* @param {!{button?: "left"|"right"|"middle", clickCount?: number}=} options | ||
*/ | ||
async down(options = {}) { | ||
@@ -263,7 +215,4 @@ const { button = 'left', clickCount = 1 } = options; | ||
} | ||
exports.Mouse = Mouse; | ||
class Touchscreen { | ||
/** | ||
* @param {CDPSession} client | ||
* @param {Keyboard} keyboard | ||
*/ | ||
constructor(client, keyboard) { | ||
@@ -298,2 +247,2 @@ this._client = client; | ||
} | ||
module.exports = { Keyboard, Mouse, Touchscreen }; | ||
exports.Touchscreen = Touchscreen; |
@@ -252,3 +252,19 @@ "use strict"; | ||
const path = require('path'); | ||
const files = filePaths.map(filePath => path.resolve(filePath)); | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const fs = require('fs'); | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const { promisify } = require('util'); | ||
const access = promisify(fs.access); | ||
// Locate all files and confirm that they exist. | ||
const files = await Promise.all(filePaths.map(async (filePath) => { | ||
const resolvedPath = path.resolve(filePath); | ||
try { | ||
await access(resolvedPath, fs.constants.R_OK); | ||
} | ||
catch (error) { | ||
if (error.code === 'ENOENT') | ||
throw new Error(`${filePath} does not exist or is not readable`); | ||
} | ||
return resolvedPath; | ||
})); | ||
const { objectId } = this._remoteObject; | ||
@@ -255,0 +271,0 @@ const { node } = await this._client.send('DOM.describeNode', { objectId }); |
@@ -23,3 +23,3 @@ /** | ||
const childProcess = require('child_process'); | ||
const BrowserFetcher = require('./BrowserFetcher'); | ||
const { BrowserFetcher } = require('./BrowserFetcher'); | ||
const { Connection } = require('./Connection'); | ||
@@ -26,0 +26,0 @@ const { Browser } = require('./Browser'); |
@@ -0,1 +1,2 @@ | ||
"use strict"; | ||
/** | ||
@@ -16,12 +17,13 @@ * Copyright 2019 Google Inc. All rights reserved. | ||
*/ | ||
const { helper, assert } = require('./helper'); | ||
const { Events } = require('./Events'); | ||
const { TimeoutError } = require('./Errors'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const helper_1 = require("./helper"); | ||
const Events_1 = require("./Events"); | ||
const Errors_1 = require("./Errors"); | ||
const puppeteerToProtocolLifecycle = new Map([ | ||
['load', 'load'], | ||
['domcontentloaded', 'DOMContentLoaded'], | ||
['networkidle0', 'networkIdle'], | ||
['networkidle2', 'networkAlmostIdle'], | ||
]); | ||
class LifecycleWatcher { | ||
/** | ||
* @param {!Puppeteer.FrameManager} frameManager | ||
* @param {!Puppeteer.Frame} frame | ||
* @param {string|!Array<string>} waitUntil | ||
* @param {number} timeout | ||
*/ | ||
constructor(frameManager, frame, waitUntil, timeout) { | ||
@@ -34,3 +36,3 @@ if (Array.isArray(waitUntil)) | ||
const protocolEvent = puppeteerToProtocolLifecycle.get(value); | ||
assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value); | ||
helper_1.assert(protocolEvent, 'Unknown value for options.waitUntil: ' + value); | ||
return protocolEvent; | ||
@@ -45,7 +47,7 @@ }); | ||
this._eventListeners = [ | ||
helper.addEventListener(frameManager._client, Events.CDPSession.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper.addEventListener(this._frameManager, Events.FrameManager.LifecycleEvent, this._checkLifecycleComplete.bind(this)), | ||
helper.addEventListener(this._frameManager, Events.FrameManager.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)), | ||
helper.addEventListener(this._frameManager, Events.FrameManager.FrameDetached, this._onFrameDetached.bind(this)), | ||
helper.addEventListener(this._frameManager.networkManager(), Events.NetworkManager.Request, this._onRequest.bind(this)), | ||
helper_1.helper.addEventListener(frameManager._client, Events_1.Events.CDPSession.Disconnected, () => this._terminate(new Error('Navigation failed because browser has disconnected!'))), | ||
helper_1.helper.addEventListener(this._frameManager, Events_1.Events.FrameManager.LifecycleEvent, this._checkLifecycleComplete.bind(this)), | ||
helper_1.helper.addEventListener(this._frameManager, Events_1.Events.FrameManager.FrameNavigatedWithinDocument, this._navigatedWithinDocument.bind(this)), | ||
helper_1.helper.addEventListener(this._frameManager, Events_1.Events.FrameManager.FrameDetached, this._onFrameDetached.bind(this)), | ||
helper_1.helper.addEventListener(this._frameManager.networkManager(), Events_1.Events.NetworkManager.Request, this._onRequest.bind(this)), | ||
]; | ||
@@ -67,5 +69,2 @@ this._sameDocumentNavigationPromise = new Promise(fulfill => { | ||
} | ||
/** | ||
* @param {!Puppeteer.Request} request | ||
*/ | ||
_onRequest(request) { | ||
@@ -76,5 +75,2 @@ if (request.frame() !== this._frame || !request.isNavigationRequest()) | ||
} | ||
/** | ||
* @param {!Puppeteer.Frame} frame | ||
*/ | ||
_onFrameDetached(frame) { | ||
@@ -87,41 +83,20 @@ if (this._frame === frame) { | ||
} | ||
/** | ||
* @return {?Puppeteer.Response} | ||
*/ | ||
navigationResponse() { | ||
return this._navigationRequest ? this._navigationRequest.response() : null; | ||
} | ||
/** | ||
* @param {!Error} error | ||
*/ | ||
_terminate(error) { | ||
this._terminationCallback.call(null, error); | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
*/ | ||
sameDocumentNavigationPromise() { | ||
return this._sameDocumentNavigationPromise; | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
*/ | ||
newDocumentNavigationPromise() { | ||
return this._newDocumentNavigationPromise; | ||
} | ||
/** | ||
* @return {!Promise} | ||
*/ | ||
lifecyclePromise() { | ||
return this._lifecyclePromise; | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
*/ | ||
timeoutOrTerminationPromise() { | ||
return Promise.race([this._timeoutPromise, this._terminationPromise]); | ||
} | ||
/** | ||
* @return {!Promise<?Error>} | ||
*/ | ||
_createTimeoutPromise() { | ||
@@ -132,7 +107,4 @@ if (!this._timeout) | ||
return new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._timeout)) | ||
.then(() => new TimeoutError(errorMessage)); | ||
.then(() => new Errors_1.TimeoutError(errorMessage)); | ||
} | ||
/** | ||
* @param {!Puppeteer.Frame} frame | ||
*/ | ||
_navigatedWithinDocument(frame) { | ||
@@ -173,12 +145,6 @@ if (frame !== this._frame) | ||
dispose() { | ||
helper.removeEventListeners(this._eventListeners); | ||
helper_1.helper.removeEventListeners(this._eventListeners); | ||
clearTimeout(this._maximumTimer); | ||
} | ||
} | ||
const puppeteerToProtocolLifecycle = new Map([ | ||
['load', 'load'], | ||
['domcontentloaded', 'DOMContentLoaded'], | ||
['networkidle0', 'networkIdle'], | ||
['networkidle2', 'networkAlmostIdle'], | ||
]); | ||
module.exports = { LifecycleWatcher }; | ||
exports.LifecycleWatcher = LifecycleWatcher; |
@@ -27,3 +27,3 @@ /** | ||
const { Keyboard, Mouse, Touchscreen } = require('./Input'); | ||
const Tracing = require('./Tracing'); | ||
const { Tracing } = require('./Tracing'); | ||
const { helper, debugError, assert } = require('./helper'); | ||
@@ -613,3 +613,3 @@ const { Coverage } = require('./Coverage'); | ||
* @param {string} html | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
*/ | ||
@@ -621,3 +621,3 @@ async setContent(html, options) { | ||
* @param {string} url | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{referer?: string, timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -629,3 +629,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -642,3 +642,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -685,3 +685,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -693,3 +693,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -701,3 +701,3 @@ */ | ||
/** | ||
* @param {!{timeout?: number, waitUntil?: string|!Array<string>}=} options | ||
* @param {!{timeout?: number, waitUntil?: !Puppeteer.PuppeteerLifeCycleEvent|!Array<!Puppeteer.PuppeteerLifeCycleEvent>}=} options | ||
* @return {!Promise<?Puppeteer.Response>} | ||
@@ -704,0 +704,0 @@ */ |
@@ -17,3 +17,3 @@ /** | ||
const Launcher = require('./Launcher'); | ||
const BrowserFetcher = require('./BrowserFetcher'); | ||
const { BrowserFetcher } = require('./BrowserFetcher'); | ||
const Errors = require('./Errors'); | ||
@@ -118,4 +118,14 @@ const DeviceDescriptors = require('./DeviceDescriptors'); | ||
} | ||
/** TODO(jacktfranklin@): Once this file is TS we can type this | ||
* using the BrowserFectcherOptions interface. | ||
*/ | ||
/** | ||
* @param {!BrowserFetcher.Options=} options | ||
* @typedef {Object} BrowserFetcherOptions | ||
* @property {('linux'|'mac'|'win32'|'win64')=} platform | ||
* @property {('chrome'|'firefox')=} product | ||
* @property {string=} path | ||
* @property {string=} host | ||
*/ | ||
/** | ||
* @param {!BrowserFetcherOptions} options | ||
* @return {!BrowserFetcher} | ||
@@ -122,0 +132,0 @@ */ |
@@ -0,1 +1,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
@@ -16,20 +18,11 @@ * Copyright 2017 Google Inc. All rights reserved. | ||
*/ | ||
const { helper, assert } = require('./helper'); | ||
// Used as a TypeDef | ||
// eslint-disable-next-line no-unused-vars | ||
const { CDPSession } = require('./Connection'); | ||
const helper_1 = require("./helper"); | ||
class Tracing { | ||
/** | ||
* @param {!CDPSession} client | ||
*/ | ||
constructor(client) { | ||
this._client = client; | ||
this._recording = false; | ||
this._path = ''; | ||
this._client = client; | ||
} | ||
/** | ||
* @param {!{path?: string, screenshots?: boolean, categories?: !Array<string>}} options | ||
*/ | ||
async start(options = {}) { | ||
assert(!this._recording, 'Cannot start recording trace while already recording trace.'); | ||
helper_1.assert(!this._recording, 'Cannot start recording trace while already recording trace.'); | ||
const defaultCategories = [ | ||
@@ -51,5 +44,2 @@ '-*', 'devtools.timeline', 'v8.execute', 'disabled-by-default-devtools.timeline', | ||
} | ||
/** | ||
* @return {!Promise<!Buffer>} | ||
*/ | ||
async stop() { | ||
@@ -59,3 +49,3 @@ let fulfill; | ||
this._client.once('Tracing.tracingComplete', event => { | ||
helper.readProtocolStream(this._client, event.stream, this._path).then(fulfill); | ||
helper_1.helper.readProtocolStream(this._client, event.stream, this._path).then(fulfill); | ||
}); | ||
@@ -67,2 +57,2 @@ await this._client.send('Tracing.end'); | ||
} | ||
module.exports = Tracing; | ||
exports.Tracing = Tracing; |
@@ -0,1 +1,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
@@ -16,16 +18,7 @@ * Copyright 2018 Google Inc. All rights reserved. | ||
*/ | ||
const EventEmitter = require('events'); | ||
const { debugError } = require('./helper'); | ||
const { ExecutionContext } = require('./ExecutionContext'); | ||
const { JSHandle } = require('./JSHandle'); | ||
// Used as a TypeDef | ||
// eslint-disable-next-line no-unused-vars | ||
const { CDPSession } = require('./Connection'); | ||
class Worker extends EventEmitter { | ||
/** | ||
* @param {CDPSession} client | ||
* @param {string} url | ||
* @param {function(string, !Array<!JSHandle>, Protocol.Runtime.StackTrace=):void} consoleAPICalled | ||
* @param {function(!Protocol.Runtime.ExceptionDetails):void} exceptionThrown | ||
*/ | ||
const events_1 = require("events"); | ||
const helper_1 = require("./helper"); | ||
const ExecutionContext_1 = require("./ExecutionContext"); | ||
const JSHandle_1 = require("./JSHandle"); | ||
class Worker extends events_1.EventEmitter { | ||
constructor(client, url, consoleAPICalled, exceptionThrown) { | ||
@@ -36,39 +29,23 @@ super(); | ||
this._executionContextPromise = new Promise(x => this._executionContextCallback = x); | ||
/** @type {function(!Protocol.Runtime.RemoteObject):!JSHandle} */ | ||
let jsHandleFactory; | ||
this._client.once('Runtime.executionContextCreated', async (event) => { | ||
jsHandleFactory = remoteObject => new JSHandle(executionContext, client, remoteObject); | ||
const executionContext = new ExecutionContext(client, event.context, null); | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
jsHandleFactory = remoteObject => new JSHandle_1.JSHandle(executionContext, client, remoteObject); | ||
const executionContext = new ExecutionContext_1.ExecutionContext(client, event.context, null); | ||
this._executionContextCallback(executionContext); | ||
}); | ||
// This might fail if the target is closed before we recieve all execution contexts. | ||
this._client.send('Runtime.enable', {}).catch(debugError); | ||
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)); | ||
} | ||
/** | ||
* @return {string} | ||
*/ | ||
url() { | ||
return this._url; | ||
} | ||
/** | ||
* @return {!Promise<ExecutionContext>} | ||
*/ | ||
async executionContext() { | ||
return this._executionContextPromise; | ||
} | ||
/** | ||
* @param {Function|string} pageFunction | ||
* @param {!Array<*>} args | ||
* @return {!Promise<*>} | ||
*/ | ||
async evaluate(pageFunction, ...args) { | ||
return (await this._executionContextPromise).evaluate(pageFunction, ...args); | ||
} | ||
/** | ||
* @param {Function|string} pageFunction | ||
* @param {!Array<*>} args | ||
* @return {!Promise<!JSHandle>} | ||
*/ | ||
async evaluateHandle(pageFunction, ...args) { | ||
@@ -78,2 +55,2 @@ return (await this._executionContextPromise).evaluateHandle(pageFunction, ...args); | ||
} | ||
module.exports = { Worker }; | ||
exports.Worker = Worker; |
{ | ||
"name": "puppeteer-core", | ||
"version": "3.0.1", | ||
"version": "3.0.2", | ||
"description": "A high-level API to control headless Chrome over the DevTools Protocol", | ||
@@ -29,5 +29,3 @@ "main": "index.js", | ||
"apply-next-version": "node utils/apply_next_version.js", | ||
"bundle": "npm run tsc && npx browserify -r ./index.js:puppeteer -o utils/browser/puppeteer-web.js", | ||
"test-types": "node utils/doclint/generate_types && tsc --version && tsc -p utils/doclint/generate_types/test/", | ||
"unit-bundle": "mocha --config mocha-config/browser-bundle-tests.js", | ||
"update-protocol-d-ts": "node utils/protocol-types-generator", | ||
@@ -75,3 +73,3 @@ "test-install": "scripts/test-install.sh" | ||
"expect": "^25.2.7", | ||
"jpeg-js": "^0.3.4", | ||
"jpeg-js": "^0.3.7", | ||
"minimist": "^1.2.0", | ||
@@ -81,3 +79,3 @@ "mocha": "^7.1.1", | ||
"pixelmatch": "^4.0.2", | ||
"pngjs": "^3.3.3", | ||
"pngjs": "^5.0.0", | ||
"text-diff": "^1.0.1", | ||
@@ -84,0 +82,0 @@ "typescript": "3.8.3" |
@@ -9,3 +9,3 @@ # Puppeteer | ||
###### [API](https://github.com/puppeteer/puppeteer/blob/v3.0.1/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.0.2/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.1/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.0.2/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.1/docs/api.md#). | ||
of `Browser`, open pages, and then manipulate them with [Puppeteer's API](https://github.com/puppeteer/puppeteer/blob/v3.0.2/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.1/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.0.2/docs/api.md#pagesetviewportviewport). | ||
@@ -120,3 +120,3 @@ **Example** - create a PDF. | ||
See [`Page.pdf()`](https://github.com/puppeteer/puppeteer/blob/v3.0.1/docs/api.md#pagepdfoptions) for more information about creating pdfs. | ||
See [`Page.pdf()`](https://github.com/puppeteer/puppeteer/blob/v3.0.2/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.1/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.0.2/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.1/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.0.2/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.1/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.0.2/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.1/docs/api.md) | ||
- [API Documentation](https://github.com/puppeteer/puppeteer/blob/v3.0.2/docs/api.md) | ||
- [Examples](https://github.com/puppeteer/puppeteer/tree/master/examples/) | ||
@@ -312,3 +312,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.1/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.0.2/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. | ||
@@ -409,3 +409,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.1/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.0.2/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). | ||
@@ -412,0 +412,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
13
914282
24071
48