Change let into const (#457)
This patch: - changes `let` into `const` throughout codebase - adds eslint check to prefer const over let
This commit is contained in:
parent
5d6d3e0a81
commit
1f9b4fb4c8
@ -47,6 +47,7 @@ module.exports = {
|
||||
"new-parens": 2,
|
||||
"func-call-spacing": 2,
|
||||
"arrow-parens": [2, "as-needed"],
|
||||
"prefer-const": 2,
|
||||
|
||||
// anti-patterns
|
||||
"no-var": 2,
|
||||
|
@ -628,5 +628,5 @@ module.exports = [
|
||||
}
|
||||
}
|
||||
];
|
||||
for (let device of module.exports)
|
||||
for (const device of module.exports)
|
||||
module.exports[device.name] = device;
|
||||
|
@ -24,7 +24,7 @@ const revisionInfo = Downloader.revisionInfo(platform, revision);
|
||||
if (revisionInfo.downloaded)
|
||||
return;
|
||||
|
||||
let allRevisions = Downloader.downloadedRevisions();
|
||||
const allRevisions = Downloader.downloadedRevisions();
|
||||
Downloader.downloadRevision(platform, revision, onProgress)
|
||||
// Remove previous chromium revisions.
|
||||
.then(() => Promise.all(allRevisions.map(({platform, revision}) => Downloader.removeRevision(platform, revision))))
|
||||
@ -52,7 +52,7 @@ function onProgress(bytesTotal, delta) {
|
||||
}
|
||||
|
||||
function toMegabytes(bytes) {
|
||||
let mb = bytes / 1024 / 1024;
|
||||
const mb = bytes / 1024 / 1024;
|
||||
return `${Math.round(mb * 10) / 10} Mb`;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ class Browser {
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
async version() {
|
||||
let version = await this._connection.send('Browser.getVersion');
|
||||
const version = await this._connection.send('Browser.getVersion');
|
||||
return version.product;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class Connection extends EventEmitter {
|
||||
*/
|
||||
static async create(url, delay = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let ws = new WebSocket(url, { perMessageDeflate: false });
|
||||
const ws = new WebSocket(url, { perMessageDeflate: false });
|
||||
ws.on('open', () => resolve(new Connection(url, ws, delay)));
|
||||
ws.on('error', reject);
|
||||
});
|
||||
@ -66,8 +66,8 @@ class Connection extends EventEmitter {
|
||||
* @return {!Promise<?Object>}
|
||||
*/
|
||||
send(method, params = {}) {
|
||||
let id = ++this._lastId;
|
||||
let message = JSON.stringify({id, method, params});
|
||||
const id = ++this._lastId;
|
||||
const message = JSON.stringify({id, method, params});
|
||||
debugProtocol('SEND ► ' + message);
|
||||
this._ws.send(message);
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -82,9 +82,9 @@ class Connection extends EventEmitter {
|
||||
if (this._delay)
|
||||
await new Promise(f => setTimeout(f, this._delay));
|
||||
debugProtocol('◀ RECV ' + message);
|
||||
let object = JSON.parse(message);
|
||||
const object = JSON.parse(message);
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
let callback = this._callbacks.get(object.id);
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error)
|
||||
callback.reject(new Error(`Protocol error (${callback.method}): ${object.error.message} ${object.error.data}`));
|
||||
@ -109,10 +109,10 @@ class Connection extends EventEmitter {
|
||||
|
||||
_onClose() {
|
||||
this._ws.removeAllListeners();
|
||||
for (let callback of this._callbacks.values())
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(new Error(`Protocol error (${callback.method}): Target closed.`));
|
||||
this._callbacks.clear();
|
||||
for (let session of this._sessions.values())
|
||||
for (const session of this._sessions.values())
|
||||
session._onClosed();
|
||||
this._sessions.clear();
|
||||
}
|
||||
@ -168,14 +168,14 @@ class Session extends EventEmitter {
|
||||
send(method, params = {}) {
|
||||
if (!this._connection)
|
||||
return Promise.reject(new Error(`Protocol error (${method}): Session closed. Most likely the page has been closed.`));
|
||||
let id = ++this._lastId;
|
||||
let message = JSON.stringify({id, method, params});
|
||||
const id = ++this._lastId;
|
||||
const message = JSON.stringify({id, method, params});
|
||||
debugSession('SEND ► ' + message);
|
||||
this._connection.send('Target.sendMessageToTarget', {sessionId: this._sessionId, message}).catch(e => {
|
||||
// The response from target might have been already dispatched.
|
||||
if (!this._callbacks.has(id))
|
||||
return;
|
||||
let callback = this._callbacks.get(id);
|
||||
const callback = this._callbacks.get(id);
|
||||
this._callbacks.delete(object.id);
|
||||
callback.reject(e);
|
||||
});
|
||||
@ -189,9 +189,9 @@ class Session extends EventEmitter {
|
||||
*/
|
||||
_onMessage(message) {
|
||||
debugSession('◀ RECV ' + message);
|
||||
let object = JSON.parse(message);
|
||||
const object = JSON.parse(message);
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
let callback = this._callbacks.get(object.id);
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error)
|
||||
callback.reject(new Error(`Protocol error (${callback.method}): ${object.error.message} ${object.error.data}`));
|
||||
@ -211,7 +211,7 @@ class Session extends EventEmitter {
|
||||
}
|
||||
|
||||
_onClosed() {
|
||||
for (let callback of this._callbacks.values())
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(new Error(`Protocol error (${callback.method}): Target closed.`));
|
||||
this._callbacks.clear();
|
||||
this._connection = null;
|
||||
|
@ -48,11 +48,11 @@ class ElementHandle {
|
||||
console.assert(!this._disposed, 'ElementHandle is disposed!');
|
||||
console.assert(typeof pageFunction === 'function', 'First argument to ElementHandle.evaluate must be a function!');
|
||||
|
||||
let stringifiedArgs = ['this'];
|
||||
const stringifiedArgs = ['this'];
|
||||
stringifiedArgs.push(...args.map(x => JSON.stringify(x)));
|
||||
let functionDeclaration = `function() { return (${pageFunction})(${stringifiedArgs.join(',')}) }`;
|
||||
const functionDeclaration = `function() { return (${pageFunction})(${stringifiedArgs.join(',')}) }`;
|
||||
const objectId = this._remoteObject.objectId;
|
||||
let { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.callFunctionOn', { objectId, functionDeclaration, returnByValue: false, awaitPromise: true});
|
||||
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.callFunctionOn', { objectId, functionDeclaration, returnByValue: false, awaitPromise: true});
|
||||
if (exceptionDetails)
|
||||
throw new Error('Evaluation failed: ' + helper.getExceptionMessage(exceptionDetails));
|
||||
return await helper.serializeRemoteObject(this._client, remoteObject);
|
||||
@ -62,11 +62,11 @@ class ElementHandle {
|
||||
* @return {!Promise<{x: number, y: number}>}
|
||||
*/
|
||||
async _visibleCenter() {
|
||||
let center = await this.evaluate(element => {
|
||||
const center = await this.evaluate(element => {
|
||||
if (!element.ownerDocument.contains(element))
|
||||
return null;
|
||||
element.scrollIntoViewIfNeeded();
|
||||
let rect = element.getBoundingClientRect();
|
||||
const rect = element.getBoundingClientRect();
|
||||
return {
|
||||
x: (Math.max(rect.left, 0) + Math.min(rect.right, window.innerWidth)) / 2,
|
||||
y: (Math.max(rect.top, 0) + Math.min(rect.bottom, window.innerHeight)) / 2
|
||||
@ -81,7 +81,7 @@ class ElementHandle {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async hover() {
|
||||
let {x, y} = await this._visibleCenter();
|
||||
const {x, y} = await this._visibleCenter();
|
||||
await this._mouse.move(x, y);
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ class ElementHandle {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async click(options) {
|
||||
let {x, y} = await this._visibleCenter();
|
||||
const {x, y} = await this._visibleCenter();
|
||||
await this._mouse.click(x, y, options);
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ class ElementHandle {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async uploadFile(...filePaths) {
|
||||
let files = filePaths.map(filePath => path.resolve(filePath));
|
||||
const files = filePaths.map(filePath => path.resolve(filePath));
|
||||
const objectId = this._remoteObject.objectId;
|
||||
return this._client.send('DOM.setFileInputFiles', { objectId, files });
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ class FrameManager extends EventEmitter {
|
||||
if (this._frames.has(frameId))
|
||||
return;
|
||||
console.assert(parentFrameId);
|
||||
let parentFrame = this._frames.get(parentFrameId);
|
||||
let frame = new Frame(this._client, this._mouse, parentFrame, frameId);
|
||||
const parentFrame = this._frames.get(parentFrameId);
|
||||
const frame = new Frame(this._client, this._mouse, parentFrame, frameId);
|
||||
this._frames.set(frame._id, frame);
|
||||
this.emit(FrameManager.Events.FrameAttached, frame);
|
||||
}
|
||||
@ -77,7 +77,7 @@ class FrameManager extends EventEmitter {
|
||||
|
||||
// Detach all child frames first.
|
||||
if (frame) {
|
||||
for (let child of frame.childFrames())
|
||||
for (const child of frame.childFrames())
|
||||
this._removeFramesRecursively(child);
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ class FrameManager extends EventEmitter {
|
||||
* @param {string} frameId
|
||||
*/
|
||||
_onFrameDetached(frameId) {
|
||||
let frame = this._frames.get(frameId);
|
||||
const frame = this._frames.get(frameId);
|
||||
if (frame)
|
||||
this._removeFramesRecursively(frame);
|
||||
}
|
||||
@ -116,7 +116,7 @@ class FrameManager extends EventEmitter {
|
||||
if (!frame)
|
||||
return;
|
||||
frame._defaultContextId = context.id;
|
||||
for (let waitTask of frame._waitTasks)
|
||||
for (const waitTask of frame._waitTasks)
|
||||
waitTask.rerun();
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ class FrameManager extends EventEmitter {
|
||||
* @param {!Frame} frame
|
||||
*/
|
||||
_removeFramesRecursively(frame) {
|
||||
for (let child of frame.childFrames())
|
||||
for (const child of frame.childFrames())
|
||||
this._removeFramesRecursively(child);
|
||||
frame._detach();
|
||||
this._frames.delete(frame._id);
|
||||
@ -179,7 +179,7 @@ class Frame {
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async evaluate(pageFunction, ...args) {
|
||||
let remoteObject = await this._rawEvaluate(pageFunction, ...args);
|
||||
const remoteObject = await this._rawEvaluate(pageFunction, ...args);
|
||||
return await helper.serializeRemoteObject(this._client, remoteObject);
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ class Frame {
|
||||
* @return {!Promise<?ElementHandle>}
|
||||
*/
|
||||
async $(selector) {
|
||||
let remoteObject = await this._rawEvaluate(selector => document.querySelector(selector), selector);
|
||||
const remoteObject = await this._rawEvaluate(selector => document.querySelector(selector), selector);
|
||||
if (remoteObject.subtype === 'node')
|
||||
return new ElementHandle(this._client, remoteObject, this._mouse);
|
||||
helper.releaseObject(this._client, remoteObject);
|
||||
@ -201,9 +201,9 @@ class Frame {
|
||||
* @return {!Promise<(!Object|undefined)>}
|
||||
*/
|
||||
async _rawEvaluate(pageFunction, ...args) {
|
||||
let expression = helper.evaluationString(pageFunction, ...args);
|
||||
const expression = helper.evaluationString(pageFunction, ...args);
|
||||
const contextId = this._defaultContextId;
|
||||
let { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', { expression, contextId, returnByValue: false, awaitPromise: true});
|
||||
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', { expression, contextId, returnByValue: false, awaitPromise: true});
|
||||
if (exceptionDetails)
|
||||
throw new Error('Evaluation failed: ' + helper.getExceptionMessage(exceptionDetails));
|
||||
return remoteObject;
|
||||
@ -270,9 +270,9 @@ class Frame {
|
||||
* @param {string} url
|
||||
*/
|
||||
function addScriptTag(url) {
|
||||
let script = document.createElement('script');
|
||||
const script = document.createElement('script');
|
||||
script.src = url;
|
||||
let promise = new Promise(x => script.onload = x);
|
||||
const promise = new Promise(x => script.onload = x);
|
||||
document.head.appendChild(script);
|
||||
return promise;
|
||||
}
|
||||
@ -349,7 +349,7 @@ class Frame {
|
||||
}
|
||||
|
||||
_detach() {
|
||||
for (let waitTask of this._waitTasks)
|
||||
for (const waitTask of this._waitTasks)
|
||||
waitTask.terminate(new Error('waitForSelector failed: frame got detached.'));
|
||||
this._detached = true;
|
||||
if (this._parentFrame)
|
||||
|
@ -166,7 +166,7 @@ class Mouse {
|
||||
}
|
||||
}
|
||||
|
||||
let keys = {
|
||||
const keys = {
|
||||
'Cancel': 3,
|
||||
'Help': 6,
|
||||
'Backspace': 8,
|
||||
|
@ -113,7 +113,7 @@ class Launcher {
|
||||
* @return {!Promise<!Browser>}
|
||||
*/
|
||||
static async connect({browserWSEndpoint, ignoreHTTPSErrors = false}) {
|
||||
let connection = await Connection.create(browserWSEndpoint);
|
||||
const connection = await Connection.create(browserWSEndpoint);
|
||||
return new Browser(connection, !!ignoreHTTPSErrors);
|
||||
}
|
||||
}
|
||||
@ -127,12 +127,12 @@ function waitForWSEndpoint(chromeProcess, timeout) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({ input: chromeProcess.stderr });
|
||||
let stderr = '';
|
||||
let listeners = [
|
||||
const listeners = [
|
||||
helper.addEventListener(rl, 'line', onLine),
|
||||
helper.addEventListener(rl, 'close', onClose),
|
||||
helper.addEventListener(chromeProcess, 'exit', onClose)
|
||||
];
|
||||
let timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;
|
||||
const timeoutId = timeout ? setTimeout(onTimeout, timeout) : 0;
|
||||
|
||||
function onClose() {
|
||||
cleanup();
|
||||
|
@ -61,7 +61,7 @@ class Multimap {
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasValue(key, value) {
|
||||
let set = this._map.get(key);
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return false;
|
||||
return set.has(value);
|
||||
@ -80,8 +80,8 @@ class Multimap {
|
||||
* @return {boolean}
|
||||
*/
|
||||
delete(key, value) {
|
||||
let values = this.get(key);
|
||||
let result = values.delete(value);
|
||||
const values = this.get(key);
|
||||
const result = values.delete(value);
|
||||
if (!values.size)
|
||||
this._map.delete(key);
|
||||
return result;
|
||||
@ -99,7 +99,7 @@ class Multimap {
|
||||
* @return {?V} value
|
||||
*/
|
||||
firstValue(key) {
|
||||
let set = this._map.get(key);
|
||||
const set = this._map.get(key);
|
||||
if (!set)
|
||||
return null;
|
||||
return set.values().next().value;
|
||||
@ -116,8 +116,8 @@ class Multimap {
|
||||
* @return {!Array<!V>}
|
||||
*/
|
||||
valuesArray() {
|
||||
let result = [];
|
||||
for (let key of this._map.keys())
|
||||
const result = [];
|
||||
for (const key of this._map.keys())
|
||||
result.push(...Array.from(this._map.get(key).values()));
|
||||
return result;
|
||||
}
|
||||
|
@ -40,19 +40,19 @@ class NavigatorWatcher {
|
||||
|
||||
this._eventListeners = [];
|
||||
|
||||
let watchdog = new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._timeout))
|
||||
const watchdog = new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._timeout))
|
||||
.then(() => 'Navigation Timeout Exceeded: ' + this._timeout + 'ms exceeded');
|
||||
let navigationPromises = [watchdog];
|
||||
const navigationPromises = [watchdog];
|
||||
|
||||
if (!this._ignoreHTTPSErrors) {
|
||||
let certificateError = new Promise(fulfill => {
|
||||
const certificateError = new Promise(fulfill => {
|
||||
this._eventListeners.push(helper.addEventListener(this._client, 'Security.certificateError', fulfill));
|
||||
}).then(error => 'SSL Certificate error: ' + error.errorType);
|
||||
navigationPromises.push(certificateError);
|
||||
}
|
||||
|
||||
if (this._waitUntil === 'load') {
|
||||
let loadEventFired = new Promise(fulfill => {
|
||||
const loadEventFired = new Promise(fulfill => {
|
||||
this._eventListeners.push(helper.addEventListener(this._client, 'Page.loadEventFired', fulfill));
|
||||
}).then(() => null);
|
||||
navigationPromises.push(loadEventFired);
|
||||
@ -64,7 +64,7 @@ class NavigatorWatcher {
|
||||
helper.addEventListener(this._client, 'Network.webSocketCreated', this._onLoadingStarted.bind(this)),
|
||||
helper.addEventListener(this._client, 'Network.webSocketClosed', this._onLoadingCompleted.bind(this)),
|
||||
]);
|
||||
let networkIdle = new Promise(fulfill => this._networkIdleCallback = fulfill).then(() => null);
|
||||
const networkIdle = new Promise(fulfill => this._networkIdleCallback = fulfill).then(() => null);
|
||||
navigationPromises.push(networkIdle);
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ class NetworkManager extends EventEmitter {
|
||||
*/
|
||||
async setExtraHTTPHeaders(extraHTTPHeaders) {
|
||||
this._extraHTTPHeaders = new Map(extraHTTPHeaders);
|
||||
let headers = {};
|
||||
for (let entry of extraHTTPHeaders.entries())
|
||||
const headers = {};
|
||||
for (const entry of extraHTTPHeaders.entries())
|
||||
headers[entry[0]] = entry[1];
|
||||
await this._client.send('Network.setExtraHTTPHeaders', { headers });
|
||||
}
|
||||
@ -89,13 +89,13 @@ class NetworkManager extends EventEmitter {
|
||||
event.request.url = removeURLHash(event.request.url);
|
||||
|
||||
if (event.redirectStatusCode) {
|
||||
let request = this._interceptionIdToRequest.get(event.interceptionId);
|
||||
const request = this._interceptionIdToRequest.get(event.interceptionId);
|
||||
console.assert(request, 'INTERNAL ERROR: failed to find request for interception redirect.');
|
||||
this._handleRequestRedirect(request, event.redirectStatusCode, event.redirectHeaders);
|
||||
this._handleRequestStart(request._requestId, event.interceptionId, event.redirectUrl, event.request);
|
||||
return;
|
||||
}
|
||||
let requestHash = generateRequestHash(event.request);
|
||||
const requestHash = generateRequestHash(event.request);
|
||||
this._requestHashToInterceptions.set(requestHash, event);
|
||||
this._maybeResolveInterception(requestHash);
|
||||
}
|
||||
@ -106,7 +106,7 @@ class NetworkManager extends EventEmitter {
|
||||
* @param {!Object} redirectHeaders
|
||||
*/
|
||||
_handleRequestRedirect(request, redirectStatus, redirectHeaders) {
|
||||
let response = new Response(this._client, request, redirectStatus, redirectHeaders);
|
||||
const response = new Response(this._client, request, redirectStatus, redirectHeaders);
|
||||
request._response = response;
|
||||
this._requestIdToRequest.delete(request._requestId);
|
||||
this._interceptionIdToRequest.delete(request._interceptionId);
|
||||
@ -121,7 +121,7 @@ class NetworkManager extends EventEmitter {
|
||||
* @param {!Object} requestPayload
|
||||
*/
|
||||
_handleRequestStart(requestId, interceptionId, url, requestPayload) {
|
||||
let request = new Request(this._client, requestId, interceptionId, url, requestPayload);
|
||||
const request = new Request(this._client, requestId, interceptionId, url, requestPayload);
|
||||
this._requestIdToRequest.set(requestId, request);
|
||||
this._interceptionIdToRequest.set(interceptionId, request);
|
||||
this.emit(NetworkManager.Events.Request, request);
|
||||
@ -135,13 +135,13 @@ class NetworkManager extends EventEmitter {
|
||||
// All redirects are handled in requestIntercepted.
|
||||
if (event.redirectResponse)
|
||||
return;
|
||||
let requestHash = generateRequestHash(event.request);
|
||||
const requestHash = generateRequestHash(event.request);
|
||||
this._requestHashToRequestIds.set(requestHash, event.requestId);
|
||||
this._maybeResolveInterception(requestHash);
|
||||
return;
|
||||
}
|
||||
if (event.redirectResponse) {
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
this._handleRequestRedirect(request, event.redirectResponse.status, event.redirectResponse.headers);
|
||||
}
|
||||
this._handleRequestStart(event.requestId, null, event.request.url, event.request);
|
||||
@ -165,11 +165,11 @@ class NetworkManager extends EventEmitter {
|
||||
* @param {!Object} event
|
||||
*/
|
||||
_onResponseReceived(event) {
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
// FileUpload sends a response without a matching request.
|
||||
if (!request)
|
||||
return;
|
||||
let response = new Response(this._client, request, event.response.status, event.response.headers);
|
||||
const response = new Response(this._client, request, event.response.status, event.response.headers);
|
||||
request._response = response;
|
||||
this.emit(NetworkManager.Events.Response, response);
|
||||
}
|
||||
@ -178,7 +178,7 @@ class NetworkManager extends EventEmitter {
|
||||
* @param {!Object} event
|
||||
*/
|
||||
_onLoadingFinished(event) {
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
// For certain requestIds we never receive requestWillBeSent event.
|
||||
// @see https://crbug.com/750469
|
||||
if (!request)
|
||||
@ -193,7 +193,7 @@ class NetworkManager extends EventEmitter {
|
||||
* @param {!Object} event
|
||||
*/
|
||||
_onLoadingFailed(event) {
|
||||
let request = this._requestIdToRequest.get(event.requestId);
|
||||
const request = this._requestIdToRequest.get(event.requestId);
|
||||
// For certain requestIds we never receive requestWillBeSent event.
|
||||
// @see https://crbug.com/750469
|
||||
if (!request)
|
||||
@ -249,7 +249,7 @@ class Request {
|
||||
let headers = undefined;
|
||||
if (overrides.headers) {
|
||||
headers = {};
|
||||
for (let entry of overrides.headers)
|
||||
for (const entry of overrides.headers)
|
||||
headers[entry[0]] = entry[1];
|
||||
}
|
||||
this._client.send('Network.continueInterceptedRequest', {
|
||||
@ -300,7 +300,7 @@ class Response {
|
||||
buffer() {
|
||||
if (!this._contentPromise) {
|
||||
this._contentPromise = this._request._completePromise.then(async() => {
|
||||
let response = await this._client.send('Network.getResponseBody', {
|
||||
const response = await this._client.send('Network.getResponseBody', {
|
||||
requestId: this._request._requestId
|
||||
});
|
||||
return Buffer.from(response.body, response.base64Encoded ? 'base64' : 'utf8');
|
||||
@ -313,7 +313,7 @@ class Response {
|
||||
* @return {!Promise<string>}
|
||||
*/
|
||||
async text() {
|
||||
let content = await this.buffer();
|
||||
const content = await this.buffer();
|
||||
return content.toString('utf8');
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ class Response {
|
||||
* @return {!Promise<!Object>}
|
||||
*/
|
||||
async json() {
|
||||
let content = await this.text();
|
||||
const content = await this.text();
|
||||
return JSON.parse(content);
|
||||
}
|
||||
|
||||
@ -339,15 +339,15 @@ helper.tracePublicAPI(Response);
|
||||
* @return {string}
|
||||
*/
|
||||
function generateRequestHash(request) {
|
||||
let hash = {
|
||||
const hash = {
|
||||
url: request.url,
|
||||
method: request.method,
|
||||
postData: request.postData,
|
||||
headers: {},
|
||||
};
|
||||
let headers = Object.keys(request.headers);
|
||||
const headers = Object.keys(request.headers);
|
||||
headers.sort();
|
||||
for (let header of headers) {
|
||||
for (const header of headers) {
|
||||
if (header === 'Accept' || header === 'Referer' || header === 'X-DevTools-Emulate-Network-Conditions-Client-Id')
|
||||
continue;
|
||||
hash.headers[header] = request.headers[header];
|
||||
@ -360,7 +360,7 @@ function generateRequestHash(request) {
|
||||
* @return {string}
|
||||
*/
|
||||
function removeURLHash(url) {
|
||||
let urlObject = new URL(url);
|
||||
const urlObject = new URL(url);
|
||||
urlObject.hash = '';
|
||||
return urlObject.toString();
|
||||
}
|
||||
|
62
lib/Page.js
62
lib/Page.js
@ -171,7 +171,7 @@ class Page extends EventEmitter {
|
||||
throw new Error(`Failed to add page binding with name ${name}: window['${name}'] already exists!`);
|
||||
this._pageBindings[name] = puppeteerFunction;
|
||||
|
||||
let expression = helper.evaluationString(addPageBinding, name);
|
||||
const expression = helper.evaluationString(addPageBinding, name);
|
||||
await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source: expression });
|
||||
await this._client.send('Runtime.evaluate', { expression, returnByValue: true });
|
||||
|
||||
@ -213,15 +213,15 @@ class Page extends EventEmitter {
|
||||
* @param {!Object} exceptionDetails
|
||||
*/
|
||||
_handleException(exceptionDetails) {
|
||||
let message = helper.getExceptionMessage(exceptionDetails);
|
||||
const message = helper.getExceptionMessage(exceptionDetails);
|
||||
this.emit(Page.Events.PageError, new Error(message));
|
||||
}
|
||||
|
||||
async _onConsoleAPI(event) {
|
||||
if (event.type === 'debug' && event.args.length && event.args[0].value === 'driver:page-binding') {
|
||||
let {name, seq, args} = JSON.parse(event.args[1].value);
|
||||
let result = await this._pageBindings[name](...args);
|
||||
let expression = helper.evaluationString(deliverResult, name, seq, result);
|
||||
const {name, seq, args} = JSON.parse(event.args[1].value);
|
||||
const result = await this._pageBindings[name](...args);
|
||||
const expression = helper.evaluationString(deliverResult, name, seq, result);
|
||||
this._client.send('Runtime.evaluate', { expression });
|
||||
|
||||
function deliverResult(name, seq, result) {
|
||||
@ -234,7 +234,7 @@ class Page extends EventEmitter {
|
||||
event.args.map(arg => helper.releaseObject(this._client, arg));
|
||||
return;
|
||||
}
|
||||
let values = await Promise.all(event.args.map(arg => helper.serializeRemoteObject(this._client, arg)));
|
||||
const values = await Promise.all(event.args.map(arg => helper.serializeRemoteObject(this._client, arg)));
|
||||
this.emit(Page.Events.Console, ...values);
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ class Page extends EventEmitter {
|
||||
else if (event.type === 'beforeunload')
|
||||
dialogType = Dialog.Type.BeforeUnload;
|
||||
console.assert(dialogType, 'Unknown javascript dialog type: ' + event.type);
|
||||
let dialog = new Dialog(this._client, dialogType, event.message, event.defaultPrompt);
|
||||
const dialog = new Dialog(this._client, dialogType, event.message, event.defaultPrompt);
|
||||
this.emit(Page.Events.Dialog, dialog);
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ class Page extends EventEmitter {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async evaluateOnNewDocument(pageFunction, ...args) {
|
||||
let source = helper.evaluationString(pageFunction, ...args);
|
||||
const source = helper.evaluationString(pageFunction, ...args);
|
||||
await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source });
|
||||
}
|
||||
|
||||
@ -430,7 +430,7 @@ class Page extends EventEmitter {
|
||||
async screenshot(options = {}) {
|
||||
let screenshotType = null;
|
||||
if (options.path) {
|
||||
let mimeType = mime.lookup(options.path);
|
||||
const mimeType = mime.lookup(options.path);
|
||||
if (mimeType === 'image/png')
|
||||
screenshotType = 'png';
|
||||
else if (mimeType === 'image/jpeg')
|
||||
@ -488,14 +488,14 @@ class Page extends EventEmitter {
|
||||
|
||||
if (options.omitBackground)
|
||||
await this._client.send('Emulation.setDefaultBackgroundColorOverride', { color: { r: 0, g: 0, b: 0, a: 0 } });
|
||||
let result = await this._client.send('Page.captureScreenshot', { format, quality: options.quality, clip });
|
||||
const result = await this._client.send('Page.captureScreenshot', { format, quality: options.quality, clip });
|
||||
if (options.omitBackground)
|
||||
await this._client.send('Emulation.setDefaultBackgroundColorOverride');
|
||||
|
||||
if (options.fullPage)
|
||||
await this.setViewport(this._viewport);
|
||||
|
||||
let buffer = new Buffer(result.data, 'base64');
|
||||
const buffer = new Buffer(result.data, 'base64');
|
||||
if (options.path)
|
||||
fs.writeFileSync(options.path, buffer);
|
||||
return buffer;
|
||||
@ -506,16 +506,16 @@ class Page extends EventEmitter {
|
||||
* @return {!Promise<!Buffer>}
|
||||
*/
|
||||
async pdf(options = {}) {
|
||||
let scale = options.scale || 1;
|
||||
let displayHeaderFooter = !!options.displayHeaderFooter;
|
||||
let printBackground = !!options.printBackground;
|
||||
let landscape = !!options.landscape;
|
||||
let pageRanges = options.pageRanges || '';
|
||||
const scale = options.scale || 1;
|
||||
const displayHeaderFooter = !!options.displayHeaderFooter;
|
||||
const printBackground = !!options.printBackground;
|
||||
const landscape = !!options.landscape;
|
||||
const pageRanges = options.pageRanges || '';
|
||||
|
||||
let paperWidth = 8.5;
|
||||
let paperHeight = 11;
|
||||
if (options.format) {
|
||||
let format = Page.PaperFormats[options.format.toLowerCase()];
|
||||
const format = Page.PaperFormats[options.format.toLowerCase()];
|
||||
console.assert(format, 'Unknown paper format: ' + options.format);
|
||||
paperWidth = format.width;
|
||||
paperHeight = format.height;
|
||||
@ -524,13 +524,13 @@ class Page extends EventEmitter {
|
||||
paperHeight = convertPrintParameterToInches(options.height) || paperHeight;
|
||||
}
|
||||
|
||||
let marginOptions = options.margin || {};
|
||||
let marginTop = convertPrintParameterToInches(marginOptions.top) || 0;
|
||||
let marginLeft = convertPrintParameterToInches(marginOptions.left) || 0;
|
||||
let marginBottom = convertPrintParameterToInches(marginOptions.bottom) || 0;
|
||||
let marginRight = convertPrintParameterToInches(marginOptions.right) || 0;
|
||||
const marginOptions = options.margin || {};
|
||||
const marginTop = convertPrintParameterToInches(marginOptions.top) || 0;
|
||||
const marginLeft = convertPrintParameterToInches(marginOptions.left) || 0;
|
||||
const marginBottom = convertPrintParameterToInches(marginOptions.bottom) || 0;
|
||||
const marginRight = convertPrintParameterToInches(marginOptions.right) || 0;
|
||||
|
||||
let result = await this._client.send('Page.printToPDF', {
|
||||
const result = await this._client.send('Page.printToPDF', {
|
||||
landscape: landscape,
|
||||
displayHeaderFooter: displayHeaderFooter,
|
||||
printBackground: printBackground,
|
||||
@ -543,7 +543,7 @@ class Page extends EventEmitter {
|
||||
marginRight: marginRight,
|
||||
pageRanges: pageRanges
|
||||
});
|
||||
let buffer = new Buffer(result.data, 'base64');
|
||||
const buffer = new Buffer(result.data, 'base64');
|
||||
if (options.path)
|
||||
fs.writeFileSync(options.path, buffer);
|
||||
return buffer;
|
||||
@ -583,7 +583,7 @@ class Page extends EventEmitter {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async click(selector, options) {
|
||||
let handle = await this.$(selector);
|
||||
const handle = await this.$(selector);
|
||||
console.assert(handle, 'No node found for selector: ' + selector);
|
||||
await handle.click(options);
|
||||
await handle.dispose();
|
||||
@ -594,7 +594,7 @@ class Page extends EventEmitter {
|
||||
* @param {!Promise}
|
||||
*/
|
||||
async hover(selector) {
|
||||
let handle = await this.$(selector);
|
||||
const handle = await this.$(selector);
|
||||
console.assert(handle, 'No node found for selector: ' + selector);
|
||||
await handle.hover();
|
||||
await handle.dispose();
|
||||
@ -605,7 +605,7 @@ class Page extends EventEmitter {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async focus(selector) {
|
||||
let handle = await this.$(selector);
|
||||
const handle = await this.$(selector);
|
||||
console.assert(handle, 'No node found for selector: ' + selector);
|
||||
await handle.evaluate(element => element.focus());
|
||||
await handle.dispose();
|
||||
@ -621,7 +621,7 @@ class Page extends EventEmitter {
|
||||
if (options && options.delay)
|
||||
delay = options.delay;
|
||||
let last;
|
||||
for (let char of text) {
|
||||
for (const char of text) {
|
||||
last = this.press(char, {text: char, delay});
|
||||
if (delay)
|
||||
await new Promise(f => setTimeout(f, delay));
|
||||
@ -684,7 +684,7 @@ Page.PaperFormats = {
|
||||
a5: {width: 5.83, height: 8.27 },
|
||||
};
|
||||
|
||||
let unitToPixels = {
|
||||
const unitToPixels = {
|
||||
'px': 1,
|
||||
'in': 96,
|
||||
'cm': 37.8,
|
||||
@ -703,7 +703,7 @@ function convertPrintParameterToInches(parameter) {
|
||||
// Treat numbers as pixel values to be aligned with phantom's paperSize.
|
||||
pixels = /** @type {number} */ (parameter);
|
||||
} else if (helper.isString(parameter)) {
|
||||
let text = parameter;
|
||||
const text = parameter;
|
||||
let unit = text.substring(text.length - 2).toLowerCase();
|
||||
let valueText = '';
|
||||
if (unitToPixels.hasOwnProperty(unit)) {
|
||||
@ -714,7 +714,7 @@ function convertPrintParameterToInches(parameter) {
|
||||
unit = 'px';
|
||||
valueText = text;
|
||||
}
|
||||
let value = Number(valueText);
|
||||
const value = Number(valueText);
|
||||
console.assert(!isNaN(value), 'Failed to parse parameter value: ' + text);
|
||||
pixels = value * unitToPixels[unit];
|
||||
} else {
|
||||
|
@ -57,7 +57,7 @@ class Tracing {
|
||||
*/
|
||||
async stop() {
|
||||
let fulfill;
|
||||
let contentPromise = new Promise(x => fulfill = x);
|
||||
const contentPromise = new Promise(x => fulfill = x);
|
||||
this._client.once('Tracing.tracingComplete', event => {
|
||||
this._readStream(event.stream, this._path).then(fulfill);
|
||||
});
|
||||
@ -73,9 +73,9 @@ class Tracing {
|
||||
*/
|
||||
async _readStream(handle, path) {
|
||||
let eof = false;
|
||||
let file = fs.openSync(path, 'w');
|
||||
const file = fs.openSync(path, 'w');
|
||||
while (!eof) {
|
||||
let response = await this._client.send('IO.read', {handle});
|
||||
const response = await this._client.send('IO.read', {handle});
|
||||
eof = response.eof;
|
||||
if (path)
|
||||
fs.writeSync(file, response.data);
|
||||
|
@ -39,9 +39,9 @@ class Helper {
|
||||
return exceptionDetails.exception.description;
|
||||
let message = exceptionDetails.text;
|
||||
if (exceptionDetails.stackTrace) {
|
||||
for (let callframe of exceptionDetails.stackTrace.callFrames) {
|
||||
let location = callframe.url + ':' + callframe.lineNumber + ':' + callframe.columnNumber;
|
||||
let functionName = callframe.functionName || '<anonymous>';
|
||||
for (const callframe of exceptionDetails.stackTrace.callFrames) {
|
||||
const location = callframe.url + ':' + callframe.lineNumber + ':' + callframe.columnNumber;
|
||||
const functionName = callframe.functionName || '<anonymous>';
|
||||
message += `\n at ${functionName} (${location})`;
|
||||
}
|
||||
}
|
||||
@ -73,7 +73,7 @@ class Helper {
|
||||
if (remoteObject.subtype === 'promise')
|
||||
return remoteObject.description;
|
||||
try {
|
||||
let response = await client.send('Runtime.callFunctionOn', {
|
||||
const response = await client.send('Runtime.callFunctionOn', {
|
||||
objectId: remoteObject.objectId,
|
||||
functionDeclaration: 'function() { return this; }',
|
||||
returnByValue: true,
|
||||
@ -112,15 +112,15 @@ class Helper {
|
||||
const debug = require('debug')(`puppeteer:${className}`);
|
||||
if (!debug.enabled && !apiCoverage)
|
||||
return;
|
||||
for (let methodName of Reflect.ownKeys(classType.prototype)) {
|
||||
for (const methodName of Reflect.ownKeys(classType.prototype)) {
|
||||
const method = Reflect.get(classType.prototype, methodName);
|
||||
if (methodName === 'constructor' || typeof methodName !== 'string' || methodName.startsWith('_') || typeof method !== 'function')
|
||||
continue;
|
||||
if (apiCoverage)
|
||||
apiCoverage.set(`${className}.${methodName}`, false);
|
||||
Reflect.set(classType.prototype, methodName, function(...args) {
|
||||
let argsText = args.map(stringifyArgument).join(', ');
|
||||
let callsite = `${className}.${methodName}(${argsText})`;
|
||||
const argsText = args.map(stringifyArgument).join(', ');
|
||||
const callsite = `${className}.${methodName}(${argsText})`;
|
||||
if (debug.enabled)
|
||||
debug(callsite);
|
||||
if (apiCoverage)
|
||||
@ -131,12 +131,12 @@ class Helper {
|
||||
|
||||
if (classType.Events) {
|
||||
if (apiCoverage) {
|
||||
for (let event of Object.values(classType.Events))
|
||||
for (const event of Object.values(classType.Events))
|
||||
apiCoverage.set(`${className}.emit(${JSON.stringify(event)})`, false);
|
||||
}
|
||||
const method = Reflect.get(classType.prototype, 'emit');
|
||||
Reflect.set(classType.prototype, 'emit', function(event, ...args) {
|
||||
let argsText = [JSON.stringify(event)].concat(args.map(stringifyArgument)).join(', ');
|
||||
const argsText = [JSON.stringify(event)].concat(args.map(stringifyArgument)).join(', ');
|
||||
if (debug.enabled && this.listenerCount(event))
|
||||
debug(`${className}.emit(${argsText})`);
|
||||
if (apiCoverage && this.listenerCount(event))
|
||||
@ -160,7 +160,7 @@ class Helper {
|
||||
}
|
||||
const state = {};
|
||||
const keys = Object.keys(arg);
|
||||
for (let key of keys) {
|
||||
for (const key of keys) {
|
||||
const value = arg[key];
|
||||
if (Helper.isString(value) || Helper.isNumber(value))
|
||||
state[key] = JSON.stringify(value);
|
||||
@ -185,7 +185,7 @@ class Helper {
|
||||
* @param {!Array<{emitter: !EventEmitter, eventName: string, handler: function(?)}>}
|
||||
*/
|
||||
static removeEventListeners(listeners) {
|
||||
for (let listener of listeners)
|
||||
for (const listener of listeners)
|
||||
listener.emitter.removeListener(listener.eventName, listener.handler);
|
||||
listeners.splice(0, listeners.length);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class FileSystem {
|
||||
* @param {string} toPath
|
||||
*/
|
||||
copy(fromPath, toPath) {
|
||||
let content = fs.readFileSync(fromPath);
|
||||
const content = fs.readFileSync(fromPath);
|
||||
fs.writeFileSync(toPath, content);
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class FileSystem {
|
||||
* @param {string} toPath
|
||||
*/
|
||||
move(fromPath, toPath) {
|
||||
let content = fs.readFileSync(fromPath);
|
||||
const content = fs.readFileSync(fromPath);
|
||||
fs.writeFileSync(toPath, content);
|
||||
fs.unlinkSync(fromPath);
|
||||
}
|
||||
@ -170,7 +170,7 @@ class FileSystem {
|
||||
* @param {string} mode
|
||||
*/
|
||||
write(filePath, data, mode) {
|
||||
let fd = new FileDescriptor(filePath, mode, 'utf8');
|
||||
const fd = new FileDescriptor(filePath, mode, 'utf8');
|
||||
fd.write(data);
|
||||
fd.close();
|
||||
}
|
||||
@ -288,8 +288,8 @@ class FileSystem {
|
||||
}
|
||||
}
|
||||
|
||||
let fdwrite = deasync(fs.write);
|
||||
let fdread = deasync(fs.read);
|
||||
const fdwrite = deasync(fs.write);
|
||||
const fdread = deasync(fs.read);
|
||||
|
||||
class FileDescriptor {
|
||||
/**
|
||||
@ -318,8 +318,8 @@ class FileDescriptor {
|
||||
* @param {string} data
|
||||
*/
|
||||
write(data) {
|
||||
let buffer = Buffer.from(data, this._encoding);
|
||||
let written = fdwrite(this._fd, buffer, 0, buffer.length, this._position);
|
||||
const buffer = Buffer.from(data, this._encoding);
|
||||
const written = fdwrite(this._fd, buffer, 0, buffer.length, this._position);
|
||||
this._position += written;
|
||||
}
|
||||
|
||||
@ -344,8 +344,8 @@ class FileDescriptor {
|
||||
size = fs.fstatSync(this._fd).size;
|
||||
position = 0;
|
||||
}
|
||||
let buffer = new Buffer(size);
|
||||
let bytesRead = fdread(this._fd, buffer, 0, size, position);
|
||||
const buffer = new Buffer(size);
|
||||
const bytesRead = fdread(this._fd, buffer, 0, size, position);
|
||||
this._position += bytesRead;
|
||||
return buffer.toString(this._encoding);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ module.exports.create = function(context, scriptPath) {
|
||||
* @param {string} filename
|
||||
*/
|
||||
loadModule: function(moduleSource, filename) {
|
||||
let code = [
|
||||
const code = [
|
||||
'(function(require, exports, module) {\n',
|
||||
moduleSource,
|
||||
'\n}.call({},',
|
||||
|
@ -61,7 +61,7 @@ class StandardInput {
|
||||
if (this._closed && !this._lines.length)
|
||||
return '';
|
||||
if (!this._lines.length) {
|
||||
let linePromise = new Promise(fulfill => this._readline.once('line', fulfill));
|
||||
const linePromise = new Promise(fulfill => this._readline.once('line', fulfill));
|
||||
await(linePromise);
|
||||
}
|
||||
return this._lines.shift();
|
||||
@ -72,10 +72,10 @@ class StandardInput {
|
||||
*/
|
||||
read() {
|
||||
if (!this._closed) {
|
||||
let closePromise = new Promise(fulfill => this._readline.once('close', fulfill));
|
||||
const closePromise = new Promise(fulfill => this._readline.once('close', fulfill));
|
||||
await(closePromise);
|
||||
}
|
||||
let text = this._lines.join('\n');
|
||||
const text = this._lines.join('\n');
|
||||
this._lines = [];
|
||||
return text;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ class WebPage {
|
||||
* @return {string}
|
||||
*/
|
||||
get focusedFrameName() {
|
||||
let focusedFrame = this._focusedFrame();
|
||||
const focusedFrame = this._focusedFrame();
|
||||
return focusedFrame ? focusedFrame.name() : '';
|
||||
}
|
||||
|
||||
@ -160,10 +160,10 @@ class WebPage {
|
||||
* @return {?Frame}
|
||||
*/
|
||||
_focusedFrame() {
|
||||
let frames = this._currentFrame.childFrames().slice();
|
||||
const frames = this._currentFrame.childFrames().slice();
|
||||
frames.push(this._currentFrame);
|
||||
let promises = frames.map(frame => frame.evaluate(() => document.hasFocus()));
|
||||
let result = await(Promise.all(promises));
|
||||
const promises = frames.map(frame => frame.evaluate(() => document.hasFocus()));
|
||||
const result = await(Promise.all(promises));
|
||||
for (let i = 0; i < result.length; ++i) {
|
||||
if (result[i])
|
||||
return frames[i];
|
||||
@ -172,7 +172,7 @@ class WebPage {
|
||||
}
|
||||
|
||||
switchToFocusedFrame() {
|
||||
let frame = this._focusedFrame();
|
||||
const frame = this._focusedFrame();
|
||||
this._currentFrame = frame;
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ class WebPage {
|
||||
* @return {boolean}
|
||||
*/
|
||||
switchToParentFrame() {
|
||||
let frame = this._currentFrame.parentFrame();
|
||||
const frame = this._currentFrame.parentFrame();
|
||||
if (!frame)
|
||||
return false;
|
||||
this._currentFrame = frame;
|
||||
@ -236,8 +236,8 @@ class WebPage {
|
||||
_onRequest(request) {
|
||||
if (!this._onResourceRequestedCallback)
|
||||
return;
|
||||
let requestData = new RequestData(request);
|
||||
let phantomRequest = new PhantomRequest();
|
||||
const requestData = new RequestData(request);
|
||||
const phantomRequest = new PhantomRequest();
|
||||
this._onResourceRequestedCallback.call(null, requestData, phantomRequest);
|
||||
if (phantomRequest._aborted) {
|
||||
request.abort();
|
||||
@ -252,14 +252,14 @@ class WebPage {
|
||||
_onResponseReceived(response) {
|
||||
if (!this.onResourceReceived)
|
||||
return;
|
||||
let phantomResponse = new PhantomResponse(response, false /* isResponseFinished */);
|
||||
const phantomResponse = new PhantomResponse(response, false /* isResponseFinished */);
|
||||
this.onResourceReceived.call(null, phantomResponse);
|
||||
}
|
||||
|
||||
_onRequestFinished(request) {
|
||||
if (!this.onResourceReceived)
|
||||
return;
|
||||
let phantomResponse = new PhantomResponse(request.response(), true /* isResponseFinished */);
|
||||
const phantomResponse = new PhantomResponse(request.response(), true /* isResponseFinished */);
|
||||
this.onResourceReceived.call(null, phantomResponse);
|
||||
}
|
||||
|
||||
@ -391,10 +391,10 @@ class WebPage {
|
||||
this._onAlertCallback.call(null, dialog.message());
|
||||
await(dialog.accept());
|
||||
} else if (dialog.type === 'confirm' && this._onConfirmCallback) {
|
||||
let result = this._onConfirmCallback.call(null, dialog.message());
|
||||
const result = this._onConfirmCallback.call(null, dialog.message());
|
||||
await(result ? dialog.accept() : dialog.dismiss());
|
||||
} else if (dialog.type === 'prompt' && this._onPromptCallback) {
|
||||
let result = this._onPromptCallback.call(null, dialog.message(), dialog.defaultValue());
|
||||
const result = this._onPromptCallback.call(null, dialog.message(), dialog.defaultValue());
|
||||
await(result ? dialog.accept(result) : dialog.dismiss());
|
||||
}
|
||||
}
|
||||
@ -449,7 +449,7 @@ class WebPage {
|
||||
await(this._page.keyboard.up(String.fromCharCode(keyOrKeys)));
|
||||
break;
|
||||
}
|
||||
for (let key of keyOrKeys)
|
||||
for (const key of keyOrKeys)
|
||||
await(this._page.keyboard.up(key));
|
||||
break;
|
||||
case 'keypress':
|
||||
@ -475,7 +475,7 @@ class WebPage {
|
||||
await(this._page.keyboard.down(String.fromCharCode(keyOrKeys)));
|
||||
break;
|
||||
}
|
||||
for (let key of keyOrKeys)
|
||||
for (const key of keyOrKeys)
|
||||
await(this._page.keyboard.down(key));
|
||||
break;
|
||||
}
|
||||
@ -539,7 +539,7 @@ class WebPage {
|
||||
errorString: 'SSL handshake failed'
|
||||
});
|
||||
}
|
||||
let status = error ? 'fail' : 'success';
|
||||
const status = error ? 'fail' : 'success';
|
||||
if (this.onLoadFinished)
|
||||
this.onLoadFinished.call(null, status);
|
||||
if (callback)
|
||||
@ -574,8 +574,8 @@ class WebPage {
|
||||
*/
|
||||
render(fileName) {
|
||||
if (fileName.endsWith('pdf')) {
|
||||
let options = {};
|
||||
let paperSize = this.paperSize || {};
|
||||
const options = {};
|
||||
const paperSize = this.paperSize || {};
|
||||
options.margin = paperSize.margin;
|
||||
options.format = paperSize.format;
|
||||
options.landscape = paperSize.orientation === 'landscape';
|
||||
@ -584,7 +584,7 @@ class WebPage {
|
||||
options.path = fileName;
|
||||
await(this._page.pdf(options));
|
||||
} else {
|
||||
let options = {};
|
||||
const options = {};
|
||||
if (this.clipRect && (this.clipRect.left || this.clipRect.top || this.clipRect.width || this.clipRect.height)) {
|
||||
options.clip = {
|
||||
x: this.clipRect.left,
|
||||
@ -669,7 +669,7 @@ class PhantomResponse {
|
||||
this.statusText = response.statusText;
|
||||
this.stage = isResponseFinished ? 'end' : 'start';
|
||||
this.headers = [];
|
||||
for (let entry of response.headers.entries()) {
|
||||
for (const entry of response.headers.entries()) {
|
||||
this.headers.push({
|
||||
name: entry[0],
|
||||
value: entry[1]
|
||||
@ -685,7 +685,7 @@ class RequestData {
|
||||
constructor(request) {
|
||||
this.url = request.url,
|
||||
this.headers = {};
|
||||
for (let entry of request.headers.entries())
|
||||
for (const entry of request.headers.entries())
|
||||
this.headers[entry[0]] = entry[1];
|
||||
}
|
||||
}
|
||||
@ -714,7 +714,7 @@ class AsyncEmitter extends EventEmitter {
|
||||
|
||||
_onListenerAdded(event, listener) {
|
||||
// Async listener calls original listener on next tick.
|
||||
let asyncListener = (...args) => {
|
||||
const asyncListener = (...args) => {
|
||||
process.nextTick(() => listener.apply(null, args));
|
||||
};
|
||||
listener[this._symbol] = asyncListener;
|
||||
|
@ -47,17 +47,17 @@ class WebServer {
|
||||
return false;
|
||||
this.newRequest = callback;
|
||||
this._server.listen(port);
|
||||
let errorPromise = new Promise(x => this._server.once('error', x));
|
||||
let successPromise = new Promise(x => this._server.once('listening', x));
|
||||
const errorPromise = new Promise(x => this._server.once('error', x));
|
||||
const successPromise = new Promise(x => this._server.once('listening', x));
|
||||
await(Promise.race([errorPromise, successPromise]));
|
||||
if (!this._server.listening)
|
||||
return false;
|
||||
|
||||
this._server.on('request', (req, res) => {
|
||||
res.close = res.end.bind(res);
|
||||
let headers = res.getHeaders();
|
||||
const headers = res.getHeaders();
|
||||
res.headers = [];
|
||||
for (let key in headers) {
|
||||
for (const key in headers) {
|
||||
res.headers.push({
|
||||
name: key,
|
||||
value: headers[key]
|
||||
@ -65,7 +65,7 @@ class WebServer {
|
||||
}
|
||||
res.header = res.getHeader;
|
||||
res.setHeaders = headers => {
|
||||
for (let key in headers)
|
||||
for (const key in headers)
|
||||
res.setHeader(key, headers[key]);
|
||||
};
|
||||
Object.defineProperty(res, 'statusCode', {
|
||||
|
@ -43,21 +43,21 @@ if (argv['ssl-certificates-path']) {
|
||||
return;
|
||||
}
|
||||
|
||||
let scriptArguments = argv._;
|
||||
const scriptArguments = argv._;
|
||||
if (!scriptArguments.length) {
|
||||
console.log(__filename.split('/').pop() + ' [scriptfile]');
|
||||
return;
|
||||
}
|
||||
|
||||
let scriptPath = path.resolve(process.cwd(), scriptArguments[0]);
|
||||
const scriptPath = path.resolve(process.cwd(), scriptArguments[0]);
|
||||
if (!fs.existsSync(scriptPath)) {
|
||||
console.error(`script not found: ${scriptPath}`);
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
let context = createPhantomContext(argv.headless, scriptPath, argv);
|
||||
let scriptContent = fs.readFileSync(scriptPath, 'utf8');
|
||||
const context = createPhantomContext(argv.headless, scriptPath, argv);
|
||||
const scriptContent = fs.readFileSync(scriptPath, 'utf8');
|
||||
vm.runInContext(scriptContent, context);
|
||||
|
||||
/**
|
||||
@ -67,7 +67,7 @@ vm.runInContext(scriptContent, context);
|
||||
* @return {!Object}
|
||||
*/
|
||||
function createPhantomContext(headless, scriptPath, argv) {
|
||||
let context = {};
|
||||
const context = {};
|
||||
let browser = null;
|
||||
context.setInterval = setInterval;
|
||||
context.setTimeout = setTimeout;
|
||||
@ -81,7 +81,7 @@ function createPhantomContext(headless, scriptPath, argv) {
|
||||
|
||||
vm.createContext(context);
|
||||
|
||||
let nativeExports = {
|
||||
const nativeExports = {
|
||||
fs: new FileSystem(),
|
||||
system: new System(argv._),
|
||||
webpage: {
|
||||
@ -95,8 +95,8 @@ function createPhantomContext(headless, scriptPath, argv) {
|
||||
},
|
||||
child_process: child_process
|
||||
};
|
||||
let bootstrapPath = path.join(__dirname, '..', 'third_party', 'phantomjs', 'bootstrap.js');
|
||||
let bootstrapCode = fs.readFileSync(bootstrapPath, 'utf8');
|
||||
const bootstrapPath = path.join(__dirname, '..', 'third_party', 'phantomjs', 'bootstrap.js');
|
||||
const bootstrapCode = fs.readFileSync(bootstrapPath, 'utf8');
|
||||
vm.runInContext(bootstrapCode, context, {
|
||||
filename: 'bootstrap.js'
|
||||
})(nativeExports);
|
||||
|
@ -1,9 +1,9 @@
|
||||
// This injects a box into the page that moves with the mouse;
|
||||
// Useful for debugging
|
||||
(function(){
|
||||
let box = document.createElement('div');
|
||||
const box = document.createElement('div');
|
||||
box.classList.add('mouse-helper');
|
||||
let styleElement = document.createElement('style');
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.innerHTML = `
|
||||
.mouse-helper {
|
||||
pointer-events: none;
|
||||
|
@ -25,7 +25,7 @@ const utils = module.exports = {
|
||||
await page.evaluate(attachFrame, frameId, url);
|
||||
|
||||
function attachFrame(frameId, url) {
|
||||
let frame = document.createElement('iframe');
|
||||
const frame = document.createElement('iframe');
|
||||
frame.src = url;
|
||||
frame.id = frameId;
|
||||
document.body.appendChild(frame);
|
||||
@ -42,7 +42,7 @@ const utils = module.exports = {
|
||||
await page.evaluate(detachFrame, frameId);
|
||||
|
||||
function detachFrame(frameId) {
|
||||
let frame = document.getElementById(frameId);
|
||||
const frame = document.getElementById(frameId);
|
||||
frame.remove();
|
||||
}
|
||||
},
|
||||
@ -57,7 +57,7 @@ const utils = module.exports = {
|
||||
await page.evaluate(navigateFrame, frameId, url);
|
||||
|
||||
function navigateFrame(frameId, url) {
|
||||
let frame = document.getElementById(frameId);
|
||||
const frame = document.getElementById(frameId);
|
||||
frame.src = url;
|
||||
return new Promise(x => frame.onload = x);
|
||||
}
|
||||
@ -71,7 +71,7 @@ const utils = module.exports = {
|
||||
dumpFrames: function(frame, indentation) {
|
||||
indentation = indentation || '';
|
||||
let result = indentation + frame.url();
|
||||
for (let child of frame.childFrames())
|
||||
for (const child of frame.childFrames())
|
||||
result += '\n' + utils.dumpFrames(child, ' ' + indentation);
|
||||
return result;
|
||||
},
|
||||
|
@ -30,7 +30,7 @@ module.exports = {
|
||||
},
|
||||
};
|
||||
|
||||
let GoldenComparators = {
|
||||
const GoldenComparators = {
|
||||
'image/png': compareImages,
|
||||
'text/plain': compareText
|
||||
};
|
||||
@ -44,15 +44,15 @@ function compareImages(actualBuffer, expectedBuffer) {
|
||||
if (!actualBuffer || !(actualBuffer instanceof Buffer))
|
||||
return { errorMessage: 'Actual result should be Buffer.' };
|
||||
|
||||
let actual = PNG.sync.read(actualBuffer);
|
||||
let expected = PNG.sync.read(expectedBuffer);
|
||||
const actual = PNG.sync.read(actualBuffer);
|
||||
const expected = PNG.sync.read(expectedBuffer);
|
||||
if (expected.width !== actual.width || expected.height !== actual.height) {
|
||||
return {
|
||||
errorMessage: `Sizes differ: expected image ${expected.width}px X ${expected.height}px, but got ${actual.width}px X ${actual.height}px. `
|
||||
};
|
||||
}
|
||||
let diff = new PNG({width: expected.width, height: expected.height});
|
||||
let count = pixelmatch(expected.data, actual.data, diff.data, expected.width, expected.height, {threshold: 0.1});
|
||||
const diff = new PNG({width: expected.width, height: expected.height});
|
||||
const count = pixelmatch(expected.data, actual.data, diff.data, expected.width, expected.height, {threshold: 0.1});
|
||||
return count > 0 ? { diff: PNG.sync.write(diff) } : null;
|
||||
}
|
||||
|
||||
@ -64,14 +64,14 @@ function compareImages(actualBuffer, expectedBuffer) {
|
||||
function compareText(actual, expectedBuffer) {
|
||||
if (typeof actual !== 'string')
|
||||
return { errorMessage: 'Actual result should be string' };
|
||||
let expected = expectedBuffer.toString('utf-8');
|
||||
const expected = expectedBuffer.toString('utf-8');
|
||||
if (expected === actual)
|
||||
return null;
|
||||
let diff = new Diff();
|
||||
let result = diff.main(expected, actual);
|
||||
const diff = new Diff();
|
||||
const result = diff.main(expected, actual);
|
||||
diff.cleanupSemantic(result);
|
||||
let html = diff.prettyHtml(result);
|
||||
let diffStylePath = path.join(__dirname, 'diffstyle.css');
|
||||
const diffStylePath = path.join(__dirname, 'diffstyle.css');
|
||||
html = `<link rel="stylesheet" href="file://${diffStylePath}">` + html;
|
||||
return {
|
||||
diff: html,
|
||||
@ -85,10 +85,10 @@ function compareText(actual, expectedBuffer) {
|
||||
* @return {!{pass: boolean, message: (undefined|string)}}
|
||||
*/
|
||||
function compare(goldenPath, outputPath, actual, goldenName) {
|
||||
let expectedPath = path.join(goldenPath, goldenName);
|
||||
let actualPath = path.join(outputPath, goldenName);
|
||||
const expectedPath = path.join(goldenPath, goldenName);
|
||||
const actualPath = path.join(outputPath, goldenName);
|
||||
|
||||
let messageSuffix = 'Output is saved in "' + path.basename(outputPath + '" directory');
|
||||
const messageSuffix = 'Output is saved in "' + path.basename(outputPath + '" directory');
|
||||
|
||||
if (!fs.existsSync(expectedPath)) {
|
||||
ensureOutputDir();
|
||||
@ -98,15 +98,15 @@ function compare(goldenPath, outputPath, actual, goldenName) {
|
||||
message: goldenName + ' is missing in golden results. ' + messageSuffix
|
||||
};
|
||||
}
|
||||
let expected = fs.readFileSync(expectedPath);
|
||||
let comparator = GoldenComparators[mime.lookup(goldenName)];
|
||||
const expected = fs.readFileSync(expectedPath);
|
||||
const comparator = GoldenComparators[mime.lookup(goldenName)];
|
||||
if (!comparator) {
|
||||
return {
|
||||
pass: false,
|
||||
message: 'Failed to find comparator with type ' + mime.lookup(goldenName) + ': ' + goldenName
|
||||
};
|
||||
}
|
||||
let result = comparator(actual, expected);
|
||||
const result = comparator(actual, expected);
|
||||
if (!result)
|
||||
return { pass: true };
|
||||
ensureOutputDir();
|
||||
@ -114,7 +114,7 @@ function compare(goldenPath, outputPath, actual, goldenName) {
|
||||
// Copy expected to the output/ folder for convenience.
|
||||
fs.writeFileSync(addSuffix(actualPath, '-expected'), expected);
|
||||
if (result.diff) {
|
||||
let diffPath = addSuffix(actualPath, '-diff', result.diffExtension);
|
||||
const diffPath = addSuffix(actualPath, '-diff', result.diffExtension);
|
||||
fs.writeFileSync(diffPath, result.diff);
|
||||
}
|
||||
|
||||
@ -139,8 +139,8 @@ function compare(goldenPath, outputPath, actual, goldenName) {
|
||||
* @return {string}
|
||||
*/
|
||||
function addSuffix(filePath, suffix, customExtension) {
|
||||
let dirname = path.dirname(filePath);
|
||||
let ext = path.extname(filePath);
|
||||
let name = path.basename(filePath, ext);
|
||||
const dirname = path.dirname(filePath);
|
||||
const ext = path.extname(filePath);
|
||||
const name = path.basename(filePath, ext);
|
||||
return path.join(dirname, name + suffix + (customExtension || ext));
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class SimpleServer {
|
||||
* @return {!SimpleServer}
|
||||
*/
|
||||
static async create(dirPath, port) {
|
||||
let server = new SimpleServer(dirPath, port);
|
||||
const server = new SimpleServer(dirPath, port);
|
||||
await new Promise(x => server._server.once('listening', x));
|
||||
return server;
|
||||
}
|
||||
@ -43,7 +43,7 @@ class SimpleServer {
|
||||
* @return {!SimpleServer}
|
||||
*/
|
||||
static async createHTTPS(dirPath, port) {
|
||||
let server = new SimpleServer(dirPath, port, {
|
||||
const server = new SimpleServer(dirPath, port, {
|
||||
key: fs.readFileSync(path.join(__dirname, 'key.pem')),
|
||||
cert: fs.readFileSync(path.join(__dirname, 'cert.pem')),
|
||||
passphrase: 'aaaa',
|
||||
@ -93,7 +93,7 @@ class SimpleServer {
|
||||
*/
|
||||
async stop() {
|
||||
this.reset();
|
||||
for (let socket of this._sockets)
|
||||
for (const socket of this._sockets)
|
||||
socket.destroy();
|
||||
this._sockets.clear();
|
||||
await new Promise(x => this._server.close(x));
|
||||
@ -139,8 +139,8 @@ class SimpleServer {
|
||||
|
||||
reset() {
|
||||
this._routes.clear();
|
||||
let error = new Error('Static Server has been reset');
|
||||
for (let subscriber of this._requestSubscribers.values())
|
||||
const error = new Error('Static Server has been reset');
|
||||
for (const subscriber of this._requestSubscribers.values())
|
||||
subscriber[rejectSymbol].call(null, error);
|
||||
this._requestSubscribers.clear();
|
||||
}
|
||||
@ -152,11 +152,11 @@ class SimpleServer {
|
||||
else
|
||||
throw error;
|
||||
});
|
||||
let pathName = url.parse(request.url).path;
|
||||
const pathName = url.parse(request.url).path;
|
||||
// Notify request subscriber.
|
||||
if (this._requestSubscribers.has(pathName))
|
||||
this._requestSubscribers.get(pathName)[fulfillSymbol].call(null, request);
|
||||
let handler = this._routes.get(pathName);
|
||||
const handler = this._routes.get(pathName);
|
||||
if (handler)
|
||||
handler.call(null, request, response);
|
||||
else
|
||||
|
298
test/test.js
298
test/test.js
@ -82,9 +82,9 @@ afterAll(SX(async function() {
|
||||
|
||||
describe('Browser', function() {
|
||||
it('Browser.Options.ignoreHTTPSErrors', SX(async function() {
|
||||
let options = Object.assign({ignoreHTTPSErrors: true}, defaultBrowserOptions);
|
||||
let browser = await puppeteer.launch(options);
|
||||
let page = await browser.newPage();
|
||||
const options = Object.assign({ignoreHTTPSErrors: true}, defaultBrowserOptions);
|
||||
const browser = await puppeteer.launch(options);
|
||||
const page = await browser.newPage();
|
||||
let error = null;
|
||||
let response = null;
|
||||
try {
|
||||
@ -97,20 +97,20 @@ describe('Browser', function() {
|
||||
browser.close();
|
||||
}));
|
||||
it('should reject all promises when browser is closed', SX(async function() {
|
||||
let browser = await puppeteer.launch(defaultBrowserOptions);
|
||||
let page = await browser.newPage();
|
||||
const browser = await puppeteer.launch(defaultBrowserOptions);
|
||||
const page = await browser.newPage();
|
||||
let error = null;
|
||||
let neverResolves = page.evaluate(() => new Promise(r => {})).catch(e => error = e);
|
||||
const neverResolves = page.evaluate(() => new Promise(r => {})).catch(e => error = e);
|
||||
browser.close();
|
||||
await neverResolves;
|
||||
expect(error.message).toContain('Protocol error');
|
||||
}));
|
||||
it('Puppeteer.connect', SX(async function() {
|
||||
let originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||
let browser = await puppeteer.connect({
|
||||
const originalBrowser = await puppeteer.launch(defaultBrowserOptions);
|
||||
const browser = await puppeteer.connect({
|
||||
browserWSEndpoint: originalBrowser.wsEndpoint()
|
||||
});
|
||||
let page = await browser.newPage();
|
||||
const page = await browser.newPage();
|
||||
expect(await page.evaluate(() => 7 * 8)).toBe(56);
|
||||
originalBrowser.close();
|
||||
}));
|
||||
@ -144,7 +144,7 @@ describe('Page', function() {
|
||||
|
||||
describe('Browser.version', function() {
|
||||
it('should return whether we are in headless', SX(async function() {
|
||||
let version = await browser.version();
|
||||
const version = await browser.version();
|
||||
expect(version.length).toBeGreaterThan(0);
|
||||
expect(version.startsWith('Headless')).toBe(headless);
|
||||
}));
|
||||
@ -152,8 +152,8 @@ describe('Page', function() {
|
||||
|
||||
describe('Page.close', function() {
|
||||
it('should reject all promises when page is closed', SX(async function() {
|
||||
let newPage = await browser.newPage();
|
||||
let neverResolves = newPage.evaluate(() => new Promise(r => {}));
|
||||
const newPage = await browser.newPage();
|
||||
const neverResolves = newPage.evaluate(() => new Promise(r => {}));
|
||||
newPage.close();
|
||||
let error = null;
|
||||
try {
|
||||
@ -177,11 +177,11 @@ describe('Page', function() {
|
||||
|
||||
describe('Page.evaluate', function() {
|
||||
it('should work', SX(async function() {
|
||||
let result = await page.evaluate(() => 7 * 3);
|
||||
const result = await page.evaluate(() => 7 * 3);
|
||||
expect(result).toBe(21);
|
||||
}));
|
||||
it('should await promise', SX(async function() {
|
||||
let result = await page.evaluate(() => Promise.resolve(8 * 7));
|
||||
const result = await page.evaluate(() => Promise.resolve(8 * 7));
|
||||
expect(result).toBe(56);
|
||||
}));
|
||||
it('should work from-inside an exposed function', SX(async function() {
|
||||
@ -189,7 +189,7 @@ describe('Page', function() {
|
||||
await page.exposeFunction('callController', async function(a, b) {
|
||||
return await page.evaluate((a, b) => a * b, a, b);
|
||||
});
|
||||
let result = await page.evaluate(async function() {
|
||||
const result = await page.evaluate(async function() {
|
||||
return await callController(9, 3);
|
||||
});
|
||||
expect(result).toBe(27);
|
||||
@ -206,40 +206,40 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should return complex objects', SX(async function() {
|
||||
const object = {foo: 'bar!'};
|
||||
let result = await page.evaluate(a => a, object);
|
||||
const result = await page.evaluate(a => a, object);
|
||||
expect(result).not.toBe(object);
|
||||
expect(result).toEqual(object);
|
||||
}));
|
||||
it('should return NaN', SX(async function() {
|
||||
let result = await page.evaluate(() => NaN);
|
||||
const result = await page.evaluate(() => NaN);
|
||||
expect(Object.is(result, NaN)).toBe(true);
|
||||
}));
|
||||
it('should return -0', SX(async function() {
|
||||
let result = await page.evaluate(() => -0);
|
||||
const result = await page.evaluate(() => -0);
|
||||
expect(Object.is(result, -0)).toBe(true);
|
||||
}));
|
||||
it('should return Infinity', SX(async function() {
|
||||
let result = await page.evaluate(() => Infinity);
|
||||
const result = await page.evaluate(() => Infinity);
|
||||
expect(Object.is(result, Infinity)).toBe(true);
|
||||
}));
|
||||
it('should return -Infinity', SX(async function() {
|
||||
let result = await page.evaluate(() => -Infinity);
|
||||
const result = await page.evaluate(() => -Infinity);
|
||||
expect(Object.is(result, -Infinity)).toBe(true);
|
||||
}));
|
||||
it('should not fail for window object', SX(async function() {
|
||||
let result = await page.evaluate(() => window);
|
||||
const result = await page.evaluate(() => window);
|
||||
expect(result).toBe('Window');
|
||||
}));
|
||||
it('should accept a string', SX(async function() {
|
||||
let result = await page.evaluate('1 + 2');
|
||||
const result = await page.evaluate('1 + 2');
|
||||
expect(result).toBe(3);
|
||||
}));
|
||||
it('should accept a string with semi colons', SX(async function() {
|
||||
let result = await page.evaluate('1 + 5;');
|
||||
const result = await page.evaluate('1 + 5;');
|
||||
expect(result).toBe(6);
|
||||
}));
|
||||
it('should accept a string with comments', SX(async function() {
|
||||
let result = await page.evaluate('2 + 5;\n// do some math!');
|
||||
const result = await page.evaluate('2 + 5;\n// do some math!');
|
||||
expect(result).toBe(7);
|
||||
}));
|
||||
});
|
||||
@ -260,13 +260,13 @@ describe('Page', function() {
|
||||
});
|
||||
|
||||
describe('Frame.evaluate', function() {
|
||||
let FrameUtils = require('./frame-utils');
|
||||
const FrameUtils = require('./frame-utils');
|
||||
it('should have different execution contexts', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);
|
||||
expect(page.frames().length).toBe(2);
|
||||
let frame1 = page.frames()[0];
|
||||
let frame2 = page.frames()[1];
|
||||
const frame1 = page.frames()[0];
|
||||
const frame2 = page.frames()[1];
|
||||
await frame1.evaluate(() => window.FOO = 'foo');
|
||||
await frame2.evaluate(() => window.FOO = 'bar');
|
||||
expect(await frame1.evaluate(() => window.FOO)).toBe('foo');
|
||||
@ -274,7 +274,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should execute after cross-site navigation', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let mainFrame = page.mainFrame();
|
||||
const mainFrame = page.mainFrame();
|
||||
expect(await mainFrame.evaluate(() => window.location.href)).toContain('localhost');
|
||||
await page.goto(CROSS_PROCESS_PREFIX + '/empty.html');
|
||||
expect(await mainFrame.evaluate(() => window.location.href)).toContain('127');
|
||||
@ -336,12 +336,12 @@ describe('Page', function() {
|
||||
});
|
||||
|
||||
describe('Frame.waitForSelector', function() {
|
||||
let FrameUtils = require('./frame-utils');
|
||||
let addElement = tag => document.body.appendChild(document.createElement(tag));
|
||||
const FrameUtils = require('./frame-utils');
|
||||
const addElement = tag => document.body.appendChild(document.createElement(tag));
|
||||
|
||||
it('should immediately resolve promise if node exists', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let frame = page.mainFrame();
|
||||
const frame = page.mainFrame();
|
||||
let added = false;
|
||||
await frame.waitForSelector('*').then(() => added = true);
|
||||
expect(added).toBe(true);
|
||||
@ -354,9 +354,9 @@ describe('Page', function() {
|
||||
|
||||
it('should resolve promise when node is added', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let frame = page.mainFrame();
|
||||
const frame = page.mainFrame();
|
||||
let added = false;
|
||||
let watchdog = frame.waitForSelector('div').then(() => added = true);
|
||||
const watchdog = frame.waitForSelector('div').then(() => added = true);
|
||||
// run nop function..
|
||||
await frame.evaluate(() => 42);
|
||||
// .. to be sure that waitForSelector promise is not resolved yet.
|
||||
@ -370,7 +370,7 @@ describe('Page', function() {
|
||||
|
||||
it('should work when node is added through innerHTML', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let watchdog = page.waitForSelector('h3 div');
|
||||
const watchdog = page.waitForSelector('h3 div');
|
||||
await page.evaluate(addElement, 'span');
|
||||
await page.evaluate(() => document.querySelector('span').innerHTML = '<h3><div></div></h3>');
|
||||
await watchdog;
|
||||
@ -379,7 +379,7 @@ describe('Page', function() {
|
||||
it('Page.waitForSelector is shortcut for main frame', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);
|
||||
let otherFrame = page.frames()[1];
|
||||
const otherFrame = page.frames()[1];
|
||||
let added = false;
|
||||
page.waitForSelector('div').then(() => added = true);
|
||||
await otherFrame.evaluate(addElement, 'div');
|
||||
@ -391,8 +391,8 @@ describe('Page', function() {
|
||||
it('should run in specified frame', SX(async function() {
|
||||
await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);
|
||||
await FrameUtils.attachFrame(page, 'frame2', EMPTY_PAGE);
|
||||
let frame1 = page.frames()[1];
|
||||
let frame2 = page.frames()[2];
|
||||
const frame1 = page.frames()[1];
|
||||
const frame2 = page.frames()[2];
|
||||
let added = false;
|
||||
frame2.waitForSelector('div').then(() => added = true);
|
||||
expect(added).toBe(false);
|
||||
@ -416,9 +416,9 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should throw when frame is detached', SX(async function() {
|
||||
await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);
|
||||
let frame = page.frames()[1];
|
||||
const frame = page.frames()[1];
|
||||
let waitError = null;
|
||||
let waitPromise = frame.waitForSelector('.box').catch(e => waitError = e);
|
||||
const waitPromise = frame.waitForSelector('.box').catch(e => waitError = e);
|
||||
await FrameUtils.detachFrame(page, 'frame1');
|
||||
await waitPromise;
|
||||
expect(waitError).toBeTruthy();
|
||||
@ -426,7 +426,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should survive cross-process navigation', SX(async function() {
|
||||
let boxFound = false;
|
||||
let waitForSelector = page.waitForSelector('.box').then(() => boxFound = true);
|
||||
const waitForSelector = page.waitForSelector('.box').then(() => boxFound = true);
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(boxFound).toBe(false);
|
||||
await page.reload();
|
||||
@ -437,7 +437,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should wait for visible', SX(async function() {
|
||||
let divFound = false;
|
||||
let waitForSelector = page.waitForSelector('div', {visible: true}).then(() => divFound = true);
|
||||
const waitForSelector = page.waitForSelector('div', {visible: true}).then(() => divFound = true);
|
||||
await page.setContent(`<div style='display: none;visibility: hidden'></div>`);
|
||||
expect(divFound).toBe(false);
|
||||
await page.evaluate(() => document.querySelector('div').style.removeProperty('display'));
|
||||
@ -456,7 +456,7 @@ describe('Page', function() {
|
||||
describe('Page.waitFor', function() {
|
||||
it('should wait for selector', SX(async function() {
|
||||
let found = false;
|
||||
let waitFor = page.waitFor('div').then(() => found = true);
|
||||
const waitFor = page.waitFor('div').then(() => found = true);
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(found).toBe(false);
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
@ -464,7 +464,7 @@ describe('Page', function() {
|
||||
expect(found).toBe(true);
|
||||
}));
|
||||
it('should timeout', SX(async function() {
|
||||
let startTime = Date.now();
|
||||
const startTime = Date.now();
|
||||
const timeout = 42;
|
||||
await page.waitFor(timeout);
|
||||
expect(Date.now() - startTime).not.toBeLessThan(timeout / 2);
|
||||
@ -495,7 +495,7 @@ describe('Page', function() {
|
||||
expect(commandArgs).toEqual([5, 'hello', {foo: 'bar'}]);
|
||||
}));
|
||||
it('should work for different console API calls', SX(async function() {
|
||||
let messages = [];
|
||||
const messages = [];
|
||||
page.on('console', msg => messages.push(msg));
|
||||
await Promise.all([
|
||||
page.evaluate(() => {
|
||||
@ -533,7 +533,7 @@ describe('Page', function() {
|
||||
|
||||
describe('Page.goto', function() {
|
||||
it('should navigate to about:blank', SX(async function() {
|
||||
let response = await page.goto('about:blank');
|
||||
const response = await page.goto('about:blank');
|
||||
expect(response).toBe(null);
|
||||
}));
|
||||
it('should fail when navigating to bad url', SX(async function() {
|
||||
@ -607,16 +607,16 @@ describe('Page', function() {
|
||||
server.setRoute('/fetch-request-b.js', (req, res) => responses.push(res));
|
||||
server.setRoute('/fetch-request-c.js', (req, res) => responses.push(res));
|
||||
server.setRoute('/fetch-request-d.js', (req, res) => responses.push(res));
|
||||
let initialFetchResourcesRequested = Promise.all([
|
||||
const initialFetchResourcesRequested = Promise.all([
|
||||
server.waitForRequest('/fetch-request-a.js'),
|
||||
server.waitForRequest('/fetch-request-b.js'),
|
||||
server.waitForRequest('/fetch-request-c.js'),
|
||||
]);
|
||||
let secondFetchResourceRequested = server.waitForRequest('/fetch-request-d.js');
|
||||
const secondFetchResourceRequested = server.waitForRequest('/fetch-request-d.js');
|
||||
|
||||
// Navigate to a page which loads immediately and then does a bunch of
|
||||
// requests via javascript's fetch method.
|
||||
let navigationPromise = page.goto(PREFIX + '/networkidle.html', {
|
||||
const navigationPromise = page.goto(PREFIX + '/networkidle.html', {
|
||||
waitUntil: 'networkidle',
|
||||
networkIdleTimeout: 100,
|
||||
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests
|
||||
@ -636,7 +636,7 @@ describe('Page', function() {
|
||||
expect(navigationFinished).toBe(false);
|
||||
|
||||
// Respond to initial requests.
|
||||
for (let response of responses) {
|
||||
for (const response of responses) {
|
||||
response.statusCode = 404;
|
||||
response.end(`File not found`);
|
||||
}
|
||||
@ -650,7 +650,7 @@ describe('Page', function() {
|
||||
expect(navigationFinished).toBe(false);
|
||||
|
||||
// Respond to requests.
|
||||
for (let response of responses) {
|
||||
for (const response of responses) {
|
||||
response.statusCode = 404;
|
||||
response.end(`File not found`);
|
||||
}
|
||||
@ -660,13 +660,13 @@ describe('Page', function() {
|
||||
expect(response.ok).toBe(true);
|
||||
}));
|
||||
it('should wait for websockets to succeed navigation', SX(async function() {
|
||||
let responses = [];
|
||||
const responses = [];
|
||||
// Hold on to the fetch request without answering.
|
||||
server.setRoute('/fetch-request.js', (req, res) => responses.push(res));
|
||||
let fetchResourceRequested = server.waitForRequest('/fetch-request.js');
|
||||
const fetchResourceRequested = server.waitForRequest('/fetch-request.js');
|
||||
// Navigate to a page which loads immediately and then opens a bunch of
|
||||
// websocket connections and then a fetch request.
|
||||
let navigationPromise = page.goto(PREFIX + '/websocket.html', {
|
||||
const navigationPromise = page.goto(PREFIX + '/websocket.html', {
|
||||
waitUntil: 'networkidle',
|
||||
networkIdleTimeout: 100,
|
||||
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests/connections
|
||||
@ -686,7 +686,7 @@ describe('Page', function() {
|
||||
expect(navigationFinished).toBe(false);
|
||||
|
||||
// Respond to the request.
|
||||
for (let response of responses) {
|
||||
for (const response of responses) {
|
||||
response.statusCode = 404;
|
||||
response.end(`File not found`);
|
||||
}
|
||||
@ -704,18 +704,18 @@ describe('Page', function() {
|
||||
expect(warning).toBe(null);
|
||||
}));
|
||||
it('should navigate to dataURL and fire dataURL requests', SX(async function() {
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
let dataURL = 'data:text/html,<div>yo</div>';
|
||||
let response = await page.goto(dataURL);
|
||||
const dataURL = 'data:text/html,<div>yo</div>';
|
||||
const response = await page.goto(dataURL);
|
||||
expect(response.status).toBe(200);
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0].url).toBe(dataURL);
|
||||
}));
|
||||
it('should navigate to URL with hash and fire requests without hash', SX(async function() {
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
let response = await page.goto(EMPTY_PAGE + '#hash');
|
||||
const response = await page.goto(EMPTY_PAGE + '#hash');
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.url).toBe(EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
@ -759,7 +759,7 @@ describe('Page', function() {
|
||||
await page.exposeFunction('compute', function(a, b) {
|
||||
return a * b;
|
||||
});
|
||||
let result = await page.evaluate(async function() {
|
||||
const result = await page.evaluate(async function() {
|
||||
return await compute(9, 4);
|
||||
});
|
||||
expect(result).toBe(36);
|
||||
@ -770,7 +770,7 @@ describe('Page', function() {
|
||||
});
|
||||
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let result = await page.evaluate(async function() {
|
||||
const result = await page.evaluate(async function() {
|
||||
return await compute(9, 4);
|
||||
});
|
||||
expect(result).toBe(36);
|
||||
@ -780,7 +780,7 @@ describe('Page', function() {
|
||||
return Promise.resolve(a * b);
|
||||
});
|
||||
|
||||
let result = await page.evaluate(async function() {
|
||||
const result = await page.evaluate(async function() {
|
||||
return await compute(3, 5);
|
||||
});
|
||||
expect(result).toBe(15);
|
||||
@ -829,7 +829,7 @@ describe('Page', function() {
|
||||
it('should amend HTTP headers', SX(async function() {
|
||||
await page.setRequestInterceptionEnabled(true);
|
||||
page.on('request', request => {
|
||||
let headers = new Map(request.headers);
|
||||
const headers = new Map(request.headers);
|
||||
headers.set('foo', 'bar');
|
||||
request.continue({ headers });
|
||||
});
|
||||
@ -859,7 +859,7 @@ describe('Page', function() {
|
||||
server.setRedirect('/non-existing-page-2.html', '/non-existing-page-3.html');
|
||||
server.setRedirect('/non-existing-page-3.html', '/non-existing-page-4.html');
|
||||
server.setRedirect('/non-existing-page-4.html', '/empty.html');
|
||||
let response = await page.goto(PREFIX + '/non-existing-page.html');
|
||||
const response = await page.goto(PREFIX + '/non-existing-page.html');
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.url).toContain('empty.html');
|
||||
}));
|
||||
@ -874,7 +874,7 @@ describe('Page', function() {
|
||||
request.continue();
|
||||
});
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let result = await page.evaluate(async() => {
|
||||
const result = await page.evaluate(async() => {
|
||||
try {
|
||||
await fetch('/non-existing.json');
|
||||
} catch (e) {
|
||||
@ -895,7 +895,7 @@ describe('Page', function() {
|
||||
spinner ? request.abort() : request.continue();
|
||||
spinner = !spinner;
|
||||
});
|
||||
let results = await page.evaluate(() => Promise.all([
|
||||
const results = await page.evaluate(() => Promise.all([
|
||||
fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),
|
||||
fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),
|
||||
fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),
|
||||
@ -904,25 +904,25 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should navigate to dataURL and fire dataURL requests', SX(async function() {
|
||||
await page.setRequestInterceptionEnabled(true);
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
});
|
||||
let dataURL = 'data:text/html,<div>yo</div>';
|
||||
let response = await page.goto(dataURL);
|
||||
const dataURL = 'data:text/html,<div>yo</div>';
|
||||
const response = await page.goto(dataURL);
|
||||
expect(response.status).toBe(200);
|
||||
expect(requests.length).toBe(1);
|
||||
expect(requests[0].url).toBe(dataURL);
|
||||
}));
|
||||
it('should navigate to URL with hash and and fire requests without hash', SX(async function() {
|
||||
await page.setRequestInterceptionEnabled(true);
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => {
|
||||
requests.push(request);
|
||||
request.continue();
|
||||
});
|
||||
let response = await page.goto(EMPTY_PAGE + '#hash');
|
||||
const response = await page.goto(EMPTY_PAGE + '#hash');
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.url).toBe(EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
@ -947,14 +947,14 @@ describe('Page', function() {
|
||||
expect(dialog.message()).toBe('question?');
|
||||
dialog.accept('answer!');
|
||||
});
|
||||
let result = await page.evaluate(() => prompt('question?', 'yes.'));
|
||||
const result = await page.evaluate(() => prompt('question?', 'yes.'));
|
||||
expect(result).toBe('answer!');
|
||||
}));
|
||||
it('should dismiss the prompt', SX(async function() {
|
||||
page.on('dialog', dialog => {
|
||||
dialog.dismiss();
|
||||
});
|
||||
let result = await page.evaluate(() => prompt('question?'));
|
||||
const result = await page.evaluate(() => prompt('question?'));
|
||||
expect(result).toBe(null);
|
||||
}));
|
||||
});
|
||||
@ -971,7 +971,7 @@ describe('Page', function() {
|
||||
|
||||
describe('Page.Events.Request', function() {
|
||||
it('should fire', SX(async function() {
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
@ -980,7 +980,7 @@ describe('Page', function() {
|
||||
});
|
||||
|
||||
describe('Frame Management', function() {
|
||||
let FrameUtils = require('./frame-utils');
|
||||
const FrameUtils = require('./frame-utils');
|
||||
it('should handle nested frames', SX(async function() {
|
||||
await page.goto(PREFIX + '/frames/nested-frames.html');
|
||||
expect(FrameUtils.dumpFrames(page.mainFrame())).toBeGolden('nested-frames.txt');
|
||||
@ -988,21 +988,21 @@ describe('Page', function() {
|
||||
it('should send events when frames are manipulated dynamically', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
// validate frameattached events
|
||||
let attachedFrames = [];
|
||||
const attachedFrames = [];
|
||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||
await FrameUtils.attachFrame(page, 'frame1', './assets/frame.html');
|
||||
expect(attachedFrames.length).toBe(1);
|
||||
expect(attachedFrames[0].url()).toContain('/assets/frame.html');
|
||||
|
||||
// validate framenavigated events
|
||||
let navigatedFrames = [];
|
||||
const navigatedFrames = [];
|
||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||
await FrameUtils.navigateFrame(page, 'frame1', './empty.html');
|
||||
expect(navigatedFrames.length).toBe(1);
|
||||
expect(navigatedFrames[0].url()).toContain('/empty.html');
|
||||
|
||||
// validate framedetached events
|
||||
let detachedFrames = [];
|
||||
const detachedFrames = [];
|
||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||
await FrameUtils.detachFrame(page, 'frame1');
|
||||
expect(detachedFrames.length).toBe(1);
|
||||
@ -1010,7 +1010,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should persist mainFrame on cross-process navigation', SX(async function() {
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let mainFrame = page.mainFrame();
|
||||
const mainFrame = page.mainFrame();
|
||||
await page.goto('http://127.0.0.1:' + PORT + '/empty.html');
|
||||
expect(page.mainFrame() === mainFrame).toBeTruthy();
|
||||
}));
|
||||
@ -1044,7 +1044,7 @@ describe('Page', function() {
|
||||
it('should report frame.name()', SX(async function() {
|
||||
await FrameUtils.attachFrame(page, 'theFrameId', EMPTY_PAGE);
|
||||
await page.evaluate(url => {
|
||||
let frame = document.createElement('iframe');
|
||||
const frame = document.createElement('iframe');
|
||||
frame.name = 'theFrameName';
|
||||
frame.src = url;
|
||||
document.body.appendChild(frame);
|
||||
@ -1066,11 +1066,11 @@ describe('Page', function() {
|
||||
describe('Page.$', function() {
|
||||
it('should query existing element', SX(async function() {
|
||||
await page.setContent('<section>test</section>');
|
||||
let element = await page.$('section');
|
||||
const element = await page.$('section');
|
||||
expect(element).toBeTruthy();
|
||||
}));
|
||||
it('should return null for non-existing element', SX(async function() {
|
||||
let element = await page.$('non-existing-element');
|
||||
const element = await page.$('non-existing-element');
|
||||
expect(element).toBe(null);
|
||||
}));
|
||||
});
|
||||
@ -1078,20 +1078,20 @@ describe('Page', function() {
|
||||
describe('ElementHandle.evaluate', function() {
|
||||
it('should work', SX(async function() {
|
||||
await page.setContent('<section>42</section>');
|
||||
let element = await page.$('section');
|
||||
let text = await element.evaluate(e => e.textContent);
|
||||
const element = await page.$('section');
|
||||
const text = await element.evaluate(e => e.textContent);
|
||||
expect(text).toBe('42');
|
||||
}));
|
||||
it('should await promise if any', SX(async function() {
|
||||
await page.setContent('<section>39</section>');
|
||||
let element = await page.$('section');
|
||||
let text = await element.evaluate(e => Promise.resolve(e.textContent));
|
||||
const element = await page.$('section');
|
||||
const text = await element.evaluate(e => Promise.resolve(e.textContent));
|
||||
expect(text).toBe('39');
|
||||
}));
|
||||
it('should throw if underlying page got closed', SX(async function() {
|
||||
let otherPage = await browser.newPage();
|
||||
const otherPage = await browser.newPage();
|
||||
await otherPage.setContent('<section>88</section>');
|
||||
let element = await otherPage.$('section');
|
||||
const element = await otherPage.$('section');
|
||||
expect(element).toBeTruthy();
|
||||
await otherPage.close();
|
||||
let error = null;
|
||||
@ -1104,7 +1104,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should throw if underlying element was disposed', SX(async function() {
|
||||
await page.setContent('<section>39</section>');
|
||||
let element = await page.$('section');
|
||||
const element = await page.$('section');
|
||||
expect(element).toBeTruthy();
|
||||
await element.dispose();
|
||||
let error = null;
|
||||
@ -1120,7 +1120,7 @@ describe('Page', function() {
|
||||
describe('ElementHandle.click', function() {
|
||||
it('should work', SX(async function() {
|
||||
await page.goto(PREFIX + '/input/button.html');
|
||||
let button = await page.$('button');
|
||||
const button = await page.$('button');
|
||||
await button.click('button');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
}));
|
||||
@ -1129,7 +1129,7 @@ describe('Page', function() {
|
||||
describe('ElementHandle.hover', function() {
|
||||
it('should work', SX(async function() {
|
||||
await page.goto(PREFIX + '/input/scrollable.html');
|
||||
let button = await page.$('#button-6');
|
||||
const button = await page.$('#button-6');
|
||||
await button.hover();
|
||||
expect(await page.evaluate(() => document.querySelector('button:hover').id)).toBe('button-6');
|
||||
}));
|
||||
@ -1173,12 +1173,12 @@ describe('Page', function() {
|
||||
it('should upload the file', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/fileupload.html');
|
||||
const filePath = path.relative(process.cwd(), __dirname + '/assets/file-to-upload.txt');
|
||||
let input = await page.$('input');
|
||||
const input = await page.$('input');
|
||||
await input.uploadFile(filePath);
|
||||
expect(await input.evaluate(e => e.files[0].name)).toBe('file-to-upload.txt');
|
||||
expect(await input.evaluate(e => {
|
||||
let reader = new FileReader();
|
||||
let promise = new Promise(fulfill => reader.onload = fulfill);
|
||||
const reader = new FileReader();
|
||||
const promise = new Promise(fulfill => reader.onload = fulfill);
|
||||
reader.readAsText(e.files[0]);
|
||||
return promise.then(() => reader.result);
|
||||
})).toBe('contents of the file');
|
||||
@ -1221,9 +1221,9 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should report shiftKey', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
let keyboard = page.keyboard;
|
||||
let codeForKey = {'Shift': 16, 'Alt': 18, 'Meta': 91, 'Control': 17};
|
||||
for (let modifierKey in codeForKey) {
|
||||
const keyboard = page.keyboard;
|
||||
const codeForKey = {'Shift': 16, 'Alt': 18, 'Meta': 91, 'Control': 17};
|
||||
for (const modifierKey in codeForKey) {
|
||||
await keyboard.down(modifierKey);
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: ' + modifierKey + ' ' + codeForKey[modifierKey] + ' [' + modifierKey + ']');
|
||||
await keyboard.down('!');
|
||||
@ -1236,7 +1236,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should report multiple modifiers', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
let keyboard = page.keyboard;
|
||||
const keyboard = page.keyboard;
|
||||
await keyboard.down('Control');
|
||||
expect(await page.evaluate(() => getResult())).toBe('Keydown: Control 17 [Control]');
|
||||
await keyboard.down('Meta');
|
||||
@ -1265,7 +1265,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should send propery codes while typing with shift', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/keyboard.html');
|
||||
let keyboard = page.keyboard;
|
||||
const keyboard = page.keyboard;
|
||||
await keyboard.down('Shift');
|
||||
await page.type('~');
|
||||
expect(await page.evaluate(() => getResult())).toBe(
|
||||
@ -1292,7 +1292,7 @@ describe('Page', function() {
|
||||
expect(await page.evaluate(() => textarea.value)).toBe('He Wrd!');
|
||||
}));
|
||||
it('keyboard.modifiers()', SX(async function(){
|
||||
let keyboard = page.keyboard;
|
||||
const keyboard = page.keyboard;
|
||||
expect(keyboard._modifiers).toBe(0);
|
||||
await keyboard.down('Shift');
|
||||
expect(keyboard._modifiers).toBe(8);
|
||||
@ -1304,13 +1304,13 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should resize the textarea', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/textarea.html');
|
||||
let {x, y, width, height} = await page.evaluate(dimensions);
|
||||
let mouse = page.mouse;
|
||||
const {x, y, width, height} = await page.evaluate(dimensions);
|
||||
const mouse = page.mouse;
|
||||
await mouse.move(x + width - 4, y + height - 4);
|
||||
await mouse.down();
|
||||
await mouse.move(x + width + 100, y + height + 100);
|
||||
await mouse.up();
|
||||
let newDimensions = await page.evaluate(dimensions);
|
||||
const newDimensions = await page.evaluate(dimensions);
|
||||
expect(newDimensions.width).toBe(width + 104);
|
||||
expect(newDimensions.height).toBe(height + 104);
|
||||
}));
|
||||
@ -1324,7 +1324,7 @@ describe('Page', function() {
|
||||
it('should click a partially obscured button', SX(async function() {
|
||||
await page.goto(PREFIX + '/input/button.html');
|
||||
await page.evaluate(() => {
|
||||
let button = document.querySelector('button');
|
||||
const button = document.querySelector('button');
|
||||
button.textContent = 'Some really long text that will go offscreen';
|
||||
button.style.position = 'absolute';
|
||||
button.style.left = '368px';
|
||||
@ -1335,10 +1335,10 @@ describe('Page', function() {
|
||||
it('should select the text with mouse', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/textarea.html');
|
||||
await page.focus('textarea');
|
||||
let text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
const text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
await page.type(text);
|
||||
await page.evaluate(() => document.querySelector('textarea').scrollTop = 0);
|
||||
let {x, y} = await page.evaluate(dimensions);
|
||||
const {x, y} = await page.evaluate(dimensions);
|
||||
await page.mouse.move(x + 2,y + 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(100,100);
|
||||
@ -1348,7 +1348,7 @@ describe('Page', function() {
|
||||
it('should select the text by triple clicking', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/textarea.html');
|
||||
await page.focus('textarea');
|
||||
let text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
const text = 'This is the text that we are going to try to select. Let\'s see how it goes.';
|
||||
await page.type(text);
|
||||
await page.click('textarea');
|
||||
await page.click('textarea', {clickCount: 2});
|
||||
@ -1372,8 +1372,8 @@ describe('Page', function() {
|
||||
it('should set modifier keys on click', SX(async function(){
|
||||
await page.goto(PREFIX + '/input/scrollable.html');
|
||||
await page.evaluate(() => document.querySelector('#button-3').addEventListener('mousedown', e => window.lastEvent = e, true));
|
||||
let modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
|
||||
for (let modifier in modifiers) {
|
||||
const modifiers = {'Shift': 'shiftKey', 'Control': 'ctrlKey', 'Alt': 'altKey', 'Meta': 'metaKey'};
|
||||
for (const modifier in modifiers) {
|
||||
await page.keyboard.down(modifier);
|
||||
await page.click('#button-3');
|
||||
if (!(await page.evaluate(mod => window.lastEvent[mod], modifiers[modifier])))
|
||||
@ -1381,7 +1381,7 @@ describe('Page', function() {
|
||||
await page.keyboard.up(modifier);
|
||||
}
|
||||
await page.click('#button-3');
|
||||
for (let modifier in modifiers) {
|
||||
for (const modifier in modifiers) {
|
||||
if ((await page.evaluate(mod => window.lastEvent[mod], modifiers[modifier])))
|
||||
fail(modifiers[modifier] + ' should be false');
|
||||
}
|
||||
@ -1402,7 +1402,7 @@ describe('Page', function() {
|
||||
await page.click('a');
|
||||
}));
|
||||
function dimensions() {
|
||||
let rect = document.querySelector('textarea').getBoundingClientRect();
|
||||
const rect = document.querySelector('textarea').getBoundingClientRect();
|
||||
return {
|
||||
x: rect.left,
|
||||
y: rect.top,
|
||||
@ -1417,7 +1417,7 @@ describe('Page', function() {
|
||||
expect(await page.evaluate(() => navigator.userAgent)).toContain('Mozilla');
|
||||
page.setUserAgent('foobar');
|
||||
page.goto(EMPTY_PAGE);
|
||||
let request = await server.waitForRequest('/empty.html');
|
||||
const request = await server.waitForRequest('/empty.html');
|
||||
expect(request.headers['user-agent']).toBe('foobar');
|
||||
}));
|
||||
it('should emulate device user-agent', SX(async function() {
|
||||
@ -1433,7 +1433,7 @@ describe('Page', function() {
|
||||
foo: 'bar'
|
||||
})));
|
||||
page.goto(EMPTY_PAGE);
|
||||
let request = await server.waitForRequest('/empty.html');
|
||||
const request = await server.waitForRequest('/empty.html');
|
||||
expect(request.headers['foo']).toBe('bar');
|
||||
}));
|
||||
});
|
||||
@ -1441,26 +1441,26 @@ describe('Page', function() {
|
||||
const expectedOutput = '<html><head></head><body><div>hello</div></body></html>';
|
||||
it('should work', SX(async function() {
|
||||
await page.setContent('<div>hello</div>');
|
||||
let result = await page.content();
|
||||
const result = await page.content();
|
||||
expect(result).toBe(expectedOutput);
|
||||
}));
|
||||
it('should work with doctype', SX(async function() {
|
||||
const doctype = '<!DOCTYPE html>';
|
||||
await page.setContent(`${doctype}<div>hello</div>`);
|
||||
let result = await page.content();
|
||||
const result = await page.content();
|
||||
expect(result).toBe(`${doctype}${expectedOutput}`);
|
||||
}));
|
||||
it('should work with HTML 4 doctype', SX(async function() {
|
||||
const doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" ' +
|
||||
'"http://www.w3.org/TR/html4/strict.dtd">';
|
||||
await page.setContent(`${doctype}<div>hello</div>`);
|
||||
let result = await page.content();
|
||||
const result = await page.content();
|
||||
expect(result).toBe(`${doctype}${expectedOutput}`);
|
||||
}));
|
||||
});
|
||||
describe('Network Events', function() {
|
||||
it('Page.Events.Request', SX(async function() {
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('request', request => requests.push(request));
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
@ -1478,7 +1478,7 @@ describe('Page', function() {
|
||||
expect(request.postData).toBe('{"foo":"bar"}');
|
||||
}));
|
||||
it('Page.Events.Response', SX(async function() {
|
||||
let responses = [];
|
||||
const responses = [];
|
||||
page.on('response', response => responses.push(response));
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(responses.length).toBe(1);
|
||||
@ -1519,7 +1519,7 @@ describe('Page', function() {
|
||||
expect(pageResponse.status).toBe(200);
|
||||
expect(requestFinished).toBe(false);
|
||||
|
||||
let responseText = pageResponse.text();
|
||||
const responseText = pageResponse.text();
|
||||
// Write part of the response and wait for it to be flushed.
|
||||
await new Promise(x => serverResponse.write('wor', x));
|
||||
// Finish response.
|
||||
@ -1534,7 +1534,7 @@ describe('Page', function() {
|
||||
else
|
||||
request.continue();
|
||||
});
|
||||
let failedRequests = [];
|
||||
const failedRequests = [];
|
||||
page.on('requestfailed', request => failedRequests.push(request));
|
||||
await page.goto(PREFIX + '/one-style.html');
|
||||
expect(failedRequests.length).toBe(1);
|
||||
@ -1542,7 +1542,7 @@ describe('Page', function() {
|
||||
expect(failedRequests[0].response()).toBe(null);
|
||||
}));
|
||||
it('Page.Events.RequestFinished', SX(async function() {
|
||||
let requests = [];
|
||||
const requests = [];
|
||||
page.on('requestfinished', request => requests.push(request));
|
||||
await page.goto(EMPTY_PAGE);
|
||||
expect(requests.length).toBe(1);
|
||||
@ -1550,7 +1550,7 @@ describe('Page', function() {
|
||||
expect(requests[0].response()).toBeTruthy();
|
||||
}));
|
||||
it('should fire events in proper order', SX(async function() {
|
||||
let events = [];
|
||||
const events = [];
|
||||
page.on('request', request => events.push('request'));
|
||||
page.on('response', response => events.push('response'));
|
||||
page.on('requestfinished', request => events.push('requestfinished'));
|
||||
@ -1558,7 +1558,7 @@ describe('Page', function() {
|
||||
expect(events).toEqual(['request', 'response', 'requestfinished']);
|
||||
}));
|
||||
it('should support redirects', SX(async function() {
|
||||
let events = [];
|
||||
const events = [];
|
||||
page.on('request', request => events.push(`${request.method} ${request.url}`));
|
||||
page.on('response', response => events.push(`${response.status} ${response.url}`));
|
||||
page.on('requestfinished', request => events.push(`DONE ${request.url}`));
|
||||
@ -1618,7 +1618,7 @@ describe('Page', function() {
|
||||
|
||||
function dispatchTouch() {
|
||||
let fulfill;
|
||||
let promise = new Promise(x => fulfill = x);
|
||||
const promise = new Promise(x => fulfill = x);
|
||||
window.ontouchstart = function(e) {
|
||||
fulfill('Recieved touch');
|
||||
};
|
||||
@ -1692,13 +1692,13 @@ describe('Page', function() {
|
||||
fs.unlinkSync(outputFile);
|
||||
}));
|
||||
it('should default to printing in Letter format', SX(async function() {
|
||||
let pages = await getPDFPages(await page.pdf());
|
||||
const pages = await getPDFPages(await page.pdf());
|
||||
expect(pages.length).toBe(1);
|
||||
expect(pages[0].width).toBeCloseTo(8.5, 2);
|
||||
expect(pages[0].height).toBeCloseTo(11, 2);
|
||||
}));
|
||||
it('should support setting custom format', SX(async function() {
|
||||
let pages = await getPDFPages(await page.pdf({
|
||||
const pages = await getPDFPages(await page.pdf({
|
||||
format: 'a4'
|
||||
}));
|
||||
expect(pages.length).toBe(1);
|
||||
@ -1706,7 +1706,7 @@ describe('Page', function() {
|
||||
expect(pages[0].height).toBeCloseTo(11.7, 1);
|
||||
}));
|
||||
it('should support setting paper width and height', SX(async function() {
|
||||
let pages = await getPDFPages(await page.pdf({
|
||||
const pages = await getPDFPages(await page.pdf({
|
||||
width: '10in',
|
||||
height: '10in',
|
||||
}));
|
||||
@ -1719,7 +1719,7 @@ describe('Page', function() {
|
||||
// Define width and height in CSS pixels.
|
||||
const width = 50 * 5 + 1;
|
||||
const height = 50 * 5 + 1;
|
||||
let pages = await getPDFPages(await page.pdf({width, height}));
|
||||
const pages = await getPDFPages(await page.pdf({width, height}));
|
||||
expect(pages.length).toBe(8);
|
||||
expect(pages[0].width).toBeCloseTo(cssPixelsToInches(width), 2);
|
||||
expect(pages[0].height).toBeCloseTo(cssPixelsToInches(height), 2);
|
||||
@ -1729,7 +1729,7 @@ describe('Page', function() {
|
||||
// Define width and height in CSS pixels.
|
||||
const width = 50 * 5 + 1;
|
||||
const height = 50 * 5 + 1;
|
||||
let pages = await getPDFPages(await page.pdf({width, height, pageRanges: '1,4-7'}));
|
||||
const pages = await getPDFPages(await page.pdf({width, height, pageRanges: '1,4-7'}));
|
||||
expect(pages.length).toBe(5);
|
||||
}));
|
||||
it('should throw if format is unknown', SX(async function() {
|
||||
@ -1777,13 +1777,13 @@ describe('Page', function() {
|
||||
it('should work', SX(async function() {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
let screenshot = await page.screenshot();
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot).toBeGolden('screenshot-sanity.png');
|
||||
}));
|
||||
it('should clip rect', SX(async function() {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
let screenshot = await page.screenshot({
|
||||
const screenshot = await page.screenshot({
|
||||
clip: {
|
||||
x: 50,
|
||||
y: 100,
|
||||
@ -1796,7 +1796,7 @@ describe('Page', function() {
|
||||
it('should work for offscreen clip', SX(async function() {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
let screenshot = await page.screenshot({
|
||||
const screenshot = await page.screenshot({
|
||||
clip: {
|
||||
x: 50,
|
||||
y: 600,
|
||||
@ -1809,7 +1809,7 @@ describe('Page', function() {
|
||||
it('should run in parallel', SX(async function() {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
let promises = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
promises.push(page.screenshot({
|
||||
clip: {
|
||||
@ -1820,28 +1820,28 @@ describe('Page', function() {
|
||||
}
|
||||
}));
|
||||
}
|
||||
let screenshots = await Promise.all(promises);
|
||||
const screenshots = await Promise.all(promises);
|
||||
expect(screenshots[1]).toBeGolden('grid-cell-1.png');
|
||||
}));
|
||||
it('should take fullPage screenshots', SX(async function() {
|
||||
await page.setViewport({width: 500, height: 500});
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
let screenshot = await page.screenshot({
|
||||
const screenshot = await page.screenshot({
|
||||
fullPage: true
|
||||
});
|
||||
expect(screenshot).toBeGolden('screenshot-grid-fullpage.png');
|
||||
}));
|
||||
it('should run in parallel in multiple pages', SX(async function() {
|
||||
const N = 2;
|
||||
let pages = await Promise.all(Array(N).fill(0).map(async() => {
|
||||
let page = await browser.newPage();
|
||||
const pages = await Promise.all(Array(N).fill(0).map(async() => {
|
||||
const page = await browser.newPage();
|
||||
await page.goto(PREFIX + '/grid.html');
|
||||
return page;
|
||||
}));
|
||||
let promises = [];
|
||||
const promises = [];
|
||||
for (let i = 0; i < N; ++i)
|
||||
promises.push(pages[i].screenshot({ clip: { x: 50 * i, y: 0, width: 50, height: 50 } }));
|
||||
let screenshots = await Promise.all(promises);
|
||||
const screenshots = await Promise.all(promises);
|
||||
for (let i = 0; i < N; ++i)
|
||||
expect(screenshots[i]).toBeGolden(`grid-cell-${i}.png`);
|
||||
await Promise.all(pages.map(page => page.close()));
|
||||
@ -1849,13 +1849,13 @@ describe('Page', function() {
|
||||
it('should allow transparency', SX(async function() {
|
||||
await page.setViewport({ width: 100, height: 100 });
|
||||
await page.goto(EMPTY_PAGE);
|
||||
let screenshot = await page.screenshot({omitBackground:true});
|
||||
const screenshot = await page.screenshot({omitBackground:true});
|
||||
expect(screenshot).toBeGolden('transparent.png');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Tracing', function() {
|
||||
let outputFile = path.join(__dirname, 'assets', 'trace.json');
|
||||
const outputFile = path.join(__dirname, 'assets', 'trace.json');
|
||||
afterEach(function() {
|
||||
fs.unlinkSync(outputFile);
|
||||
});
|
||||
@ -1867,7 +1867,7 @@ describe('Page', function() {
|
||||
}));
|
||||
it('should throw if tracing on two pages', SX(async function() {
|
||||
await page.tracing.start({path: outputFile});
|
||||
let newPage = await browser.newPage();
|
||||
const newPage = await browser.newPage();
|
||||
let error = null;
|
||||
try {
|
||||
await newPage.tracing.start({path: outputFile});
|
||||
@ -1883,12 +1883,12 @@ describe('Page', function() {
|
||||
|
||||
if (process.env.COVERAGE) {
|
||||
describe('COVERAGE', function(){
|
||||
let coverage = helper.publicAPICoverage();
|
||||
let disabled = new Set();
|
||||
const coverage = helper.publicAPICoverage();
|
||||
const disabled = new Set();
|
||||
if (!headless)
|
||||
disabled.add('page.pdf');
|
||||
|
||||
for (let method of coverage.keys()) {
|
||||
for (const method of coverage.keys()) {
|
||||
(disabled.has(method) ? xit : it)(`public api '${method}' should be called`, SX(async function(){
|
||||
expect(coverage.get(method)).toBe(true);
|
||||
}));
|
||||
@ -1903,7 +1903,7 @@ if (process.env.COVERAGE) {
|
||||
*/
|
||||
function waitForEvents(emitter, eventName, eventCount = 1) {
|
||||
let fulfill;
|
||||
let promise = new Promise(x => fulfill = x);
|
||||
const promise = new Promise(x => fulfill = x);
|
||||
emitter.on(eventName, onEvent);
|
||||
return promise;
|
||||
|
||||
@ -1925,10 +1925,10 @@ async function getPDFPages(pdfBuffer) {
|
||||
PDFJS.disableWorker = true;
|
||||
const data = new Uint8Array(pdfBuffer);
|
||||
const doc = await PDFJS.getDocument(data);
|
||||
let pages = [];
|
||||
const pages = [];
|
||||
for (let i = 0; i < doc.numPages; ++i) {
|
||||
let page = await doc.getPage(i + 1);
|
||||
let viewport = page.getViewport(1);
|
||||
const page = await doc.getPage(i + 1);
|
||||
const viewport = page.getViewport(1);
|
||||
// Viewport width and height is in PDF points, which is
|
||||
// 1/72 of an inch.
|
||||
pages.push({
|
||||
|
@ -44,7 +44,7 @@ module.exports = {
|
||||
* @return {string}
|
||||
*/
|
||||
currentPlatform: function() {
|
||||
let platform = os.platform();
|
||||
const platform = os.platform();
|
||||
if (platform === 'darwin')
|
||||
return 'mac';
|
||||
if (platform === 'linux')
|
||||
@ -61,15 +61,15 @@ module.exports = {
|
||||
*/
|
||||
canDownloadRevision: function(platform, revision) {
|
||||
console.assert(downloadURLs[platform], 'Unknown platform: ' + platform);
|
||||
let url = URL.parse(util.format(downloadURLs[platform], revision));
|
||||
let options = {
|
||||
const url = URL.parse(util.format(downloadURLs[platform], revision));
|
||||
const options = {
|
||||
method: 'HEAD',
|
||||
host: url.host,
|
||||
path: url.pathname,
|
||||
};
|
||||
let resolve;
|
||||
let promise = new Promise(x => resolve = x);
|
||||
let request = https.request(options, response => {
|
||||
const promise = new Promise(x => resolve = x);
|
||||
const request = https.request(options, response => {
|
||||
resolve(response.statusCode === 200);
|
||||
});
|
||||
request.on('error', error => {
|
||||
@ -90,8 +90,8 @@ module.exports = {
|
||||
let url = downloadURLs[platform];
|
||||
console.assert(url, `Unsupported platform: ${platform}`);
|
||||
url = util.format(url, revision);
|
||||
let zipPath = path.join(DOWNLOADS_FOLDER, `download-${platform}-${revision}.zip`);
|
||||
let folderPath = getFolderPath(platform, revision);
|
||||
const zipPath = path.join(DOWNLOADS_FOLDER, `download-${platform}-${revision}.zip`);
|
||||
const folderPath = getFolderPath(platform, revision);
|
||||
if (fs.existsSync(folderPath))
|
||||
return;
|
||||
try {
|
||||
@ -111,7 +111,7 @@ module.exports = {
|
||||
downloadedRevisions: function() {
|
||||
if (!fs.existsSync(DOWNLOADS_FOLDER))
|
||||
return [];
|
||||
let fileNames = fs.readdirSync(DOWNLOADS_FOLDER);
|
||||
const fileNames = fs.readdirSync(DOWNLOADS_FOLDER);
|
||||
return fileNames.map(fileName => parseFolderPath(fileName)).filter(revision => !!revision);
|
||||
},
|
||||
|
||||
@ -133,7 +133,7 @@ module.exports = {
|
||||
*/
|
||||
revisionInfo: function(platform, revision) {
|
||||
console.assert(downloadURLs[platform], `Unsupported platform: ${platform}`);
|
||||
let folderPath = getFolderPath(platform, revision);
|
||||
const folderPath = getFolderPath(platform, revision);
|
||||
let executablePath = '';
|
||||
if (platform === 'mac')
|
||||
executablePath = path.join(folderPath, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
|
||||
@ -166,11 +166,11 @@ function getFolderPath(platform, revision) {
|
||||
* @return {?{platform: string, revision: string}}
|
||||
*/
|
||||
function parseFolderPath(folderPath) {
|
||||
let name = path.basename(folderPath);
|
||||
let splits = name.split('-');
|
||||
const name = path.basename(folderPath);
|
||||
const splits = name.split('-');
|
||||
if (splits.length !== 2)
|
||||
return null;
|
||||
let [platform, revision] = splits;
|
||||
const [platform, revision] = splits;
|
||||
if (!downloadURLs[platform])
|
||||
return null;
|
||||
return {platform, revision};
|
||||
@ -184,20 +184,20 @@ function parseFolderPath(folderPath) {
|
||||
*/
|
||||
function downloadFile(url, destinationPath, progressCallback) {
|
||||
let fulfill, reject;
|
||||
let promise = new Promise((x, y) => { fulfill = x; reject = y; });
|
||||
let request = https.get(url, response => {
|
||||
const promise = new Promise((x, y) => { fulfill = x; reject = y; });
|
||||
const request = https.get(url, response => {
|
||||
if (response.statusCode !== 200) {
|
||||
let error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
|
||||
const error = new Error(`Download failed: server returned code ${response.statusCode}. URL: ${url}`);
|
||||
// consume response data to free up memory
|
||||
response.resume();
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
let file = fs.createWriteStream(destinationPath);
|
||||
const file = fs.createWriteStream(destinationPath);
|
||||
file.on('finish', () => fulfill());
|
||||
file.on('error', error => reject(error));
|
||||
response.pipe(file);
|
||||
let totalBytes = parseInt(response.headers['content-length'], 10);
|
||||
const totalBytes = parseInt(response.headers['content-length'], 10);
|
||||
if (progressCallback)
|
||||
response.on('data', onData.bind(null, totalBytes));
|
||||
});
|
||||
|
@ -59,8 +59,8 @@ Running command without arguments will check against omahaproxy revisions.`);
|
||||
return;
|
||||
}
|
||||
|
||||
let fromRevision = parseInt(process.argv[2], 10);
|
||||
let toRevision = parseInt(process.argv[3], 10);
|
||||
const fromRevision = parseInt(process.argv[2], 10);
|
||||
const toRevision = parseInt(process.argv[3], 10);
|
||||
checkRangeAvailability(fromRevision, toRevision);
|
||||
|
||||
/**
|
||||
@ -68,23 +68,23 @@ checkRangeAvailability(fromRevision, toRevision);
|
||||
*/
|
||||
async function checkOmahaProxyAvailability() {
|
||||
console.log('Fetching revisions from ' + OMAHA_PROXY);
|
||||
let platforms = await loadJSON(OMAHA_PROXY);
|
||||
const platforms = await loadJSON(OMAHA_PROXY);
|
||||
if (!platforms) {
|
||||
console.error('ERROR: failed to fetch chromium revisions from omahaproxy.');
|
||||
return;
|
||||
}
|
||||
let table = new Table([27, 7, 7, 7, 7]);
|
||||
const table = new Table([27, 7, 7, 7, 7]);
|
||||
table.drawRow([''].concat(Downloader.supportedPlatforms()));
|
||||
for (let platform of platforms) {
|
||||
for (const platform of platforms) {
|
||||
// Trust only to the main platforms.
|
||||
if (platform.os !== 'mac' && platform.os !== 'win' && platform.os !== 'win64' && platform.os !== 'linux')
|
||||
continue;
|
||||
let osName = platform.os === 'win' ? 'win32' : platform.os;
|
||||
for (let version of platform.versions) {
|
||||
const osName = platform.os === 'win' ? 'win32' : platform.os;
|
||||
for (const version of platform.versions) {
|
||||
if (version.channel !== 'dev' && version.channel !== 'beta' && version.channel !== 'canary' && version.channel !== 'stable')
|
||||
continue;
|
||||
let revisionName = padLeft('[' + osName + ' ' + version.channel + ']', 15);
|
||||
let revision = parseInt(version.branch_base_position, 10);
|
||||
const revisionName = padLeft('[' + osName + ' ' + version.channel + ']', 15);
|
||||
const revision = parseInt(version.branch_base_position, 10);
|
||||
await checkAndDrawRevisionAvailability(table, revisionName, revision);
|
||||
}
|
||||
}
|
||||
@ -96,9 +96,9 @@ async function checkOmahaProxyAvailability() {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async function checkRangeAvailability(fromRevision, toRevision) {
|
||||
let table = new Table([10, 7, 7, 7, 7]);
|
||||
const table = new Table([10, 7, 7, 7, 7]);
|
||||
table.drawRow([''].concat(Downloader.supportedPlatforms()));
|
||||
let inc = fromRevision < toRevision ? 1 : -1;
|
||||
const inc = fromRevision < toRevision ? 1 : -1;
|
||||
for (let revision = fromRevision; revision !== toRevision; revision += inc)
|
||||
await checkAndDrawRevisionAvailability(table, '', revision);
|
||||
}
|
||||
@ -110,15 +110,15 @@ async function checkRangeAvailability(fromRevision, toRevision) {
|
||||
* @return {!Promise}
|
||||
*/
|
||||
async function checkAndDrawRevisionAvailability(table, name, revision) {
|
||||
let promises = [];
|
||||
for (let platform of Downloader.supportedPlatforms())
|
||||
const promises = [];
|
||||
for (const platform of Downloader.supportedPlatforms())
|
||||
promises.push(Downloader.canDownloadRevision(platform, revision));
|
||||
let availability = await Promise.all(promises);
|
||||
let allAvailable = availability.every(e => !!e);
|
||||
let values = [name + ' ' + (allAvailable ? colors.green + revision + colors.reset : revision)];
|
||||
const availability = await Promise.all(promises);
|
||||
const allAvailable = availability.every(e => !!e);
|
||||
const values = [name + ' ' + (allAvailable ? colors.green + revision + colors.reset : revision)];
|
||||
for (let i = 0; i < availability.length; ++i) {
|
||||
let decoration = availability[i] ? '+' : '-';
|
||||
let color = availability[i] ? colors.green : colors.red;
|
||||
const decoration = availability[i] ? '+' : '-';
|
||||
const color = availability[i] ? colors.green : colors.red;
|
||||
values.push(color + decoration + colors.reset);
|
||||
}
|
||||
table.drawRow(values);
|
||||
@ -130,7 +130,7 @@ async function checkAndDrawRevisionAvailability(table, name, revision) {
|
||||
*/
|
||||
function loadJSON(url) {
|
||||
let resolve;
|
||||
let promise = new Promise(x => resolve = x);
|
||||
const promise = new Promise(x => resolve = x);
|
||||
https.get(url, response => {
|
||||
if (response.statusCode !== 200) {
|
||||
resolve(null);
|
||||
@ -141,7 +141,7 @@ function loadJSON(url) {
|
||||
body += chunk;
|
||||
});
|
||||
response.on('end', function(){
|
||||
let json = JSON.parse(body);
|
||||
const json = JSON.parse(body);
|
||||
resolve(json);
|
||||
});
|
||||
}).on('error', function(e){
|
||||
@ -164,8 +164,8 @@ function spaceString(size) {
|
||||
* @return {string}
|
||||
*/
|
||||
function filterOutColors(text) {
|
||||
for (let colorName in colors) {
|
||||
let color = colors[colorName];
|
||||
for (const colorName in colors) {
|
||||
const color = colors[colorName];
|
||||
text = text.replace(color, '');
|
||||
}
|
||||
return text;
|
||||
@ -177,7 +177,7 @@ function filterOutColors(text) {
|
||||
* @return {string}
|
||||
*/
|
||||
function padLeft(text, length) {
|
||||
let printableCharacters = filterOutColors(text);
|
||||
const printableCharacters = filterOutColors(text);
|
||||
return printableCharacters.length >= length ? text : spaceString(length - text.length) + text;
|
||||
}
|
||||
|
||||
@ -187,10 +187,10 @@ function padLeft(text, length) {
|
||||
* @return {string}
|
||||
*/
|
||||
function padCenter(text, length) {
|
||||
let printableCharacters = filterOutColors(text);
|
||||
const printableCharacters = filterOutColors(text);
|
||||
if (printableCharacters.length >= length)
|
||||
return text;
|
||||
let left = Math.floor((length - printableCharacters.length) / 2);
|
||||
let right = Math.ceil((length - printableCharacters.length) / 2);
|
||||
const left = Math.floor((length - printableCharacters.length) / 2);
|
||||
const right = Math.ceil((length - printableCharacters.length) / 2);
|
||||
return spaceString(left) + text + spaceString(right);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class Documentation {
|
||||
constructor(classesArray) {
|
||||
this.classesArray = classesArray;
|
||||
this.classes = new Map();
|
||||
for (let cls of classesArray)
|
||||
for (const cls of classesArray)
|
||||
this.classes.set(cls.name, cls);
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ Documentation.Class = class {
|
||||
this.properties = new Map();
|
||||
this.methods = new Map();
|
||||
this.events = new Map();
|
||||
for (let member of membersArray) {
|
||||
for (const member of membersArray) {
|
||||
this.members.set(member.name, member);
|
||||
if (member.type === 'method')
|
||||
this.methods.set(member.name, member);
|
||||
@ -65,7 +65,7 @@ Documentation.Member = class {
|
||||
this.args = new Map();
|
||||
this.hasReturn = hasReturn;
|
||||
this.async = async;
|
||||
for (let arg of argsArray)
|
||||
for (const arg of argsArray)
|
||||
this.args.set(arg.name, arg);
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,13 @@ class ESTreeWalker {
|
||||
return;
|
||||
}
|
||||
|
||||
let walkOrder = ESTreeWalker._walkOrder[node.type];
|
||||
const walkOrder = ESTreeWalker._walkOrder[node.type];
|
||||
if (!walkOrder)
|
||||
return;
|
||||
|
||||
if (node.type === 'TemplateLiteral') {
|
||||
let templateLiteral = /** @type {!ESTree.TemplateLiteralNode} */ (node);
|
||||
let expressionsLength = templateLiteral.expressions.length;
|
||||
const templateLiteral = /** @type {!ESTree.TemplateLiteralNode} */ (node);
|
||||
const expressionsLength = templateLiteral.expressions.length;
|
||||
for (let i = 0; i < expressionsLength; ++i) {
|
||||
this._innerWalk(templateLiteral.quasis[i], templateLiteral);
|
||||
this._innerWalk(templateLiteral.expressions[i], templateLiteral);
|
||||
@ -50,7 +50,7 @@ class ESTreeWalker {
|
||||
this._innerWalk(templateLiteral.quasis[expressionsLength], templateLiteral);
|
||||
} else {
|
||||
for (let i = 0; i < walkOrder.length; ++i) {
|
||||
let entity = node[walkOrder[i]];
|
||||
const entity = node[walkOrder[i]];
|
||||
if (Array.isArray(entity))
|
||||
this._walkArray(entity, node);
|
||||
else
|
||||
|
@ -27,8 +27,8 @@ class JSOutline {
|
||||
this._currentClassMembers = [];
|
||||
|
||||
this._text = text;
|
||||
let ast = esprima.parseScript(this._text, {loc: true, range: true});
|
||||
let walker = new ESTreeWalker(node => {
|
||||
const ast = esprima.parseScript(this._text, {loc: true, range: true});
|
||||
const walker = new ESTreeWalker(node => {
|
||||
if (node.type === 'ClassDeclaration')
|
||||
this._onClassDeclaration(node);
|
||||
else if (node.type === 'MethodDefinition')
|
||||
@ -49,9 +49,9 @@ class JSOutline {
|
||||
_onMethodDefinition(node) {
|
||||
console.assert(this._currentClassName !== null);
|
||||
console.assert(node.value.type === 'FunctionExpression');
|
||||
let methodName = this._extractText(node.key);
|
||||
const methodName = this._extractText(node.key);
|
||||
if (node.kind === 'get') {
|
||||
let property = Documentation.Member.createProperty(methodName);
|
||||
const property = Documentation.Member.createProperty(methodName);
|
||||
this._currentClassMembers.push(property);
|
||||
return;
|
||||
}
|
||||
@ -60,7 +60,7 @@ class JSOutline {
|
||||
// Extract properties from constructor.
|
||||
if (node.kind === 'constructor') {
|
||||
// Extract properties from constructor.
|
||||
let walker = new ESTreeWalker(node => {
|
||||
const walker = new ESTreeWalker(node => {
|
||||
if (node.type !== 'AssignmentExpression')
|
||||
return;
|
||||
node = node.left;
|
||||
@ -71,7 +71,7 @@ class JSOutline {
|
||||
});
|
||||
walker.walk(node);
|
||||
} else if (!hasReturn) {
|
||||
let walker = new ESTreeWalker(node => {
|
||||
const walker = new ESTreeWalker(node => {
|
||||
if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression')
|
||||
return ESTreeWalker.SkipSubtree;
|
||||
if (node.type === 'ReturnStatement')
|
||||
@ -80,7 +80,7 @@ class JSOutline {
|
||||
walker.walk(node.value.body);
|
||||
}
|
||||
const args = [];
|
||||
for (let param of node.value.params) {
|
||||
for (const param of node.value.params) {
|
||||
if (param.type === 'AssignmentPattern')
|
||||
args.push(new Documentation.Argument(param.left.name));
|
||||
else if (param.type === 'RestElement')
|
||||
@ -92,7 +92,7 @@ class JSOutline {
|
||||
else
|
||||
this.errors.push(`JS Parsing issue: unsupported syntax to define parameter in ${this._currentClassName}.${methodName}(): ${this._extractText(param)}`);
|
||||
}
|
||||
let method = Documentation.Member.createMethod(methodName, args, hasReturn, node.value.async);
|
||||
const method = Documentation.Member.createMethod(methodName, args, hasReturn, node.value.async);
|
||||
this._currentClassMembers.push(method);
|
||||
return ESTreeWalker.SkipSubtree;
|
||||
}
|
||||
@ -108,7 +108,7 @@ class JSOutline {
|
||||
events = [];
|
||||
this._eventsByClassName.set(className, events);
|
||||
}
|
||||
for (let property of node.right.properties) {
|
||||
for (const property of node.right.properties) {
|
||||
if (property.type !== 'Property' || property.key.type !== 'Identifier' || property.value.type !== 'Literal')
|
||||
continue;
|
||||
events.push(Documentation.Member.createEvent(property.value.value));
|
||||
@ -118,7 +118,7 @@ class JSOutline {
|
||||
_flushClassIfNeeded() {
|
||||
if (this._currentClassName === null)
|
||||
return;
|
||||
let jsClass = new Documentation.Class(this._currentClassName, this._currentClassMembers);
|
||||
const jsClass = new Documentation.Class(this._currentClassName, this._currentClassMembers);
|
||||
this.classes.push(jsClass);
|
||||
this._currentClassName = null;
|
||||
this._currentClassMembers = [];
|
||||
@ -126,8 +126,8 @@ class JSOutline {
|
||||
|
||||
_recreateClassesWithEvents() {
|
||||
this.classes = this.classes.map(cls => {
|
||||
let events = this._eventsByClassName.get(cls.name) || [];
|
||||
let members = cls.membersArray.concat(events);
|
||||
const events = this._eventsByClassName.get(cls.name) || [];
|
||||
const members = cls.membersArray.concat(events);
|
||||
return new Documentation.Class(cls.name, members);
|
||||
});
|
||||
}
|
||||
@ -135,7 +135,7 @@ class JSOutline {
|
||||
_extractText(node) {
|
||||
if (!node)
|
||||
return null;
|
||||
let text = this._text.substring(node.range[0], node.range[1]).trim();
|
||||
const text = this._text.substring(node.range[0], node.range[1]).trim();
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@ -145,10 +145,10 @@ class JSOutline {
|
||||
* @return {!Promise<{documentation: !Documentation, errors: !Array<string>}>}
|
||||
*/
|
||||
module.exports = async function(sources) {
|
||||
let classes = [];
|
||||
let errors = [];
|
||||
for (let source of sources) {
|
||||
let outline = new JSOutline(source.text());
|
||||
const classes = [];
|
||||
const errors = [];
|
||||
for (const source of sources) {
|
||||
const outline = new JSOutline(source.text());
|
||||
classes.push(...outline.classes);
|
||||
errors.push(...outline.errors);
|
||||
}
|
||||
|
@ -33,11 +33,11 @@ class MDOutline {
|
||||
// Extract headings.
|
||||
await page.setContent(html);
|
||||
const {classes, errors} = await page.evaluate(() => {
|
||||
let classes = [];
|
||||
const classes = [];
|
||||
let currentClass = {};
|
||||
let member = {};
|
||||
let errors = [];
|
||||
for (let element of document.body.querySelectorAll('h3, h4, h4 + ul > li')) {
|
||||
const errors = [];
|
||||
for (const element of document.body.querySelectorAll('h3, h4, h4 + ul > li')) {
|
||||
if (element.matches('h3')) {
|
||||
currentClass = {
|
||||
name: element.textContent,
|
||||
@ -82,22 +82,22 @@ class MDOutline {
|
||||
let currentClassName = null;
|
||||
let currentClassMembers = [];
|
||||
for (const cls of classes) {
|
||||
let match = cls.name.match(classHeading);
|
||||
const match = cls.name.match(classHeading);
|
||||
if (!match)
|
||||
continue;
|
||||
currentClassName = match[1];
|
||||
for (let member of cls.members) {
|
||||
for (const member of cls.members) {
|
||||
if (constructorRegex.test(member.name)) {
|
||||
let match = member.name.match(constructorRegex);
|
||||
const match = member.name.match(constructorRegex);
|
||||
handleMethod.call(this, member, match[1], 'constructor', match[2]);
|
||||
} else if (methodRegex.test(member.name)) {
|
||||
let match = member.name.match(methodRegex);
|
||||
const match = member.name.match(methodRegex);
|
||||
handleMethod.call(this, member, match[1], match[2], match[3]);
|
||||
} else if (propertyRegex.test(member.name)) {
|
||||
let match = member.name.match(propertyRegex);
|
||||
const match = member.name.match(propertyRegex);
|
||||
handleProperty.call(this, member, match[1], match[2]);
|
||||
} else if (eventRegex.test(member.name)) {
|
||||
let match = member.name.match(eventRegex);
|
||||
const match = member.name.match(eventRegex);
|
||||
handleEvent.call(this, member, match[1]);
|
||||
}
|
||||
}
|
||||
@ -112,8 +112,8 @@ class MDOutline {
|
||||
parameters = parameters.trim().replace(/[\[\]]/g, '');
|
||||
if (parameters !== member.args.join(', '))
|
||||
this.errors.push(`Heading arguments for "${member.name}" do not match described ones, i.e. "${parameters}" != "${member.args.join(', ')}"`);
|
||||
let args = member.args.map(arg => new Documentation.Argument(arg));
|
||||
let method = Documentation.Member.createMethod(methodName, args, member.hasReturn, false);
|
||||
const args = member.args.map(arg => new Documentation.Argument(arg));
|
||||
const method = Documentation.Member.createMethod(methodName, args, member.hasReturn, false);
|
||||
currentClassMembers.push(method);
|
||||
}
|
||||
|
||||
@ -149,10 +149,10 @@ class MDOutline {
|
||||
* @return {!Promise<{documentation: !Documentation, errors: !Array<string>}>}
|
||||
*/
|
||||
module.exports = async function(page, sources) {
|
||||
let classes = [];
|
||||
let errors = [];
|
||||
for (let source of sources) {
|
||||
let outline = await MDOutline.create(page, source.text());
|
||||
const classes = [];
|
||||
const errors = [];
|
||||
for (const source of sources) {
|
||||
const outline = await MDOutline.create(page, source.text());
|
||||
classes.push(...outline.classes);
|
||||
errors.push(...outline.errors);
|
||||
}
|
||||
|
@ -58,21 +58,21 @@ const EXCLUDE_METHODS = new Set([
|
||||
* @return {!Promise<!Array<!Message>>}
|
||||
*/
|
||||
module.exports = async function lint(page, mdSources, jsSources) {
|
||||
let mdResult = await mdBuilder(page, mdSources);
|
||||
let jsResult = await jsBuilder(jsSources);
|
||||
let jsDocumentation = filterJSDocumentation(jsResult.documentation);
|
||||
let mdDocumentation = mdResult.documentation;
|
||||
const mdResult = await mdBuilder(page, mdSources);
|
||||
const jsResult = await jsBuilder(jsSources);
|
||||
const jsDocumentation = filterJSDocumentation(jsResult.documentation);
|
||||
const mdDocumentation = mdResult.documentation;
|
||||
|
||||
let jsErrors = jsResult.errors;
|
||||
const jsErrors = jsResult.errors;
|
||||
jsErrors.push(...checkDuplicates(jsDocumentation));
|
||||
|
||||
let mdErrors = mdResult.errors;
|
||||
const mdErrors = mdResult.errors;
|
||||
mdErrors.push(...compareDocumentations(mdDocumentation, jsDocumentation));
|
||||
mdErrors.push(...checkDuplicates(mdDocumentation));
|
||||
mdErrors.push(...checkSorting(mdDocumentation));
|
||||
|
||||
// Push all errors with proper prefixes
|
||||
let errors = jsErrors.map(error => '[JavaScript] ' + error);
|
||||
const errors = jsErrors.map(error => '[JavaScript] ' + error);
|
||||
errors.push(...mdErrors.map(error => '[MarkDown] ' + error));
|
||||
return errors.map(error => Message.error(error));
|
||||
};
|
||||
@ -83,8 +83,8 @@ module.exports = async function lint(page, mdSources, jsSources) {
|
||||
*/
|
||||
function checkSorting(doc) {
|
||||
const errors = [];
|
||||
for (let cls of doc.classesArray) {
|
||||
let members = cls.membersArray;
|
||||
for (const cls of doc.classesArray) {
|
||||
const members = cls.membersArray;
|
||||
|
||||
// Events should go first.
|
||||
let eventIndex = 0;
|
||||
@ -94,14 +94,14 @@ function checkSorting(doc) {
|
||||
errors.push(`Events should go first. Event '${members[eventIndex].name}' in class ${cls.name} breaks order`);
|
||||
|
||||
// Constructor should be right after events and before all other members.
|
||||
let constructorIndex = members.findIndex(member => member.type === 'method' && member.name === 'constructor');
|
||||
const constructorIndex = members.findIndex(member => member.type === 'method' && member.name === 'constructor');
|
||||
if (constructorIndex > 0 && members[constructorIndex - 1].type !== 'event')
|
||||
errors.push(`Constructor of ${cls.name} should go before other methods`);
|
||||
|
||||
// Events should be sorted alphabetically.
|
||||
for (let i = 0; i < members.length - 1; ++i) {
|
||||
let member1 = cls.membersArray[i];
|
||||
let member2 = cls.membersArray[i + 1];
|
||||
const member1 = cls.membersArray[i];
|
||||
const member2 = cls.membersArray[i + 1];
|
||||
if (member1.type !== 'event' || member2.type !== 'event')
|
||||
continue;
|
||||
if (member1.name > member2.name)
|
||||
@ -110,8 +110,8 @@ function checkSorting(doc) {
|
||||
|
||||
// All other members should be sorted alphabetically.
|
||||
for (let i = 0; i < members.length - 1; ++i) {
|
||||
let member1 = cls.membersArray[i];
|
||||
let member2 = cls.membersArray[i + 1];
|
||||
const member1 = cls.membersArray[i];
|
||||
const member2 = cls.membersArray[i + 1];
|
||||
if (member1.type === 'event' || member2.type === 'event')
|
||||
continue;
|
||||
if (member1.type === 'method' && member1.name === 'constructor')
|
||||
@ -136,11 +136,11 @@ function checkSorting(doc) {
|
||||
*/
|
||||
function filterJSDocumentation(jsDocumentation) {
|
||||
// Filter classes and methods.
|
||||
let classes = [];
|
||||
for (let cls of jsDocumentation.classesArray) {
|
||||
const classes = [];
|
||||
for (const cls of jsDocumentation.classesArray) {
|
||||
if (EXCLUDE_CLASSES.has(cls.name))
|
||||
continue;
|
||||
let members = cls.membersArray.filter(member => {
|
||||
const members = cls.membersArray.filter(member => {
|
||||
if (member.name.startsWith('_'))
|
||||
return false;
|
||||
return !EXCLUDE_METHODS.has(`${cls.name}.${member.name}`);
|
||||
@ -156,19 +156,19 @@ function filterJSDocumentation(jsDocumentation) {
|
||||
*/
|
||||
function checkDuplicates(doc) {
|
||||
const errors = [];
|
||||
let classes = new Set();
|
||||
const classes = new Set();
|
||||
// Report duplicates.
|
||||
for (let cls of doc.classesArray) {
|
||||
for (const cls of doc.classesArray) {
|
||||
if (classes.has(cls.name))
|
||||
errors.push(`Duplicate declaration of class ${cls.name}`);
|
||||
classes.add(cls.name);
|
||||
let members = new Set();
|
||||
for (let member of cls.membersArray) {
|
||||
const members = new Set();
|
||||
for (const member of cls.membersArray) {
|
||||
if (members.has(member.name))
|
||||
errors.push(`Duplicate declaration of method ${cls.name}.${member.name}()`);
|
||||
members.add(member.name);
|
||||
let args = new Set();
|
||||
for (let arg of member.argsArray) {
|
||||
const args = new Set();
|
||||
for (const arg of member.argsArray) {
|
||||
if (args.has(arg.name))
|
||||
errors.push(`Duplicate declaration of argument ${cls.name}.${member.name} "${arg.name}"`);
|
||||
args.add(arg.name);
|
||||
@ -188,24 +188,24 @@ function compareDocumentations(actual, expected) {
|
||||
|
||||
const actualClasses = Array.from(actual.classes.keys()).sort();
|
||||
const expectedClasses = Array.from(expected.classes.keys()).sort();
|
||||
let classesDiff = diff(actualClasses, expectedClasses);
|
||||
for (let className of classesDiff.extra)
|
||||
const classesDiff = diff(actualClasses, expectedClasses);
|
||||
for (const className of classesDiff.extra)
|
||||
errors.push(`Non-existing class found: ${className}`);
|
||||
for (let className of classesDiff.missing)
|
||||
for (const className of classesDiff.missing)
|
||||
errors.push(`Class not found: ${className}`);
|
||||
|
||||
for (let className of classesDiff.equal) {
|
||||
for (const className of classesDiff.equal) {
|
||||
const actualClass = actual.classes.get(className);
|
||||
const expectedClass = expected.classes.get(className);
|
||||
const actualMethods = Array.from(actualClass.methods.keys()).sort();
|
||||
const expectedMethods = Array.from(expectedClass.methods.keys()).sort();
|
||||
const methodDiff = diff(actualMethods, expectedMethods);
|
||||
for (let methodName of methodDiff.extra)
|
||||
for (const methodName of methodDiff.extra)
|
||||
errors.push(`Non-existing method found: ${className}.${methodName}()`);
|
||||
for (let methodName of methodDiff.missing)
|
||||
for (const methodName of methodDiff.missing)
|
||||
errors.push(`Method not found: ${className}.${methodName}()`);
|
||||
|
||||
for (let methodName of methodDiff.equal) {
|
||||
for (const methodName of methodDiff.equal) {
|
||||
const actualMethod = actualClass.methods.get(methodName);
|
||||
const expectedMethod = expectedClass.methods.get(methodName);
|
||||
if (actualMethod.hasReturn !== expectedMethod.hasReturn) {
|
||||
@ -220,10 +220,10 @@ function compareDocumentations(actual, expected) {
|
||||
const expectedArgs = Array.from(expectedMethod.args.keys());
|
||||
const argDiff = diff(actualArgs, expectedArgs);
|
||||
if (argDiff.extra.length || argDiff.missing.length) {
|
||||
let text = [`Method ${className}.${methodName}() fails to describe its parameters:`];
|
||||
for (let arg of argDiff.missing)
|
||||
const text = [`Method ${className}.${methodName}() fails to describe its parameters:`];
|
||||
for (const arg of argDiff.missing)
|
||||
text.push(`- Argument not found: ${arg}`);
|
||||
for (let arg of argDiff.extra)
|
||||
for (const arg of argDiff.extra)
|
||||
text.push(`- Non-existing argument found: ${arg}`);
|
||||
errors.push(text.join('\n'));
|
||||
}
|
||||
@ -231,17 +231,17 @@ function compareDocumentations(actual, expected) {
|
||||
const actualProperties = Array.from(actualClass.properties.keys()).sort();
|
||||
const expectedProperties = Array.from(expectedClass.properties.keys()).sort();
|
||||
const propertyDiff = diff(actualProperties, expectedProperties);
|
||||
for (let propertyName of propertyDiff.extra)
|
||||
for (const propertyName of propertyDiff.extra)
|
||||
errors.push(`Non-existing property found: ${className}.${propertyName}`);
|
||||
for (let propertyName of propertyDiff.missing)
|
||||
for (const propertyName of propertyDiff.missing)
|
||||
errors.push(`Property not found: ${className}.${propertyName}`);
|
||||
|
||||
const actualEvents = Array.from(actualClass.events.keys()).sort();
|
||||
const expectedEvents = Array.from(expectedClass.events.keys()).sort();
|
||||
const eventsDiff = diff(actualEvents, expectedEvents);
|
||||
for (let eventName of eventsDiff.extra)
|
||||
for (const eventName of eventsDiff.extra)
|
||||
errors.push(`Non-existing event found in class ${className}: '${eventName}'`);
|
||||
for (let eventName of eventsDiff.missing)
|
||||
for (const eventName of eventsDiff.missing)
|
||||
errors.push(`Event not found in class ${className}: '${eventName}'`);
|
||||
}
|
||||
return errors;
|
||||
@ -261,8 +261,8 @@ function diff(actual, expected) {
|
||||
return {extra: [], missing: expected.slice(), equal: []};
|
||||
if (M === 0)
|
||||
return {extra: actual.slice(), missing: [], equal: []};
|
||||
let d = new Array(N);
|
||||
let bt = new Array(N);
|
||||
const d = new Array(N);
|
||||
const bt = new Array(N);
|
||||
for (let i = 0; i < N; ++i) {
|
||||
d[i] = new Array(M);
|
||||
bt[i] = new Array(M);
|
||||
@ -276,7 +276,7 @@ function diff(actual, expected) {
|
||||
d[i][j] = left;
|
||||
bt[i][j] = 'missing';
|
||||
}
|
||||
let diag = val(i - 1, j - 1);
|
||||
const diag = val(i - 1, j - 1);
|
||||
if (actual[i] === expected[j] && d[i][j] < diag + 1) {
|
||||
d[i][j] = diag + 1;
|
||||
bt[i][j] = 'eq';
|
||||
@ -286,9 +286,9 @@ function diff(actual, expected) {
|
||||
// Backtrack results.
|
||||
let i = N - 1;
|
||||
let j = M - 1;
|
||||
let missing = [];
|
||||
let extra = [];
|
||||
let equal = [];
|
||||
const missing = [];
|
||||
const extra = [];
|
||||
const equal = [];
|
||||
while (i >= 0 && j >= 0) {
|
||||
switch (bt[i][j]) {
|
||||
case 'extra':
|
||||
|
@ -19,9 +19,9 @@ const Message = require('../Message');
|
||||
const PUPPETEER_VERSION = require('../../../package.json').version;
|
||||
|
||||
module.exports = function(sources) {
|
||||
let messages = [];
|
||||
const messages = [];
|
||||
let commands = [];
|
||||
for (let source of sources) {
|
||||
for (const source of sources) {
|
||||
const text = source.text();
|
||||
const commandStartRegex = /<!--\s*gen:([a-z]+)(?:\s*\(\s*([^)]*)\s*\))?\s*-->/ig;
|
||||
const commandEndRegex = /<!--\s*gen:stop\s*-->/ig;
|
||||
@ -45,10 +45,10 @@ module.exports = function(sources) {
|
||||
|
||||
commands = validateCommands(commands, messages);
|
||||
|
||||
let changedSources = new Set();
|
||||
const changedSources = new Set();
|
||||
// Iterate commands in reverse order so that edits don't conflict.
|
||||
commands.sort((a, b) => b.from - a.from);
|
||||
for (let command of commands) {
|
||||
for (const command of commands) {
|
||||
let newText = command.source.text();
|
||||
if (command.name === 'version')
|
||||
newText = replaceInText(newText, command.from, command.to, PUPPETEER_VERSION);
|
||||
@ -67,7 +67,7 @@ module.exports = function(sources) {
|
||||
*/
|
||||
function validateCommands(commands, outMessages) {
|
||||
// Filter sane commands
|
||||
let goodCommands = commands.filter(command => {
|
||||
const goodCommands = commands.filter(command => {
|
||||
if (command.name === 'version')
|
||||
return check(command, !command.arg, `"gen:version" should not have argument`);
|
||||
check(command, false, `Unknown command: "gen:${command.name}"`);
|
||||
|
@ -21,8 +21,8 @@ const VERSION = require('../../../package.json').version;
|
||||
|
||||
describe('preprocessor', function() {
|
||||
it('should throw for unknown command', function() {
|
||||
let source = factory.createForTest('doc.md', getCommand('unknownCommand()'));
|
||||
let messages = preprocessor([source]);
|
||||
const source = factory.createForTest('doc.md', getCommand('unknownCommand()'));
|
||||
const messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
@ -30,22 +30,22 @@ describe('preprocessor', function() {
|
||||
});
|
||||
describe('gen:version', function() {
|
||||
it('should work', function() {
|
||||
let source = factory.createForTest('doc.md', `Puppeteer v${getCommand('version')}`);
|
||||
let messages = preprocessor([source]);
|
||||
const source = factory.createForTest('doc.md', `Puppeteer v${getCommand('version')}`);
|
||||
const messages = preprocessor([source]);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('warning');
|
||||
expect(messages[0].text).toContain('doc.md');
|
||||
expect(source.text()).toBe(`Puppeteer v${getCommand('version', VERSION)}`);
|
||||
});
|
||||
it('should tolerate different writing', function() {
|
||||
let source = factory.createForTest('doc.md', `Puppeteer v<!-- gEn:version ( ) -->WHAT
|
||||
const source = factory.createForTest('doc.md', `Puppeteer v<!-- gEn:version ( ) -->WHAT
|
||||
<!-- GEN:stop -->`);
|
||||
preprocessor([source]);
|
||||
expect(source.text()).toBe(`Puppeteer v<!-- gEn:version ( ) -->${VERSION}<!-- GEN:stop -->`);
|
||||
});
|
||||
it('should not tolerate missing gen:stop', function() {
|
||||
let source = factory.createForTest('doc.md', `<!--GEN:version-->`);
|
||||
let messages = preprocessor([source]);
|
||||
const source = factory.createForTest('doc.md', `<!--GEN:version-->`);
|
||||
const messages = preprocessor([source]);
|
||||
expect(source.hasUpdatedText()).toBe(false);
|
||||
expect(messages.length).toBe(1);
|
||||
expect(messages[0].type).toBe('error');
|
||||
|
@ -23,7 +23,7 @@ const Message = require('./Message');
|
||||
*/
|
||||
module.exports = function(sources) {
|
||||
const warnings = [];
|
||||
for (let source of sources) {
|
||||
for (const source of sources) {
|
||||
const newText = markdownToc.insert(source.text());
|
||||
if (source.setText(newText))
|
||||
warnings.push('Regenerated table-of-contexts: ' + source.projectPath());
|
||||
|
@ -52,7 +52,7 @@ Fetch Chrome DevTools front-end emulation devices from given URL, convert them t
|
||||
devices and save to the <outputPath>.
|
||||
`;
|
||||
|
||||
let argv = require('minimist')(process.argv.slice(2), {
|
||||
const argv = require('minimist')(process.argv.slice(2), {
|
||||
alias: { u: 'url', h: 'help' },
|
||||
});
|
||||
|
||||
@ -61,8 +61,8 @@ if (argv.help) {
|
||||
return;
|
||||
}
|
||||
|
||||
let url = argv.url || DEVICES_URL;
|
||||
let outputPath = argv._[0];
|
||||
const url = argv.url || DEVICES_URL;
|
||||
const outputPath = argv._[0];
|
||||
if (!outputPath) {
|
||||
console.log('ERROR: output file name is missing. Use --help for help.');
|
||||
return;
|
||||
@ -72,7 +72,7 @@ main(url);
|
||||
|
||||
async function main(url) {
|
||||
console.log('GET ' + url);
|
||||
let text = await httpGET(url);
|
||||
const text = await httpGET(url);
|
||||
let json = null;
|
||||
try {
|
||||
json = JSON.parse(text);
|
||||
@ -80,11 +80,11 @@ async function main(url) {
|
||||
console.error(`FAILED: error parsing response - ${e.message}`);
|
||||
return;
|
||||
}
|
||||
let devicePayloads = json.extensions.filter(extension => extension.type === 'emulated-device').map(extension => extension.device);
|
||||
const devicePayloads = json.extensions.filter(extension => extension.type === 'emulated-device').map(extension => extension.device);
|
||||
let devices = [];
|
||||
for (let payload of devicePayloads) {
|
||||
let device = createDevice(payload, false);
|
||||
let landscape = createDevice(payload, true);
|
||||
for (const payload of devicePayloads) {
|
||||
const device = createDevice(payload, false);
|
||||
const landscape = createDevice(payload, true);
|
||||
devices.push(device);
|
||||
if (landscape.viewport.width !== device.viewport.width || landscape.viewport.height !== device.viewport.height)
|
||||
devices.push(landscape);
|
||||
@ -92,10 +92,10 @@ async function main(url) {
|
||||
devices = devices.filter(device => device.viewport.isMobile);
|
||||
devices.sort((a, b) => a.name.localeCompare(b.name));
|
||||
// Use single-quotes instead of double-quotes to conform with codestyle.
|
||||
let serialized = JSON.stringify(devices, null, 2)
|
||||
const serialized = JSON.stringify(devices, null, 2)
|
||||
.replace(/'/g, `\\'`)
|
||||
.replace(/"/g, `'`);
|
||||
let result = util.format(template, serialized);
|
||||
const result = util.format(template, serialized);
|
||||
fs.writeFileSync(outputPath, result, 'utf8');
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user