fix(lint): webkit linting
This commit is contained in:
parent
48e9719d8a
commit
6abc91b0db
|
|
@ -17,13 +17,12 @@
|
||||||
|
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { Connection, ConnectionEvents } from './Connection';
|
import { Connection } from './Connection';
|
||||||
import { Events } from '../Events';
|
import { Events } from '../Events';
|
||||||
import { RegisteredListener, assert, helper } from '../helper';
|
import { RegisteredListener, assert, helper } from '../helper';
|
||||||
import { Page, Viewport } from './Page';
|
import { Page, Viewport } from './Page';
|
||||||
import { Target } from './Target';
|
import { Target } from './Target';
|
||||||
import { TaskQueue } from './TaskQueue';
|
import { TaskQueue } from './TaskQueue';
|
||||||
import { Protocol } from './protocol';
|
|
||||||
|
|
||||||
export class Browser extends EventEmitter {
|
export class Browser extends EventEmitter {
|
||||||
_defaultViewport: Viewport;
|
_defaultViewport: Viewport;
|
||||||
|
|
@ -101,7 +100,7 @@ export class Browser extends EventEmitter {
|
||||||
return this._createPageInContext(this._defaultContext._id);
|
return this._createPageInContext(this._defaultContext._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _createPageInContext(browserContextId?: string ): Promise<Page> {
|
async _createPageInContext(browserContextId?: string): Promise<Page> {
|
||||||
const {targetId} = await this._connection.send('Browser.createPage', {browserContextId});
|
const {targetId} = await this._connection.send('Browser.createPage', {browserContextId});
|
||||||
const target = this._targets.get(targetId);
|
const target = this._targets.get(targetId);
|
||||||
return await target.page();
|
return await target.page();
|
||||||
|
|
@ -146,11 +145,11 @@ export class Browser extends EventEmitter {
|
||||||
async _onTargetCreated({targetInfo}) {
|
async _onTargetCreated({targetInfo}) {
|
||||||
let context = null;
|
let context = null;
|
||||||
if (targetInfo.browserContextId) {
|
if (targetInfo.browserContextId) {
|
||||||
context = this._contexts.get(targetInfo.browserContextId);
|
|
||||||
// FIXME: we don't know about the default context id, so assume that all targets from
|
// FIXME: we don't know about the default context id, so assume that all targets from
|
||||||
// unknown contexts are created in the 'default' context which can in practice be represented
|
// unknown contexts are created in the 'default' context which can in practice be represented
|
||||||
// by multiple actual contexts in WebKit. Solving this properly will require adding context
|
// by multiple actual contexts in WebKit. Solving this properly will require adding context
|
||||||
// lifecycle events.
|
// lifecycle events.
|
||||||
|
context = this._contexts.get(targetInfo.browserContextId);
|
||||||
// if (!context)
|
// if (!context)
|
||||||
// throw new Error(`Target ${targetId} created in unknown browser context ${browserContextId}.`);
|
// throw new Error(`Target ${targetId} created in unknown browser context ${browserContextId}.`);
|
||||||
}
|
}
|
||||||
|
|
@ -177,8 +176,7 @@ export class Browser extends EventEmitter {
|
||||||
target.browserContext().emit(Events.BrowserContext.TargetDestroyed, target);
|
target.browserContext().emit(Events.BrowserContext.TargetDestroyed, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onProvisionalTargetCommitted({oldTargetId, newTargetId})
|
async _onProvisionalTargetCommitted({oldTargetId, newTargetId}) {
|
||||||
{
|
|
||||||
const oldTarget = this._targets.get(oldTargetId);
|
const oldTarget = this._targets.get(oldTargetId);
|
||||||
if (!oldTarget._pagePromise)
|
if (!oldTarget._pagePromise)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ export class Connection extends EventEmitter {
|
||||||
else
|
else
|
||||||
callback.resolve(object.result);
|
callback.resolve(object.result);
|
||||||
} else {
|
} else {
|
||||||
assert(this._closed, "Received response for unknown callback: " + object.id);
|
assert(this._closed, 'Received response for unknown callback: ' + object.id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.emit(object.method, object.params);
|
this.emit(object.method, object.params);
|
||||||
|
|
@ -114,16 +114,16 @@ export class Connection extends EventEmitter {
|
||||||
} else if (object.method === 'Target.dispatchMessageFromTarget') {
|
} else if (object.method === 'Target.dispatchMessageFromTarget') {
|
||||||
const session = this._sessions.get(object.params.targetId);
|
const session = this._sessions.get(object.params.targetId);
|
||||||
if (!session)
|
if (!session)
|
||||||
throw new Error("Unknown target: " + object.params.targetId);
|
throw new Error('Unknown target: ' + object.params.targetId);
|
||||||
session._dispatchMessageFromTarget(object.params.message);
|
session._dispatchMessageFromTarget(object.params.message);
|
||||||
} else if (object.method === 'Target.didCommitProvisionalTarget') {
|
} else if (object.method === 'Target.didCommitProvisionalTarget') {
|
||||||
const {oldTargetId, newTargetId} = object.params;
|
const {oldTargetId, newTargetId} = object.params;
|
||||||
const newSession = this._sessions.get(newTargetId);
|
const newSession = this._sessions.get(newTargetId);
|
||||||
if (!newSession)
|
if (!newSession)
|
||||||
throw new Error("Unknown new target: " + newTargetId);
|
throw new Error('Unknown new target: ' + newTargetId);
|
||||||
const oldSession = this._sessions.get(oldTargetId);
|
const oldSession = this._sessions.get(oldTargetId);
|
||||||
if (!oldSession)
|
if (!oldSession)
|
||||||
throw new Error("Unknown old target: " + oldTargetId);
|
throw new Error('Unknown old target: ' + oldTargetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,28 +188,28 @@ export class TargetSession extends EventEmitter {
|
||||||
method,
|
method,
|
||||||
params
|
params
|
||||||
};
|
};
|
||||||
debugWrappedMessage("SEND ► " + JSON.stringify(messageObj, null, 2));
|
debugWrappedMessage('SEND ► ' + JSON.stringify(messageObj, null, 2));
|
||||||
this._out.push(messageObj);
|
this._out.push(messageObj);
|
||||||
// Serialize message before adding callback in case JSON throws.
|
// Serialize message before adding callback in case JSON throws.
|
||||||
const message = JSON.stringify(messageObj);
|
const message = JSON.stringify(messageObj);
|
||||||
const result = new Promise<Protocol.CommandReturnValues[T]>((resolve, reject) => {
|
const result = new Promise<Protocol.CommandReturnValues[T]>((resolve, reject) => {
|
||||||
this._callbacks.set(innerId, {resolve, reject, error: new Error(), method});
|
this._callbacks.set(innerId, {resolve, reject, error: new Error(), method});
|
||||||
});
|
});
|
||||||
this._connection.send("Target.sendMessageToTarget", {
|
this._connection.send('Target.sendMessageToTarget', {
|
||||||
message: message, targetId: this._sessionId
|
message: message, targetId: this._sessionId
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
// There is a possible race of the connection closure. We may have received
|
// There is a possible race of the connection closure. We may have received
|
||||||
// targetDestroyed notification before response for the command, in that
|
// targetDestroyed notification before response for the command, in that
|
||||||
// case it's safe to swallow the exception.g
|
// case it's safe to swallow the exception.g
|
||||||
const callback = this._callbacks.get(innerId);
|
const callback = this._callbacks.get(innerId);
|
||||||
assert(!callback, "Callback was not rejected when target was destroyed.");
|
assert(!callback, 'Callback was not rejected when target was destroyed.');
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dispatchMessageFromTarget(message: string) {
|
_dispatchMessageFromTarget(message: string) {
|
||||||
const object = JSON.parse(message);
|
const object = JSON.parse(message);
|
||||||
debugWrappedMessage("◀ RECV " + JSON.stringify(object, null, 2));
|
debugWrappedMessage('◀ RECV ' + JSON.stringify(object, null, 2));
|
||||||
this._in.push(object);
|
this._in.push(object);
|
||||||
if (object.id && this._callbacks.has(object.id)) {
|
if (object.id && this._callbacks.has(object.id)) {
|
||||||
const callback = this._callbacks.get(object.id);
|
const callback = this._callbacks.get(object.id);
|
||||||
|
|
@ -219,8 +219,6 @@ export class TargetSession extends EventEmitter {
|
||||||
else
|
else
|
||||||
callback.resolve(object.result);
|
callback.resolve(object.result);
|
||||||
} else {
|
} else {
|
||||||
if (object.id)
|
|
||||||
console.log(JSON.stringify(object, null, 2));
|
|
||||||
assert(!object.id);
|
assert(!object.id);
|
||||||
// console.log(`[${this._sessionId}] ${object.method}`);
|
// console.log(`[${this._sessionId}] ${object.method}`);
|
||||||
this.emit(object.method, object.params);
|
this.emit(object.method, object.params);
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export class ExecutionContext {
|
||||||
return void 0;
|
return void 0;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return this._session.send('Runtime.callFunctionOn', {
|
return this._session.send('Runtime.callFunctionOn', {
|
||||||
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
||||||
functionDeclaration: serializeFunction + '\n' + suffix + '\n',
|
functionDeclaration: serializeFunction + '\n' + suffix + '\n',
|
||||||
|
|
@ -121,7 +121,8 @@ export class ExecutionContext {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return valueFromRemoteObject(response.result);
|
return valueFromRemoteObject(response.result);
|
||||||
}).catch(rewriteError); }
|
}).catch(rewriteError);
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof pageFunction !== 'function')
|
if (typeof pageFunction !== 'function')
|
||||||
throw new Error(`Expected to get |string| or |function| as the first argument, but got "${pageFunction}" instead.`);
|
throw new Error(`Expected to get |string| or |function| as the first argument, but got "${pageFunction}" instead.`);
|
||||||
|
|
@ -147,10 +148,10 @@ export class ExecutionContext {
|
||||||
let serializableArgs;
|
let serializableArgs;
|
||||||
if (args.some(isUnserializable)) {
|
if (args.some(isUnserializable)) {
|
||||||
serializableArgs = [];
|
serializableArgs = [];
|
||||||
let paramStrings = [];
|
const paramStrings = [];
|
||||||
for (let arg of args) {
|
for (const arg of args) {
|
||||||
if (isUnserializable(arg)) {
|
if (isUnserializable(arg)) {
|
||||||
paramStrings.push(unserializableToString(arg))
|
paramStrings.push(unserializableToString(arg));
|
||||||
} else {
|
} else {
|
||||||
paramStrings.push('arguments[' + serializableArgs.length + ']');
|
paramStrings.push('arguments[' + serializableArgs.length + ']');
|
||||||
serializableArgs.push(arg);
|
serializableArgs.push(arg);
|
||||||
|
|
@ -172,7 +173,7 @@ export class ExecutionContext {
|
||||||
returnByValue: false,
|
returnByValue: false,
|
||||||
emulateUserGesture: true
|
emulateUserGesture: true
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch (err) {
|
||||||
if (err instanceof TypeError && err.message.startsWith('Converting circular structure to JSON'))
|
if (err instanceof TypeError && err.message.startsWith('Converting circular structure to JSON'))
|
||||||
err.message += ' Are you passing a nested JSHandle?';
|
err.message += ' Are you passing a nested JSHandle?';
|
||||||
throw err;
|
throw err;
|
||||||
|
|
@ -198,7 +199,7 @@ export class ExecutionContext {
|
||||||
if (response.wasThrown)
|
if (response.wasThrown)
|
||||||
throw new Error('Evaluation failed: ' + response.result.description);
|
throw new Error('Evaluation failed: ' + response.result.description);
|
||||||
if (!returnByValue)
|
if (!returnByValue)
|
||||||
return createJSHandle(this, response.result);;
|
return createJSHandle(this, response.result);
|
||||||
if (response.result.objectId) {
|
if (response.result.objectId) {
|
||||||
const serializeFunction = function() {
|
const serializeFunction = function() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -208,7 +209,7 @@ export class ExecutionContext {
|
||||||
return void 0;
|
return void 0;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return this._session.send('Runtime.callFunctionOn', {
|
return this._session.send('Runtime.callFunctionOn', {
|
||||||
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
||||||
functionDeclaration: serializeFunction + '\n' + suffix + '\n',
|
functionDeclaration: serializeFunction + '\n' + suffix + '\n',
|
||||||
|
|
@ -294,7 +295,7 @@ export class ExecutionContext {
|
||||||
|
|
||||||
async _contextGlobalObjectId() {
|
async _contextGlobalObjectId() {
|
||||||
if (!this._globalObjectId) {
|
if (!this._globalObjectId) {
|
||||||
const globalObject = await this._session.send('Runtime.evaluate', { expression: "this", contextId: this._contextId });
|
const globalObject = await this._session.send('Runtime.evaluate', { expression: 'this', contextId: this._contextId });
|
||||||
this._globalObjectId = globalObject.result.objectId;
|
this._globalObjectId = globalObject.result.objectId;
|
||||||
}
|
}
|
||||||
return this._globalObjectId;
|
return this._globalObjectId;
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,18 @@
|
||||||
*/
|
*/
|
||||||
import * as EventEmitter from 'events';
|
import * as EventEmitter from 'events';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import {helper, assert, debugError, RegisteredListener} from '../helper';
|
import { TimeoutError } from '../Errors';
|
||||||
import {TimeoutError} from '../Errors';
|
import { Events } from '../Events';
|
||||||
import {Events} from '../Events';
|
import { assert, debugError, helper, RegisteredListener } from '../helper';
|
||||||
import {ExecutionContext, EVALUATION_SCRIPT_URL} from './ExecutionContext';
|
|
||||||
import {NetworkManager, Response, Request, NetworkManagerEvents} from './NetworkManager';
|
|
||||||
import { TargetSession } from './Connection';
|
|
||||||
import { Page } from './Page';
|
|
||||||
import { TimeoutSettings } from '../TimeoutSettings';
|
import { TimeoutSettings } from '../TimeoutSettings';
|
||||||
import { JSHandle, ElementHandle } from './JSHandle';
|
import { TargetSession } from './Connection';
|
||||||
|
import { ExecutionContext } from './ExecutionContext';
|
||||||
|
import { ElementHandle, JSHandle } from './JSHandle';
|
||||||
|
import { NetworkManager, NetworkManagerEvents, Request, Response } from './NetworkManager';
|
||||||
|
import { Page } from './Page';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
const readFileAsync = helper.promisify(fs.readFile);
|
const readFileAsync = helper.promisify(fs.readFile);
|
||||||
|
|
||||||
export const FrameManagerEvents = {
|
export const FrameManagerEvents = {
|
||||||
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
FrameNavigatedWithinDocument: Symbol('FrameNavigatedWithinDocument'),
|
||||||
TargetSwappedOnNavigation: Symbol('TargetSwappedOnNavigation'),
|
TargetSwappedOnNavigation: Symbol('TargetSwappedOnNavigation'),
|
||||||
|
|
@ -34,7 +35,8 @@ export const FrameManagerEvents = {
|
||||||
FrameAttached: Symbol('FrameAttached'),
|
FrameAttached: Symbol('FrameAttached'),
|
||||||
FrameDetached: Symbol('FrameDetached'),
|
FrameDetached: Symbol('FrameDetached'),
|
||||||
FrameNavigated: Symbol('FrameNavigated'),
|
FrameNavigated: Symbol('FrameNavigated'),
|
||||||
}
|
};
|
||||||
|
|
||||||
export class FrameManager extends EventEmitter {
|
export class FrameManager extends EventEmitter {
|
||||||
_session: TargetSession;
|
_session: TargetSession;
|
||||||
_page: Page;
|
_page: Page;
|
||||||
|
|
@ -71,8 +73,7 @@ export class FrameManager extends EventEmitter {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addSessionListeners()
|
_addSessionListeners() {
|
||||||
{
|
|
||||||
this._sessionListeners = [
|
this._sessionListeners = [
|
||||||
helper.addEventListener(this._session, 'Page.frameNavigated', event => this._onFrameNavigated(event.frame)),
|
helper.addEventListener(this._session, 'Page.frameNavigated', event => this._onFrameNavigated(event.frame)),
|
||||||
helper.addEventListener(this._session, 'Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url)),
|
helper.addEventListener(this._session, 'Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url)),
|
||||||
|
|
@ -82,8 +83,7 @@ export class FrameManager extends EventEmitter {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async _swapTargetOnNavigation(newSession)
|
async _swapTargetOnNavigation(newSession) {
|
||||||
{
|
|
||||||
helper.removeEventListeners(this._sessionListeners);
|
helper.removeEventListeners(this._sessionListeners);
|
||||||
this.disconnectFromTarget();
|
this.disconnectFromTarget();
|
||||||
this._session = newSession;
|
this._session = newSession;
|
||||||
|
|
@ -210,7 +210,7 @@ export class FrameManager extends EventEmitter {
|
||||||
return;
|
return;
|
||||||
/** @type {!ExecutionContext} */
|
/** @type {!ExecutionContext} */
|
||||||
const context: ExecutionContext = new ExecutionContext(this._session, contextPayload, frame);
|
const context: ExecutionContext = new ExecutionContext(this._session, contextPayload, frame);
|
||||||
frame._setContext(context)
|
frame._setContext(context);
|
||||||
this._contextIdToContext.set(contextPayload.id, context);
|
this._contextIdToContext.set(contextPayload.id, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,7 +282,7 @@ export class Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForNavigation(): Promise<Response | null> {
|
async waitForNavigation(): Promise<Response | null> {
|
||||||
//FIXME: this method only works for main frames.
|
// FIXME: this method only works for main frames.
|
||||||
const watchDog = new NextNavigationWatchdog(this, 10000);
|
const watchDog = new NextNavigationWatchdog(this, 10000);
|
||||||
return watchDog.waitForNavigation();
|
return watchDog.waitForNavigation();
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +521,7 @@ export class Frame {
|
||||||
return this._detached;
|
return this._detached;
|
||||||
}
|
}
|
||||||
|
|
||||||
async click(selector: string, options: { delay?: number; button?: "left" | "right" | "middle"; clickCount?: number; } | undefined) {
|
async click(selector: string, options: { delay?: number; button?: 'left' | 'right' | 'middle'; clickCount?: number; } | undefined) {
|
||||||
const handle = await this.$(selector);
|
const handle = await this.$(selector);
|
||||||
assert(handle, 'No node found for selector: ' + selector);
|
assert(handle, 'No node found for selector: ' + selector);
|
||||||
await handle.click(options);
|
await handle.click(options);
|
||||||
|
|
@ -696,7 +696,7 @@ class NextNavigationWatchdog {
|
||||||
constructor(frame, timeout) {
|
constructor(frame, timeout) {
|
||||||
this._frame = frame;
|
this._frame = frame;
|
||||||
this._newDocumentNavigationPromise = new Promise(fulfill => {
|
this._newDocumentNavigationPromise = new Promise(fulfill => {
|
||||||
this._newDocumentNavigationCallback = fulfill
|
this._newDocumentNavigationCallback = fulfill;
|
||||||
});
|
});
|
||||||
this._sameDocumentNavigationPromise = new Promise(fulfill => {
|
this._sameDocumentNavigationPromise = new Promise(fulfill => {
|
||||||
this._sameDocumentNavigationCallback = fulfill;
|
this._sameDocumentNavigationCallback = fulfill;
|
||||||
|
|
@ -742,7 +742,7 @@ class NextNavigationWatchdog {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("_onTargetReconnected " + e);
|
debugError('_onTargetReconnected ' + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@ export class Keyboard {
|
||||||
const ControlKey = 1 << 1;
|
const ControlKey = 1 << 1;
|
||||||
const AltKey = 1 << 2;
|
const AltKey = 1 << 2;
|
||||||
const MetaKey = 1 << 3;
|
const MetaKey = 1 << 3;
|
||||||
const CapsLockKey = 1 << 4;
|
|
||||||
if (key === 'Alt')
|
if (key === 'Alt')
|
||||||
return AltKey;
|
return AltKey;
|
||||||
if (key === 'Control')
|
if (key === 'Control')
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import * as path from 'path';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
import { assert, debugError, helper } from '../helper';
|
||||||
import { TargetSession } from './Connection';
|
import { TargetSession } from './Connection';
|
||||||
import { ExecutionContext } from './ExecutionContext';
|
import { ExecutionContext } from './ExecutionContext';
|
||||||
import { Frame, FrameManager } from './FrameManager';
|
import { FrameManager } from './FrameManager';
|
||||||
import { assert, debugError, helper } from '../helper';
|
import { Button } from './Input';
|
||||||
import { valueFromRemoteObject, releaseObject } from './protocolHelper';
|
|
||||||
import { Page } from './Page';
|
import { Page } from './Page';
|
||||||
import { Modifier, Button } from './Input';
|
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
|
import { releaseObject, valueFromRemoteObject } from './protocolHelper';
|
||||||
const writeFileAsync = helper.promisify(fs.writeFile);
|
const writeFileAsync = helper.promisify(fs.writeFile);
|
||||||
|
|
||||||
export type ClickOptions = {
|
export type ClickOptions = {
|
||||||
|
|
@ -173,7 +172,7 @@ export class ElementHandle extends JSHandle {
|
||||||
this._client.send('DOM.getContentQuads', {
|
this._client.send('DOM.getContentQuads', {
|
||||||
objectId: this._remoteObject.objectId
|
objectId: this._remoteObject.objectId
|
||||||
}).catch(debugError),
|
}).catch(debugError),
|
||||||
this._page.evaluate(() => { return { clientWidth: innerWidth, clientHeight: innerHeight} }),
|
this._page.evaluate(() => ({ clientWidth: innerWidth, clientHeight: innerHeight })),
|
||||||
]);
|
]);
|
||||||
if (!result || !result.quads.length)
|
if (!result || !result.quads.length)
|
||||||
throw new Error('Node is either not visible or not an HTMLElement');
|
throw new Error('Node is either not visible or not an HTMLElement');
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,12 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
import * as path from 'path';
|
import { debugError, helper } from '../helper';
|
||||||
import { Browser } from './Browser';
|
import { Browser } from './Browser';
|
||||||
import { BrowserFetcher } from './BrowserFetcher';
|
import { BrowserFetcher } from './BrowserFetcher';
|
||||||
import { Connection } from './Connection';
|
import { Connection } from './Connection';
|
||||||
import { debugError, helper } from '../helper';
|
|
||||||
import { Viewport } from './Page';
|
import { Viewport } from './Page';
|
||||||
import { PipeTransport } from './PipeTransport';
|
import { PipeTransport } from './PipeTransport';
|
||||||
import * as os from 'os';
|
|
||||||
|
|
||||||
|
|
||||||
export class Launcher {
|
export class Launcher {
|
||||||
|
|
@ -43,7 +41,6 @@ export class Launcher {
|
||||||
handleSIGINT = true,
|
handleSIGINT = true,
|
||||||
handleSIGTERM = true,
|
handleSIGTERM = true,
|
||||||
handleSIGHUP = true,
|
handleSIGHUP = true,
|
||||||
headless = true,
|
|
||||||
defaultViewport = {width: 800, height: 600},
|
defaultViewport = {width: 800, height: 600},
|
||||||
slowMo = 0
|
slowMo = 0
|
||||||
} = options;
|
} = options;
|
||||||
|
|
@ -100,8 +97,7 @@ export class Launcher {
|
||||||
try {
|
try {
|
||||||
const transport = new PipeTransport(webkitProcess.stdio[3] as NodeJS.WritableStream, webkitProcess.stdio[4] as NodeJS.ReadableStream);
|
const transport = new PipeTransport(webkitProcess.stdio[3] as NodeJS.WritableStream, webkitProcess.stdio[4] as NodeJS.ReadableStream);
|
||||||
connection = new Connection('', transport, slowMo);
|
connection = new Connection('', transport, slowMo);
|
||||||
const browser = new Browser(connection, defaultViewport, webkitProcess
|
const browser = new Browser(connection, defaultViewport, webkitProcess, gracefullyCloseWebkit);
|
||||||
, gracefullyCloseWebkit);
|
|
||||||
return browser;
|
return browser;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
killWebKit();
|
killWebKit();
|
||||||
|
|
|
||||||
|
|
@ -310,79 +310,3 @@ export class Response {
|
||||||
return this._request.frame();
|
return this._request.frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function headersArray(headers: { [s: string]: string; }): { name: string; value: string; }[] {
|
|
||||||
const result = [];
|
|
||||||
for (const name in headers) {
|
|
||||||
if (headers[name] !== undefined)
|
|
||||||
result.push({name, value: headers[name] + ''});
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// List taken from https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml with extra 306 and 418 codes.
|
|
||||||
const STATUS_TEXTS = {
|
|
||||||
'100': 'Continue',
|
|
||||||
'101': 'Switching Protocols',
|
|
||||||
'102': 'Processing',
|
|
||||||
'103': 'Early Hints',
|
|
||||||
'200': 'OK',
|
|
||||||
'201': 'Created',
|
|
||||||
'202': 'Accepted',
|
|
||||||
'203': 'Non-Authoritative Information',
|
|
||||||
'204': 'No Content',
|
|
||||||
'205': 'Reset Content',
|
|
||||||
'206': 'Partial Content',
|
|
||||||
'207': 'Multi-Status',
|
|
||||||
'208': 'Already Reported',
|
|
||||||
'226': 'IM Used',
|
|
||||||
'300': 'Multiple Choices',
|
|
||||||
'301': 'Moved Permanently',
|
|
||||||
'302': 'Found',
|
|
||||||
'303': 'See Other',
|
|
||||||
'304': 'Not Modified',
|
|
||||||
'305': 'Use Proxy',
|
|
||||||
'306': 'Switch Proxy',
|
|
||||||
'307': 'Temporary Redirect',
|
|
||||||
'308': 'Permanent Redirect',
|
|
||||||
'400': 'Bad Request',
|
|
||||||
'401': 'Unauthorized',
|
|
||||||
'402': 'Payment Required',
|
|
||||||
'403': 'Forbidden',
|
|
||||||
'404': 'Not Found',
|
|
||||||
'405': 'Method Not Allowed',
|
|
||||||
'406': 'Not Acceptable',
|
|
||||||
'407': 'Proxy Authentication Required',
|
|
||||||
'408': 'Request Timeout',
|
|
||||||
'409': 'Conflict',
|
|
||||||
'410': 'Gone',
|
|
||||||
'411': 'Length Required',
|
|
||||||
'412': 'Precondition Failed',
|
|
||||||
'413': 'Payload Too Large',
|
|
||||||
'414': 'URI Too Long',
|
|
||||||
'415': 'Unsupported Media Type',
|
|
||||||
'416': 'Range Not Satisfiable',
|
|
||||||
'417': 'Expectation Failed',
|
|
||||||
'418': 'I\'m a teapot',
|
|
||||||
'421': 'Misdirected Request',
|
|
||||||
'422': 'Unprocessable Entity',
|
|
||||||
'423': 'Locked',
|
|
||||||
'424': 'Failed Dependency',
|
|
||||||
'425': 'Too Early',
|
|
||||||
'426': 'Upgrade Required',
|
|
||||||
'428': 'Precondition Required',
|
|
||||||
'429': 'Too Many Requests',
|
|
||||||
'431': 'Request Header Fields Too Large',
|
|
||||||
'451': 'Unavailable For Legal Reasons',
|
|
||||||
'500': 'Internal Server Error',
|
|
||||||
'501': 'Not Implemented',
|
|
||||||
'502': 'Bad Gateway',
|
|
||||||
'503': 'Service Unavailable',
|
|
||||||
'504': 'Gateway Timeout',
|
|
||||||
'505': 'HTTP Version Not Supported',
|
|
||||||
'506': 'Variant Also Negotiates',
|
|
||||||
'507': 'Insufficient Storage',
|
|
||||||
'508': 'Loop Detected',
|
|
||||||
'510': 'Not Extended',
|
|
||||||
'511': 'Network Authentication Required',
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import * as mime from 'mime';
|
||||||
import { TargetSession, TargetSessionEvents } from './Connection';
|
import { TargetSession, TargetSessionEvents } from './Connection';
|
||||||
import { Events } from '../Events';
|
import { Events } from '../Events';
|
||||||
import { Frame, FrameManager, FrameManagerEvents } from './FrameManager';
|
import { Frame, FrameManager, FrameManagerEvents } from './FrameManager';
|
||||||
import { assert, helper, RegisteredListener } from '../helper';
|
import { assert, debugError, helper, RegisteredListener } from '../helper';
|
||||||
import { valueFromRemoteObject } from './protocolHelper';
|
import { valueFromRemoteObject } from './protocolHelper';
|
||||||
import { Keyboard, Mouse } from './Input';
|
import { Keyboard, Mouse } from './Input';
|
||||||
import { createJSHandle, ElementHandle, JSHandle, ClickOptions } from './JSHandle';
|
import { createJSHandle, ElementHandle, JSHandle, ClickOptions } from './JSHandle';
|
||||||
|
|
@ -113,14 +113,11 @@ export class Page extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _swapTargetOnNavigation(newSession : TargetSession, newTarget : Target)
|
async _swapTargetOnNavigation(newSession : TargetSession, newTarget : Target) {
|
||||||
{
|
|
||||||
this._setSession(newSession);
|
this._setSession(newSession);
|
||||||
this._setTarget(newTarget);
|
this._setTarget(newTarget);
|
||||||
|
|
||||||
await this._frameManager._swapTargetOnNavigation(newSession);
|
await this._frameManager._swapTargetOnNavigation(newSession);
|
||||||
|
await this._initialize().catch(e => debugError('failed to enable agents after swap: ' + e));
|
||||||
await this._initialize().catch(e => console.log('failed to enable agents after swap: ' + e));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target(): Target {
|
target(): Target {
|
||||||
|
|
@ -140,7 +137,7 @@ export class Page extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onConsoleMessage(event : Protocol.Console.messageAddedPayload) {
|
async _onConsoleMessage(event : Protocol.Console.messageAddedPayload) {
|
||||||
const {type, level, text, parameters, url, line:lineNumber, column:columnNumber} = event.message;
|
const { type, level, text, parameters, url, line: lineNumber, column: columnNumber } = event.message;
|
||||||
let derivedType: string = type;
|
let derivedType: string = type;
|
||||||
if (type === 'log')
|
if (type === 'log')
|
||||||
derivedType = level;
|
derivedType = level;
|
||||||
|
|
@ -148,7 +145,7 @@ export class Page extends EventEmitter {
|
||||||
derivedType = 'timeEnd';
|
derivedType = 'timeEnd';
|
||||||
const mainFrameContext = await this.mainFrame().executionContext();
|
const mainFrameContext = await this.mainFrame().executionContext();
|
||||||
const handles = (parameters || []).map(p => {
|
const handles = (parameters || []).map(p => {
|
||||||
let context = null;;
|
let context = null;
|
||||||
if (p.objectId) {
|
if (p.objectId) {
|
||||||
const objectId = JSON.parse(p.objectId);
|
const objectId = JSON.parse(p.objectId);
|
||||||
context = this._frameManager._contextIdToContext.get(objectId.injectedScriptId);
|
context = this._frameManager._contextIdToContext.get(objectId.injectedScriptId);
|
||||||
|
|
@ -239,7 +236,7 @@ export class Page extends EventEmitter {
|
||||||
};
|
};
|
||||||
if (!cookie.url && pageURL.startsWith('http'))
|
if (!cookie.url && pageURL.startsWith('http'))
|
||||||
item.url = pageURL;
|
item.url = pageURL;
|
||||||
await this._session.send('Page.deleteCookie', item).catch(e => console.log("deleting " + JSON.stringify(item) + " => " +e));
|
await this._session.send('Page.deleteCookie', item).catch(e => debugError('deleting ' + JSON.stringify(item) + ' => ' + e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,22 +385,22 @@ export class Page extends EventEmitter {
|
||||||
async _screenshotTask(options?: ScreenshotOptions): Promise<Buffer | string> {
|
async _screenshotTask(options?: ScreenshotOptions): Promise<Buffer | string> {
|
||||||
const params: Protocol.Page.snapshotRectParameters = { x: 0, y: 0, width: 800, height: 600, coordinateSystem: 'Page' };
|
const params: Protocol.Page.snapshotRectParameters = { x: 0, y: 0, width: 800, height: 600, coordinateSystem: 'Page' };
|
||||||
if (options.fullPage) {
|
if (options.fullPage) {
|
||||||
const pageSize = await this.evaluate(() => {
|
const pageSize = await this.evaluate(() =>
|
||||||
return {
|
({
|
||||||
width: document.body.scrollWidth,
|
width: document.body.scrollWidth,
|
||||||
height: document.body.scrollHeight
|
height: document.body.scrollHeight
|
||||||
};
|
}));
|
||||||
});
|
|
||||||
Object.assign(params, pageSize);
|
Object.assign(params, pageSize);
|
||||||
} else if (options.clip)
|
} else if (options.clip) {
|
||||||
Object.assign(params, options.clip);
|
Object.assign(params, options.clip);
|
||||||
else if (this._viewport)
|
} else if (this._viewport) {
|
||||||
Object.assign(params, this._viewport);
|
Object.assign(params, this._viewport);
|
||||||
|
}
|
||||||
const [, result] = await Promise.all([
|
const [, result] = await Promise.all([
|
||||||
this._session._connection.send('Target.activate', { targetId: this._target._targetId }),
|
this._session._connection.send('Target.activate', { targetId: this._target._targetId }),
|
||||||
this._session.send('Page.snapshotRect', params),
|
this._session.send('Page.snapshotRect', params),
|
||||||
]).catch(e => {
|
]).catch(e => {
|
||||||
console.log('Failed to take screenshot: ' + e);
|
debugError('Failed to take screenshot: ' + e);
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
const prefix = 'data:image/png;base64,';
|
const prefix = 'data:image/png;base64,';
|
||||||
|
|
@ -421,7 +418,7 @@ export class Page extends EventEmitter {
|
||||||
this.browser()._connection.send('Target.close', {
|
this.browser()._connection.send('Target.close', {
|
||||||
targetId: this._target._targetId
|
targetId: this._target._targetId
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
console.log(e);
|
debugError(e);
|
||||||
});
|
});
|
||||||
await this._target._isClosedPromise;
|
await this._target._isClosedPromise;
|
||||||
}
|
}
|
||||||
|
|
@ -516,76 +513,6 @@ type ScreenshotOptions = {
|
||||||
encoding?: string,
|
encoding?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
type MediaFeature = {
|
|
||||||
name: string,
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const supportedMetrics: Set<string> = new Set([
|
|
||||||
'Timestamp',
|
|
||||||
'Documents',
|
|
||||||
'Frames',
|
|
||||||
'JSEventListeners',
|
|
||||||
'Nodes',
|
|
||||||
'LayoutCount',
|
|
||||||
'RecalcStyleCount',
|
|
||||||
'LayoutDuration',
|
|
||||||
'RecalcStyleDuration',
|
|
||||||
'ScriptDuration',
|
|
||||||
'TaskDuration',
|
|
||||||
'JSHeapUsedSize',
|
|
||||||
'JSHeapTotalSize',
|
|
||||||
]);
|
|
||||||
|
|
||||||
const PagePaperFormats = {
|
|
||||||
letter: {width: 8.5, height: 11},
|
|
||||||
legal: {width: 8.5, height: 14},
|
|
||||||
tabloid: {width: 11, height: 17},
|
|
||||||
ledger: {width: 17, height: 11},
|
|
||||||
a0: {width: 33.1, height: 46.8 },
|
|
||||||
a1: {width: 23.4, height: 33.1 },
|
|
||||||
a2: {width: 16.54, height: 23.4 },
|
|
||||||
a3: {width: 11.7, height: 16.54 },
|
|
||||||
a4: {width: 8.27, height: 11.7 },
|
|
||||||
a5: {width: 5.83, height: 8.27 },
|
|
||||||
a6: {width: 4.13, height: 5.83 },
|
|
||||||
};
|
|
||||||
|
|
||||||
const unitToPixels = {
|
|
||||||
'px': 1,
|
|
||||||
'in': 96,
|
|
||||||
'cm': 37.8,
|
|
||||||
'mm': 3.78
|
|
||||||
};
|
|
||||||
|
|
||||||
function convertPrintParameterToInches(parameter: (string | number | undefined)): (number | undefined) {
|
|
||||||
if (typeof parameter === 'undefined')
|
|
||||||
return undefined;
|
|
||||||
let pixels: number;
|
|
||||||
if (helper.isNumber(parameter)) {
|
|
||||||
// Treat numbers as pixel values to be aligned with phantom's paperSize.
|
|
||||||
pixels = parameter as number;
|
|
||||||
} else if (helper.isString(parameter)) {
|
|
||||||
const text: string = parameter as string;
|
|
||||||
let unit = text.substring(text.length - 2).toLowerCase();
|
|
||||||
let valueText = '';
|
|
||||||
if (unitToPixels.hasOwnProperty(unit)) {
|
|
||||||
valueText = text.substring(0, text.length - 2);
|
|
||||||
} else {
|
|
||||||
// In case of unknown unit try to parse the whole parameter as number of pixels.
|
|
||||||
// This is consistent with phantom's paperSize behavior.
|
|
||||||
unit = 'px';
|
|
||||||
valueText = text;
|
|
||||||
}
|
|
||||||
const value = Number(valueText);
|
|
||||||
assert(!isNaN(value), 'Failed to parse parameter value: ' + text);
|
|
||||||
pixels = value * unitToPixels[unit];
|
|
||||||
} else {
|
|
||||||
throw new Error('page.pdf() Cannot handle parameter type: ' + (typeof parameter));
|
|
||||||
}
|
|
||||||
return pixels / 96;
|
|
||||||
}
|
|
||||||
|
|
||||||
type NetworkCookie = {
|
type NetworkCookie = {
|
||||||
name: string,
|
name: string,
|
||||||
value: string,
|
value: string,
|
||||||
|
|
@ -599,19 +526,6 @@ type NetworkCookie = {
|
||||||
sameSite?: 'Strict'|'Lax'|'Extended'|'None'
|
sameSite?: 'Strict'|'Lax'|'Extended'|'None'
|
||||||
};
|
};
|
||||||
|
|
||||||
type NetworkCookieParam = {
|
|
||||||
name: string,
|
|
||||||
value: string,
|
|
||||||
url?: string,
|
|
||||||
domain?: string,
|
|
||||||
path?: string,
|
|
||||||
expires?: number,
|
|
||||||
httpOnly?: boolean,
|
|
||||||
secure?: boolean,
|
|
||||||
sameSite?: 'Strict'|'Lax'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
type DeleteNetworkCookieParam = {
|
type DeleteNetworkCookieParam = {
|
||||||
name: string,
|
name: string,
|
||||||
url?: string,
|
url?: string,
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Browser, BrowserContext } from './Browser';
|
|
||||||
import { TargetSession, Connection } from './Connection';
|
|
||||||
import { Events } from '../Events';
|
|
||||||
import { Page, Viewport } from './Page';
|
|
||||||
import { TaskQueue } from './TaskQueue';
|
|
||||||
import { Protocol } from './protocol';
|
|
||||||
import { helper, RegisteredListener } from '../helper';
|
import { helper, RegisteredListener } from '../helper';
|
||||||
|
import { Browser, BrowserContext } from './Browser';
|
||||||
|
import { Page } from './Page';
|
||||||
|
import { Protocol } from './protocol';
|
||||||
|
|
||||||
export class Target {
|
export class Target {
|
||||||
private _browserContext: BrowserContext;
|
private _browserContext: BrowserContext;
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import * as fs from 'fs';
|
|
||||||
import {helper, assert, debugError} from '../helper';
|
import { assert, debugError } from '../helper';
|
||||||
import { TargetSession } from './Connection';
|
import { TargetSession } from './Connection';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
|
|
||||||
const openAsync = helper.promisify(fs.open);
|
|
||||||
const writeAsync = helper.promisify(fs.write);
|
|
||||||
const closeAsync = helper.promisify(fs.close);
|
|
||||||
|
|
||||||
export function valueFromRemoteObject(remoteObject: Protocol.Runtime.RemoteObject): any {
|
export function valueFromRemoteObject(remoteObject: Protocol.Runtime.RemoteObject): any {
|
||||||
assert(!remoteObject.objectId, 'Cannot extract value when objectId is given');
|
assert(!remoteObject.objectId, 'Cannot extract value when objectId is given');
|
||||||
if (remoteObject.type === 'number') {
|
if (remoteObject.type === 'number') {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue