chore: cleanup multiple definitions and types (#109)

This commit is contained in:
Dmitry Gozman 2019-11-27 16:03:51 -08:00 коммит произвёл GitHub
Родитель c3393039b0
Коммит 961556a596
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
25 изменённых файлов: 302 добавлений и 283 удалений

Просмотреть файл

@ -26,9 +26,6 @@ import * as dom from '../dom';
export const EVALUATION_SCRIPT_URL = '__playwright_evaluation_script__';
const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
export type ExecutionContext = js.ExecutionContext;
export type JSHandle = js.JSHandle;
export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
_client: CDPSession;
_contextId: number;
@ -38,7 +35,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
this._contextId = contextPayload.id;
}
async evaluate(context: ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
async evaluate(context: js.ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
const suffix = `//# sourceURL=${EVALUATION_SCRIPT_URL}`;
if (helper.isString(pageFunction)) {
@ -136,7 +133,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
}
}
async adoptBackendNodeId(context: ExecutionContext, backendNodeId: Protocol.DOM.BackendNodeId) {
async adoptBackendNodeId(context: js.ExecutionContext, backendNodeId: Protocol.DOM.BackendNodeId) {
const {object} = await this._client.send('DOM.resolveNode', {
backendNodeId,
executionContextId: this._contextId,
@ -144,7 +141,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return createJSHandle(context, object) as dom.ElementHandle;
}
async getProperties(handle: JSHandle): Promise<Map<string, JSHandle>> {
async getProperties(handle: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._client.send('Runtime.getProperties', {
objectId: toRemoteObject(handle).objectId,
ownProperties: true
@ -158,11 +155,11 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return result;
}
async releaseHandle(handle: JSHandle): Promise<void> {
async releaseHandle(handle: js.JSHandle): Promise<void> {
await releaseObject(this._client, toRemoteObject(handle));
}
async handleJSONValue(handle: JSHandle): Promise<any> {
async handleJSONValue(handle: js.JSHandle): Promise<any> {
const remoteObject = toRemoteObject(handle);
if (remoteObject.objectId) {
const response = await this._client.send('Runtime.callFunctionOn', {
@ -176,7 +173,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return valueFromRemoteObject(remoteObject);
}
handleToString(handle: JSHandle): string {
handleToString(handle: js.JSHandle): string {
const object = toRemoteObject(handle);
if (object.objectId) {
const type = object.subtype || object.type;
@ -188,10 +185,10 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
const remoteObjectSymbol = Symbol('RemoteObject');
export function toRemoteObject(handle: JSHandle): Protocol.Runtime.RemoteObject {
export function toRemoteObject(handle: js.JSHandle): Protocol.Runtime.RemoteObject {
return (handle as any)[remoteObjectSymbol];
}
export function markJSHandle(handle: JSHandle, remoteObject: Protocol.Runtime.RemoteObject) {
export function markJSHandle(handle: js.JSHandle, remoteObject: Protocol.Runtime.RemoteObject) {
(handle as any)[remoteObjectSymbol] = remoteObject;
}

Просмотреть файл

@ -20,11 +20,12 @@ import * as frames from '../frames';
import { assert, debugError } from '../helper';
import * as js from '../javascript';
import * as dom from '../dom';
import * as network from '../network';
import { TimeoutSettings } from '../TimeoutSettings';
import { CDPSession } from './Connection';
import { EVALUATION_SCRIPT_URL, ExecutionContext, ExecutionContextDelegate, toRemoteObject } from './ExecutionContext';
import { EVALUATION_SCRIPT_URL, ExecutionContextDelegate, toRemoteObject } from './ExecutionContext';
import { LifecycleWatcher } from './LifecycleWatcher';
import { NetworkManager, Response } from './NetworkManager';
import { NetworkManager } from './NetworkManager';
import { Page } from './Page';
import { Protocol } from './protocol';
@ -45,17 +46,15 @@ type FrameData = {
lifecycleEvents: Set<string>,
};
export type Frame = frames.Frame;
export class FrameManager extends EventEmitter implements frames.FrameDelegate {
_client: CDPSession;
private _page: Page;
private _networkManager: NetworkManager;
_timeoutSettings: TimeoutSettings;
private _frames = new Map<string, Frame>();
private _contextIdToContext = new Map<number, ExecutionContext>();
private _frames = new Map<string, frames.Frame>();
private _contextIdToContext = new Map<number, js.ExecutionContext>();
private _isolatedWorlds = new Set<string>();
private _mainFrame: Frame;
private _mainFrame: frames.Frame;
constructor(client: CDPSession, page: Page, ignoreHTTPSErrors: boolean, timeoutSettings: TimeoutSettings) {
super();
@ -92,14 +91,14 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return this._networkManager;
}
_frameData(frame: Frame): FrameData {
_frameData(frame: frames.Frame): FrameData {
return (frame as any)[frameDataSymbol];
}
async navigateFrame(
frame: Frame,
frame: frames.Frame,
url: string,
options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } = {}): Promise<Response | null> {
options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } = {}): Promise<network.Response | null> {
assertNoLegacyNavigationOptions(options);
const {
referer = this._networkManager.extraHTTPHeaders()['referer'],
@ -136,9 +135,9 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
}
async waitForFrameNavigation(
frame: Frame,
frame: frames.Frame,
options: { timeout?: number; waitUntil?: string | string[]; } = {}
): Promise<Response | null> {
): Promise<network.Response | null> {
assertNoLegacyNavigationOptions(options);
const {
waitUntil = ['load'],
@ -156,7 +155,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return watcher.navigationResponse();
}
async setFrameContent(frame: Frame, html: string, options: frames.NavigateOptions = {}) {
async setFrameContent(frame: frames.Frame, html: string, options: frames.NavigateOptions = {}) {
const {
waitUntil = ['load'],
timeout = this._timeoutSettings.navigationTimeout(),
@ -179,11 +178,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
throw error;
}
timeoutSettings(): TimeoutSettings {
return this._timeoutSettings;
}
async adoptElementHandle(elementHandle: dom.ElementHandle, context: ExecutionContext): Promise<dom.ElementHandle> {
async adoptElementHandle(elementHandle: dom.ElementHandle, context: js.ExecutionContext): Promise<dom.ElementHandle> {
const nodeInfo = await this._client.send('DOM.describeNode', {
objectId: toRemoteObject(elementHandle).objectId,
});
@ -228,15 +223,15 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return this._page;
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._mainFrame;
}
frames(): Frame[] {
frames(): frames.Frame[] {
return Array.from(this._frames.values());
}
frame(frameId: string): Frame | null {
frame(frameId: string): frames.Frame | null {
return this._frames.get(frameId) || null;
}
@ -245,7 +240,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return;
assert(parentFrameId);
const parentFrame = this._frames.get(parentFrameId);
const frame = new frames.Frame(this, parentFrame);
const frame = new frames.Frame(this, this._timeoutSettings, parentFrame);
const data: FrameData = {
id: frameId,
loaderId: '',
@ -276,7 +271,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
data.id = framePayload.id;
} else {
// Initial main frame navigation.
frame = new frames.Frame(this, null);
frame = new frames.Frame(this, this._timeoutSettings, null);
const data: FrameData = {
id: framePayload.id,
loaderId: '',
@ -329,7 +324,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
const frame = this._frames.get(frameId) || null;
if (contextPayload.auxData && contextPayload.auxData['type'] === 'isolated')
this._isolatedWorlds.add(contextPayload.name);
const context: ExecutionContext = new js.ExecutionContext(new ExecutionContextDelegate(this._client, contextPayload), frame);
const context: js.ExecutionContext = new js.ExecutionContext(new ExecutionContextDelegate(this._client, contextPayload), frame);
if (frame) {
if (contextPayload.auxData && !!contextPayload.auxData['isDefault'])
frame._contextCreated('main', context);
@ -353,13 +348,13 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
this._onExecutionContextDestroyed(contextId);
}
executionContextById(contextId: number): ExecutionContext {
executionContextById(contextId: number): js.ExecutionContext {
const context = this._contextIdToContext.get(contextId);
assert(context, 'INTERNAL ERROR: missing context with id = ' + contextId);
return context;
}
_removeFramesRecursively(frame: Frame) {
_removeFramesRecursively(frame: frames.Frame) {
for (const child of frame.childFrames())
this._removeFramesRecursively(child);
frame._detach();

Просмотреть файл

@ -19,13 +19,14 @@ import { assert, debugError } from '../helper';
import * as js from '../javascript';
import * as dom from '../dom';
import * as input from '../input';
import * as types from '../types';
import * as frames from '../frames';
import { CDPSession } from './Connection';
import { Frame } from './FrameManager';
import { FrameManager } from './FrameManager';
import { Protocol } from './protocol';
import { JSHandle, ExecutionContext, ExecutionContextDelegate, markJSHandle, toRemoteObject } from './ExecutionContext';
import { ExecutionContextDelegate, markJSHandle, toRemoteObject } from './ExecutionContext';
export function createJSHandle(context: ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): JSHandle {
export function createJSHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
const frame = context.frame();
if (remoteObject.subtype === 'node' && frame) {
const frameManager = frame._delegate as FrameManager;
@ -49,7 +50,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
this._frameManager = frameManager;
}
async contentFrame(handle: dom.ElementHandle): Promise<Frame|null> {
async contentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null> {
const nodeInfo = await this._client.send('DOM.describeNode', {
objectId: toRemoteObject(handle).objectId
});
@ -68,7 +69,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
}).catch(error => debugError(error));
}
async boundingBox(handle: dom.ElementHandle): Promise<dom.Rect | null> {
async boundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
const result = await this._getBoxModel(handle);
if (!result)
return null;
@ -121,7 +122,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return imageData;
}
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: dom.Point): Promise<dom.Point> {
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: types.Point): Promise<types.Point> {
await handle._scrollIntoViewIfNeeded();
if (!relativePoint)
return this._clickablePoint(handle);
@ -142,8 +143,8 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return r.point;
}
private async _clickablePoint(handle: dom.ElementHandle): Promise<dom.Point> {
const fromProtocolQuad = (quad: number[]): dom.Point[] => {
private async _clickablePoint(handle: dom.ElementHandle): Promise<types.Point> {
const fromProtocolQuad = (quad: number[]): types.Point[] => {
return [
{x: quad[0], y: quad[1]},
{x: quad[2], y: quad[3]},
@ -152,14 +153,14 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
];
};
const intersectQuadWithViewport = (quad: dom.Point[], width: number, height: number): dom.Point[] => {
const intersectQuadWithViewport = (quad: types.Point[], width: number, height: number): types.Point[] => {
return quad.map(point => ({
x: Math.min(Math.max(point.x, 0), width),
y: Math.min(Math.max(point.y, 0), height),
}));
};
const computeQuadArea = (quad: dom.Point[]) => {
const computeQuadArea = (quad: types.Point[]) => {
// Compute sum of all directed areas of adjacent triangles
// https://en.wikipedia.org/wiki/Polygon#Simple_polygons
let area = 0;
@ -200,9 +201,9 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
};
}
async _viewportPointAndScroll(handle: dom.ElementHandle, relativePoint: dom.Point): Promise<{point: dom.Point, scrollX: number, scrollY: number}> {
async _viewportPointAndScroll(handle: dom.ElementHandle, relativePoint: types.Point): Promise<{point: types.Point, scrollX: number, scrollY: number}> {
const model = await this._getBoxModel(handle);
let point: dom.Point;
let point: types.Point;
if (!model) {
point = relativePoint;
} else {

Просмотреть файл

@ -17,18 +17,19 @@
import { CDPSessionEvents } from './Connection';
import { TimeoutError } from '../Errors';
import { Frame } from './FrameManager';
import { FrameManager, FrameManagerEvents } from './FrameManager';
import { assert, helper, RegisteredListener } from '../helper';
import { NetworkManagerEvents, Request, Response } from './NetworkManager';
import { NetworkManagerEvents } from './NetworkManager';
import * as frames from '../frames';
import * as network from '../network';
export class LifecycleWatcher {
private _expectedLifecycle: string[];
private _frameManager: FrameManager;
private _frame: Frame;
private _frame: frames.Frame;
private _initialLoaderId: string;
private _timeout: number;
private _navigationRequest: Request | null = null;
private _navigationRequest: network.Request | null = null;
private _eventListeners: RegisteredListener[];
private _sameDocumentNavigationPromise: Promise<Error | null>;
private _sameDocumentNavigationCompleteCallback: () => void;
@ -42,7 +43,7 @@ export class LifecycleWatcher {
private _maximumTimer: NodeJS.Timer;
private _hasSameDocumentNavigation: boolean;
constructor(frameManager: FrameManager, frame: Frame, waitUntil: string | string[], timeout: number) {
constructor(frameManager: FrameManager, frame: frames.Frame, waitUntil: string | string[], timeout: number) {
if (Array.isArray(waitUntil))
waitUntil = waitUntil.slice();
else if (typeof waitUntil === 'string')
@ -84,13 +85,13 @@ export class LifecycleWatcher {
this._checkLifecycleComplete();
}
_onRequest(request: Request) {
_onRequest(request: network.Request) {
if (request.frame() !== this._frame || !request.isNavigationRequest())
return;
this._navigationRequest = request;
}
_onFrameDetached(frame: Frame) {
_onFrameDetached(frame: frames.Frame) {
if (this._frame === frame) {
this._terminationCallback.call(null, new Error('Navigating frame was detached'));
return;
@ -98,7 +99,7 @@ export class LifecycleWatcher {
this._checkLifecycleComplete();
}
navigationResponse(): Response | null {
navigationResponse(): network.Response | null {
return this._navigationRequest ? this._navigationRequest.response() : null;
}
@ -130,7 +131,7 @@ export class LifecycleWatcher {
.then(() => new TimeoutError(errorMessage));
}
_navigatedWithinDocument(frame: Frame) {
_navigatedWithinDocument(frame: frames.Frame) {
if (frame !== this._frame)
return;
this._hasSameDocumentNavigation = true;
@ -138,7 +139,7 @@ export class LifecycleWatcher {
}
_checkLifecycleComplete() {
const checkLifecycle = (frame: Frame, expectedLifecycle: string[]): boolean => {
const checkLifecycle = (frame: frames.Frame, expectedLifecycle: string[]): boolean => {
for (const event of expectedLifecycle) {
if (!this._frameManager._frameData(frame).lifecycleEvents.has(event))
return false;

Просмотреть файл

@ -17,11 +17,11 @@
import { EventEmitter } from 'events';
import { CDPSession } from './Connection';
import { Frame } from './FrameManager';
import { FrameManager } from './FrameManager';
import { assert, debugError, helper } from '../helper';
import { Protocol } from './protocol';
import * as network from '../network';
import * as frames from '../frames';
export const NetworkManagerEvents = {
Request: Symbol('Events.NetworkManager.Request'),
@ -30,9 +30,6 @@ export const NetworkManagerEvents = {
RequestFinished: Symbol('Events.NetworkManager.RequestFinished'),
};
export type Request = network.Request;
export type Response = network.Response;
export class NetworkManager extends EventEmitter {
private _client: CDPSession;
private _ignoreHTTPSErrors: boolean;
@ -191,7 +188,7 @@ export class NetworkManager extends EventEmitter {
}
_onRequest(event: Protocol.Network.requestWillBeSentPayload, interceptionId: string | null) {
let redirectChain: Request[] = [];
let redirectChain: network.Request[] = [];
if (event.redirectResponse) {
const request = this._requestIdToRequest.get(event.requestId);
// If we connect late to the target, we could have missed the requestWillBeSent event.
@ -206,7 +203,7 @@ export class NetworkManager extends EventEmitter {
this.emit(NetworkManagerEvents.Request, request.request);
}
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): Response {
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): network.Response {
const remoteAddress: network.RemoteAddress = { ip: responsePayload.remoteIPAddress, port: responsePayload.remotePort };
const getResponseBody = async () => {
const response = await this._client.send('Network.getResponseBody', { requestId: request._requestId });
@ -273,14 +270,14 @@ export function toInterceptableRequest(request: network.Request): InterceptableR
}
class InterceptableRequest {
readonly request: Request;
readonly request: network.Request;
_requestId: string;
_interceptionId: string;
private _client: CDPSession;
private _allowInterception: boolean;
private _interceptionHandled = false;
constructor(client: CDPSession, frame: Frame | null, interceptionId: string, allowInterception: boolean, event: Protocol.Network.requestWillBeSentPayload, redirectChain: Request[]) {
constructor(client: CDPSession, frame: frames.Frame | null, interceptionId: string, allowInterception: boolean, event: Protocol.Network.requestWillBeSentPayload, redirectChain: network.Request[]) {
this._client = client;
this._requestId = event.requestId;
this._interceptionId = interceptionId;

Просмотреть файл

@ -33,12 +33,11 @@ import { Overrides } from './features/overrides';
import { Interception } from './features/interception';
import { PDF } from './features/pdf';
import { Workers } from './features/workers';
import { Frame } from './FrameManager';
import { FrameManager, FrameManagerEvents } from './FrameManager';
import { RawMouseImpl, RawKeyboardImpl } from './Input';
import { createJSHandle } from './JSHandle';
import { JSHandle, toRemoteObject } from './ExecutionContext';
import { NetworkManagerEvents, Response } from './NetworkManager';
import { toRemoteObject } from './ExecutionContext';
import { NetworkManagerEvents } from './NetworkManager';
import { Protocol } from './protocol';
import { getExceptionMessage, releaseObject, valueFromRemoteObject } from './protocolHelper';
import { Target } from './Target';
@ -46,6 +45,9 @@ import { TaskQueue } from './TaskQueue';
import * as input from '../input';
import * as types from '../types';
import * as dom from '../dom';
import * as frames from '../frames';
import * as js from '../javascript';
import * as network from '../network';
import { ExecutionContextDelegate } from './ExecutionContext';
const writeFileAsync = helper.promisify(fs.writeFile);
@ -205,7 +207,7 @@ export class Page extends EventEmitter {
this.emit(Events.Page.Console, new ConsoleMessage(level, text, [], {url, lineNumber}));
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._frameManager.mainFrame();
}
@ -213,7 +215,7 @@ export class Page extends EventEmitter {
return this._keyboard;
}
frames(): Frame[] {
frames(): frames.Frame[] {
return this._frameManager.frames();
}
@ -229,16 +231,16 @@ export class Page extends EventEmitter {
return this.mainFrame().$(selector);
}
evaluateHandle: types.EvaluateHandle<JSHandle> = async (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
const context = await this.mainFrame().executionContext();
return context.evaluateHandle(pageFunction, ...args as any);
}
$eval: types.$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$eval: types.$Eval = (selector, pageFunction, ...args) => {
return this.mainFrame().$eval(selector, pageFunction, ...args as any);
}
$$eval: types.$$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$$eval: types.$$Eval = (selector, pageFunction, ...args) => {
return this.mainFrame().$$eval(selector, pageFunction, ...args as any);
}
@ -355,7 +357,7 @@ export class Page extends EventEmitter {
}
}
_addConsoleMessage(type: string, args: JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) {
_addConsoleMessage(type: string, args: js.JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) {
if (!this.listenerCount(Events.Page.Console)) {
args.forEach(arg => arg.dispose());
return;
@ -404,11 +406,11 @@ export class Page extends EventEmitter {
await this._frameManager.mainFrame().setContent(html, options);
}
async goto(url: string, options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<Response | null> {
async goto(url: string, options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<network.Response | null> {
return await this._frameManager.mainFrame().goto(url, options);
}
async reload(options: { timeout?: number; waitUntil?: string | string[]; } = {}): Promise<Response | null> {
async reload(options: { timeout?: number; waitUntil?: string | string[]; } = {}): Promise<network.Response | null> {
const [response] = await Promise.all([
this.waitForNavigation(options),
this._client.send('Page.reload')
@ -416,7 +418,7 @@ export class Page extends EventEmitter {
return response;
}
async waitForNavigation(options: { timeout?: number; waitUntil?: string | string[]; } = {}): Promise<Response | null> {
async waitForNavigation(options: { timeout?: number; waitUntil?: string | string[]; } = {}): Promise<network.Response | null> {
return await this._frameManager.mainFrame().waitForNavigation(options);
}
@ -439,7 +441,7 @@ export class Page extends EventEmitter {
}, timeout, this._sessionClosePromise());
}
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<Response> {
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } = {}): Promise<network.Response> {
const {
timeout = this._timeoutSettings.timeout(),
} = options;
@ -452,15 +454,15 @@ export class Page extends EventEmitter {
}, timeout, this._sessionClosePromise());
}
async goBack(options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<Response | null> {
async goBack(options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<network.Response | null> {
return this._go(-1, options);
}
async goForward(options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<Response | null> {
async goForward(options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<network.Response | null> {
return this._go(+1, options);
}
async _go(delta, options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<Response | null> {
async _go(delta, options: { timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<network.Response | null> {
const history = await this._client.send('Page.getNavigationHistory');
const entry = history.entries[history.currentIndex + delta];
if (!entry)
@ -512,7 +514,7 @@ export class Page extends EventEmitter {
return this._viewport;
}
evaluate: types.Evaluate<JSHandle> = (pageFunction, ...args) => {
evaluate: types.Evaluate = (pageFunction, ...args) => {
return this._frameManager.mainFrame().evaluate(pageFunction, ...args as any);
}
@ -660,7 +662,7 @@ export class Page extends EventEmitter {
return this.mainFrame().type(selector, text, options);
}
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string | number; } = {}, ...args: any[]): Promise<JSHandle> {
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string | number; } = {}, ...args: any[]): Promise<js.JSHandle> {
return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
}
@ -675,7 +677,7 @@ export class Page extends EventEmitter {
waitForFunction(pageFunction: Function, options: {
polling?: string | number;
timeout?: number; } = {},
...args: any[]): Promise<JSHandle> {
...args: any[]): Promise<js.JSHandle> {
return this.mainFrame().waitForFunction(pageFunction, options, ...args);
}
}
@ -704,10 +706,10 @@ type ConsoleMessageLocation = {
export class ConsoleMessage {
private _type: string;
private _text: string;
private _args: JSHandle[];
private _args: js.JSHandle[];
private _location: any;
constructor(type: string, text: string, args: JSHandle[], location: ConsoleMessageLocation = {}) {
constructor(type: string, text: string, args: js.JSHandle[], location: ConsoleMessageLocation = {}) {
this._type = type;
this._text = text;
this._args = args;
@ -722,7 +724,7 @@ export class ConsoleMessage {
return this._text;
}
args(): JSHandle[] {
args(): js.JSHandle[] {
return this._args;
}

Просмотреть файл

@ -1,7 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { NetworkManager, Request, toInterceptableRequest } from '../NetworkManager';
import { NetworkManager, toInterceptableRequest } from '../NetworkManager';
import * as network from '../../network';
export class Interception {
private _networkManager: NetworkManager;
@ -18,15 +19,15 @@ export class Interception {
await this._networkManager.setRequestInterception(false);
}
async continue(request: Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
async continue(request: network.Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
return toInterceptableRequest(request).continue(overrides);
}
async fulfill(request: Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
async fulfill(request: network.Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
return toInterceptableRequest(request).fulfill(response);
}
async abort(request: Request, errorCode: string = 'failed') {
async abort(request: network.Request, errorCode: string = 'failed') {
return toInterceptableRequest(request).abort(errorCode);
}

Просмотреть файл

@ -21,10 +21,10 @@ import { Protocol } from '../protocol';
import { Events } from '../events';
import * as types from '../../types';
import * as js from '../../javascript';
import { JSHandle, ExecutionContext, ExecutionContextDelegate } from '../ExecutionContext';
import { ExecutionContextDelegate } from '../ExecutionContext';
import { createJSHandle } from '../JSHandle';
type AddToConsoleCallback = (type: string, args: JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) => void;
type AddToConsoleCallback = (type: string, args: js.JSHandle[], stackTrace: Protocol.Runtime.StackTrace | undefined) => void;
type HandleExceptionCallback = (exceptionDetails: Protocol.Runtime.ExceptionDetails) => void;
export class Workers extends EventEmitter {
@ -58,15 +58,15 @@ export class Workers extends EventEmitter {
export class Worker extends EventEmitter {
private _client: CDPSession;
private _url: string;
private _executionContextPromise: Promise<ExecutionContext>;
private _executionContextCallback: (value?: ExecutionContext) => void;
private _executionContextPromise: Promise<js.ExecutionContext>;
private _executionContextCallback: (value?: js.ExecutionContext) => void;
constructor(client: CDPSession, url: string, addToConsole: AddToConsoleCallback, handleException: HandleExceptionCallback) {
super();
this._client = client;
this._url = url;
this._executionContextPromise = new Promise(x => this._executionContextCallback = x);
let jsHandleFactory: (o: Protocol.Runtime.RemoteObject) => JSHandle;
let jsHandleFactory: (o: Protocol.Runtime.RemoteObject) => js.JSHandle;
this._client.once('Runtime.executionContextCreated', async event => {
jsHandleFactory = remoteObject => createJSHandle(executionContext, remoteObject);
const executionContext = new js.ExecutionContext(new ExecutionContextDelegate(client, event.context), null);
@ -83,15 +83,15 @@ export class Worker extends EventEmitter {
return this._url;
}
async executionContext(): Promise<ExecutionContext> {
async executionContext(): Promise<js.ExecutionContext> {
return this._executionContextPromise;
}
evaluate: types.Evaluate<JSHandle> = async (pageFunction, ...args) => {
evaluate: types.Evaluate = async (pageFunction, ...args) => {
return (await this._executionContextPromise).evaluate(pageFunction, ...args as any);
}
evaluateHandle: types.EvaluateHandle<JSHandle> = async (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
return (await this._executionContextPromise).evaluateHandle(pageFunction, ...args as any);
}
}

Просмотреть файл

@ -2,24 +2,21 @@
// Licensed under the MIT license.
import * as frames from './frames';
import * as types from './types';
import * as js from './javascript';
import * as input from './input';
import { assert, helper } from './helper';
import Injected from './injected/injected';
import * as input from './input';
import * as js from './javascript';
import * as types from './types';
export type Rect = { x: number, y: number, width: number, height: number };
export type Point = { x: number, y: number };
type SelectorRoot = Element | ShadowRoot | Document;
export interface DOMWorldDelegate {
isJavascriptEnabled(): boolean;
contentFrame(handle: ElementHandle): Promise<frames.Frame | null>;
boundingBox(handle: ElementHandle): Promise<Rect | null>;
boundingBox(handle: ElementHandle): Promise<types.Rect | null>;
screenshot(handle: ElementHandle, options?: any): Promise<string | Buffer>;
ensurePointerActionPoint(handle: ElementHandle, relativePoint?: Point): Promise<Point>;
ensurePointerActionPoint(handle: ElementHandle, relativePoint?: types.Point): Promise<types.Point>;
setInputFiles(handle: ElementHandle, files: input.FilePayload[]): Promise<void>;
// await this.evaluate(input.setFileInputFunction, );
}
export class ElementHandle extends js.JSHandle {
@ -71,7 +68,7 @@ export class ElementHandle extends js.JSHandle {
throw new Error(error);
}
async _performPointerAction(action: (point: Point) => Promise<void>, options?: input.PointerActionOptions): Promise<void> {
async _performPointerAction(action: (point: types.Point) => Promise<void>, options?: input.PointerActionOptions): Promise<void> {
const point = await this._delegate.ensurePointerActionPoint(this, options ? options.relativePoint : undefined);
let restoreModifiers: input.Modifier[] | undefined;
if (options && options.modifiers)
@ -141,7 +138,7 @@ export class ElementHandle extends js.JSHandle {
await this._keyboard.press(key, options);
}
async boundingBox(): Promise<Rect | null> {
async boundingBox(): Promise<types.Rect | null> {
return this._delegate.boundingBox(this);
}
@ -177,7 +174,7 @@ export class ElementHandle extends js.JSHandle {
return result;
}
$eval: types.$Eval<js.JSHandle> = async (selector, pageFunction, ...args) => {
$eval: types.$Eval = async (selector, pageFunction, ...args) => {
const elementHandle = await this.$(selector);
if (!elementHandle)
throw new Error(`Error: failed to find element matching selector "${selector}"`);
@ -186,7 +183,7 @@ export class ElementHandle extends js.JSHandle {
return result;
}
$$eval: types.$$Eval<js.JSHandle> = async (selector, pageFunction, ...args) => {
$$eval: types.$$Eval = async (selector, pageFunction, ...args) => {
const arrayHandle = await this.evaluateHandle(
(root: SelectorRoot, selector: string, injected: Injected) => injected.querySelectorAll('css=' + selector, root),
selector, await this._context._injected()

Просмотреть файл

@ -20,9 +20,6 @@ import { createHandle } from './JSHandle';
import * as js from '../javascript';
import { JugglerSession } from './Connection';
export type ExecutionContext = js.ExecutionContext;
export type JSHandle = js.JSHandle;
export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
_session: JugglerSession;
_executionContextId: string;
@ -32,7 +29,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
this._executionContextId = executionContextId;
}
async evaluate(context: ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
async evaluate(context: js.ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
if (returnByValue) {
try {
const handle = await this.evaluate(context, false /* returnByValue */, pageFunction, ...args as any);
@ -113,7 +110,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
}
}
async getProperties(handle: JSHandle): Promise<Map<string, JSHandle>> {
async getProperties(handle: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._session.send('Runtime.getObjectProperties', {
executionContextId: this._executionContextId,
objectId: toPayload(handle).objectId,
@ -124,7 +121,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return result;
}
async releaseHandle(handle: JSHandle): Promise<void> {
async releaseHandle(handle: js.JSHandle): Promise<void> {
await this._session.send('Runtime.disposeObject', {
executionContextId: this._executionContextId,
objectId: toPayload(handle).objectId,
@ -135,7 +132,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
});
}
async handleJSONValue(handle: JSHandle): Promise<any> {
async handleJSONValue(handle: js.JSHandle): Promise<any> {
const payload = toPayload(handle);
if (!payload.objectId)
return deserializeValue(payload);
@ -148,7 +145,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return deserializeValue(simpleValue.result);
}
handleToString(handle: JSHandle): string {
handleToString(handle: js.JSHandle): string {
const payload = toPayload(handle);
if (payload.objectId)
return 'JSHandle@' + (payload.subtype || payload.type);
@ -162,11 +159,11 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
const payloadSymbol = Symbol('payload');
export function toPayload(handle: JSHandle): any {
export function toPayload(handle: js.JSHandle): any {
return (handle as any)[payloadSymbol];
}
export function markJSHandle(handle: JSHandle, payload: any) {
export function markJSHandle(handle: js.JSHandle, payload: any) {
(handle as any)[payloadSymbol] = payload;
}

Просмотреть файл

@ -23,9 +23,10 @@ import * as js from '../javascript';
import * as dom from '../dom';
import { TimeoutSettings } from '../TimeoutSettings';
import { JugglerSession } from './Connection';
import { ExecutionContext, ExecutionContextDelegate } from './ExecutionContext';
import { ExecutionContextDelegate } from './ExecutionContext';
import { NavigationWatchdog, NextNavigationWatchdog } from './NavigationWatchdog';
import { Page } from './Page';
import { NetworkManager } from './NetworkManager';
export const FrameManagerEvents = {
FrameNavigated: Symbol('FrameManagerEvents.FrameNavigated'),
@ -42,16 +43,14 @@ type FrameData = {
firedEvents: Set<string>,
};
export type Frame = frames.Frame;
export class FrameManager extends EventEmitter implements frames.FrameDelegate {
_session: JugglerSession;
_page: Page;
_networkManager: any;
_timeoutSettings: any;
_mainFrame: Frame;
_frames: Map<string, Frame>;
_contextIdToContext: Map<string, ExecutionContext>;
_networkManager: NetworkManager;
_timeoutSettings: TimeoutSettings;
_mainFrame: frames.Frame;
_frames: Map<string, frames.Frame>;
_contextIdToContext: Map<string, js.ExecutionContext>;
_eventListeners: RegisteredListener[];
constructor(session: JugglerSession, page: Page, networkManager, timeoutSettings) {
@ -98,24 +97,24 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
context.frame()._contextDestroyed(context);
}
_frameData(frame: Frame): FrameData {
_frameData(frame: frames.Frame): FrameData {
return (frame as any)[frameDataSymbol];
}
frame(frameId: string): Frame {
frame(frameId: string): frames.Frame {
return this._frames.get(frameId);
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._mainFrame;
}
frames() {
const frames: Array<Frame> = [];
const frames: Array<frames.Frame> = [];
collect(this._mainFrame);
return frames;
function collect(frame: Frame) {
function collect(frame: frames.Frame) {
frames.push(frame);
for (const subframe of frame.childFrames())
collect(subframe);
@ -139,7 +138,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
_onFrameAttached(params) {
const parentFrame = this._frames.get(params.parentFrameId) || null;
const frame = new frames.Frame(this, parentFrame);
const frame = new frames.Frame(this, this._timeoutSettings, parentFrame);
const data: FrameData = {
frameId: params.frameId,
lastCommittedNavigationId: '',
@ -176,16 +175,12 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
helper.removeEventListeners(this._eventListeners);
}
timeoutSettings(): TimeoutSettings {
return this._timeoutSettings;
}
async adoptElementHandle(elementHandle: dom.ElementHandle, context: ExecutionContext): Promise<dom.ElementHandle> {
async adoptElementHandle(elementHandle: dom.ElementHandle, context: js.ExecutionContext): Promise<dom.ElementHandle> {
assert(false, 'Multiple isolated worlds are not implemented');
return elementHandle;
}
async waitForFrameNavigation(frame: Frame, options: { timeout?: number; waitUntil?: string | Array<string>; } = {}) {
async waitForFrameNavigation(frame: frames.Frame, options: { timeout?: number; waitUntil?: string | Array<string>; } = {}) {
const {
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
@ -230,7 +225,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return watchDog.navigationResponse();
}
async navigateFrame(frame: Frame, url: string, options: { timeout?: number; waitUntil?: string | Array<string>; referer?: string; } = {}) {
async navigateFrame(frame: frames.Frame, url: string, options: { timeout?: number; waitUntil?: string | Array<string>; referer?: string; } = {}) {
const {
timeout = this._timeoutSettings.navigationTimeout(),
waitUntil = ['load'],
@ -262,7 +257,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return watchDog.navigationResponse();
}
async setFrameContent(frame: Frame, html: string) {
async setFrameContent(frame: frames.Frame, html: string) {
const context = await frame._utilityContext();
await context.evaluate(html => {
document.open();

Просмотреть файл

@ -19,9 +19,11 @@ import { assert, debugError } from '../helper';
import * as js from '../javascript';
import * as dom from '../dom';
import * as input from '../input';
import * as types from '../types';
import * as frames from '../frames';
import { JugglerSession } from './Connection';
import { Frame, FrameManager } from './FrameManager';
import { ExecutionContext, markJSHandle, ExecutionContextDelegate, toPayload } from './ExecutionContext';
import { FrameManager } from './FrameManager';
import { markJSHandle, ExecutionContextDelegate, toPayload } from './ExecutionContext';
class DOMWorldDelegate implements dom.DOMWorldDelegate {
private _session: JugglerSession;
@ -34,7 +36,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
this._frameId = frameId;
}
async contentFrame(handle: dom.ElementHandle): Promise<Frame|null> {
async contentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null> {
const {frameId} = await this._session.send('Page.contentFrame', {
frameId: this._frameId,
objectId: toPayload(handle).objectId,
@ -49,7 +51,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return this._frameManager._page._javascriptEnabled;
}
async boundingBox(handle: dom.ElementHandle): Promise<dom.Rect | null> {
async boundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
return await this._session.send('Page.getBoundingBox', {
frameId: this._frameId,
objectId: toPayload(handle).objectId,
@ -77,7 +79,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
}));
}
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: dom.Point): Promise<dom.Point> {
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: types.Point): Promise<types.Point> {
await handle._scrollIntoViewIfNeeded();
if (!relativePoint)
return this._clickablePoint(handle);
@ -85,8 +87,8 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return { x: box.x + relativePoint.x, y: box.y + relativePoint.y };
}
private async _clickablePoint(handle: dom.ElementHandle): Promise<dom.Point> {
type Quad = {p1: dom.Point, p2: dom.Point, p3: dom.Point, p4: dom.Point};
private async _clickablePoint(handle: dom.ElementHandle): Promise<types.Point> {
type Quad = {p1: types.Point, p2: types.Point, p3: types.Point, p4: types.Point};
const computeQuadArea = (quad: Quad) => {
// Compute sum of all directed areas of adjacent triangles
@ -129,7 +131,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
}
}
export function createHandle(context: ExecutionContext, result: any, exceptionDetails?: any) {
export function createHandle(context: js.ExecutionContext, result: any, exceptionDetails?: any) {
if (exceptionDetails) {
if (exceptionDetails.value)
throw new Error('Evaluation failed: ' + JSON.stringify(exceptionDetails.value));

Просмотреть файл

@ -1,17 +1,35 @@
/**
* Copyright 2019 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { helper, RegisteredListener } from '../helper';
import { JugglerSessionEvents } from './Connection';
import { Frame, FrameManagerEvents, FrameManager } from './FrameManager';
import { FrameManagerEvents, FrameManager } from './FrameManager';
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
import * as frames from '../frames';
export class NextNavigationWatchdog {
private _frameManager: FrameManager;
private _navigatedFrame: Frame;
private _navigatedFrame: frames.Frame;
private _promise: Promise<unknown>;
private _resolveCallback: (value?: unknown) => void;
private _navigation: {navigationId: number|null, url?: string} = null;
private _eventListeners: RegisteredListener[];
constructor(frameManager: FrameManager, navigatedFrame: Frame) {
constructor(frameManager: FrameManager, navigatedFrame: frames.Frame) {
this._frameManager = frameManager;
this._navigatedFrame = navigatedFrame;
this._promise = new Promise(x => this._resolveCallback = x);
@ -55,7 +73,7 @@ export class NextNavigationWatchdog {
export class NavigationWatchdog {
private _frameManager: FrameManager;
private _navigatedFrame: Frame;
private _navigatedFrame: frames.Frame;
private _targetNavigationId: any;
private _firedEvents: any;
private _targetURL: any;
@ -64,7 +82,7 @@ export class NavigationWatchdog {
private _navigationRequest: any;
private _eventListeners: RegisteredListener[];
constructor(frameManager: FrameManager, navigatedFrame: Frame, networkManager: NetworkManager, targetNavigationId, targetURL, firedEvents) {
constructor(frameManager: FrameManager, navigatedFrame: frames.Frame, networkManager: NetworkManager, targetNavigationId, targetURL, firedEvents) {
this._frameManager = frameManager;
this._navigatedFrame = navigatedFrame;
this._targetNavigationId = targetNavigationId;
@ -100,7 +118,7 @@ export class NavigationWatchdog {
}
_checkNavigationComplete() {
const checkFiredEvents = (frame: Frame, firedEvents) => {
const checkFiredEvents = (frame: frames.Frame, firedEvents) => {
for (const subframe of frame.childFrames()) {
if (!checkFiredEvents(subframe, firedEvents))
return false;

Просмотреть файл

@ -18,11 +18,9 @@
import { EventEmitter } from 'events';
import { assert, debugError, helper, RegisteredListener } from '../helper';
import { JugglerSession } from './Connection';
import { FrameManager, Frame } from './FrameManager';
import { FrameManager } from './FrameManager';
import * as network from '../network';
export type Request = network.Request;
export type Response = network.Response;
import * as frames from '../frames';
export const NetworkManagerEvents = {
RequestFailed: Symbol('NetworkManagerEvents.RequestFailed'),
@ -78,7 +76,7 @@ export class NetworkManager extends EventEmitter {
const frame = redirected ? redirected.request.frame() : (this._frameManager && event.frameId ? this._frameManager.frame(event.frameId) : null);
if (!frame)
return;
let redirectChain: Request[] = [];
let redirectChain: network.Request[] = [];
if (redirected) {
redirectChain = redirected.request._redirectChain;
redirectChain.push(redirected.request);
@ -170,13 +168,13 @@ export function toInterceptableRequest(request: network.Request): InterceptableR
}
class InterceptableRequest {
readonly request: Request;
readonly request: network.Request;
_id: string;
private _session: JugglerSession;
private _suspended: boolean;
private _interceptionHandled: boolean;
constructor(session: JugglerSession, frame: Frame, redirectChain: Request[], payload: any) {
constructor(session: JugglerSession, frame: frames.Frame, redirectChain: network.Request[], payload: any) {
this._id = payload.requestId;
this._session = session;
this._suspended = payload.suspended;

Просмотреть файл

@ -1,3 +1,20 @@
/**
* Copyright 2019 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { EventEmitter } from 'events';
import * as fs from 'fs';
import * as mime from 'mime';
@ -10,15 +27,18 @@ import { Dialog } from './Dialog';
import { Events } from './events';
import { Accessibility } from './features/accessibility';
import { Interception } from './features/interception';
import { FrameManager, FrameManagerEvents, normalizeWaitUntil, Frame } from './FrameManager';
import { FrameManager, FrameManagerEvents, normalizeWaitUntil } from './FrameManager';
import { RawMouseImpl, RawKeyboardImpl } from './Input';
import { createHandle } from './JSHandle';
import { NavigationWatchdog } from './NavigationWatchdog';
import { NetworkManager, NetworkManagerEvents, Request, Response } from './NetworkManager';
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
import * as input from '../input';
import * as types from '../types';
import * as dom from '../dom';
import { JSHandle, toPayload, deserializeValue } from './ExecutionContext';
import * as js from '../javascript';
import * as network from '../network';
import * as frames from '../frames';
import { toPayload, deserializeValue } from './ExecutionContext';
const writeFileAsync = helper.promisify(fs.writeFile);
@ -172,7 +192,7 @@ export class Page extends EventEmitter {
return this._disconnectPromise;
}
async waitForRequest(urlOrPredicate: (string | Function), options: { timeout?: number; } | undefined = {}): Promise<Request> {
async waitForRequest(urlOrPredicate: (string | Function), options: { timeout?: number; } | undefined = {}): Promise<network.Request> {
const {
timeout = this._timeoutSettings.timeout(),
} = options;
@ -185,7 +205,7 @@ export class Page extends EventEmitter {
}, timeout, this._sessionClosePromise());
}
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } | undefined = {}): Promise<Response> {
async waitForResponse(urlOrPredicate: (string | Function), options: { timeout?: number; } | undefined = {}): Promise<network.Response> {
const {
timeout = this._timeoutSettings.timeout(),
} = options;
@ -288,7 +308,7 @@ export class Page extends EventEmitter {
this.emit(Events.Page.Dialog, new Dialog(this._session, params));
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._frameManager.mainFrame();
}
@ -420,7 +440,7 @@ export class Page extends EventEmitter {
}
}
evaluate: types.Evaluate<JSHandle> = (pageFunction, ...args) => {
evaluate: types.Evaluate = (pageFunction, ...args) => {
return this.mainFrame().evaluate(pageFunction, ...args as any);
}
@ -464,11 +484,11 @@ export class Page extends EventEmitter {
return this._frameManager.mainFrame().hover(selector);
}
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { polling?: string | number; timeout?: number; visible?: boolean; hidden?: boolean; } | undefined = {}, ...args: Array<any>): Promise<JSHandle> {
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { polling?: string | number; timeout?: number; visible?: boolean; hidden?: boolean; } | undefined = {}, ...args: Array<any>): Promise<js.JSHandle> {
return this._frameManager.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
}
waitForFunction(pageFunction: Function | string, options: { polling?: string | number; timeout?: number; } | undefined = {}, ...args): Promise<JSHandle> {
waitForFunction(pageFunction: Function | string, options: { polling?: string | number; timeout?: number; } | undefined = {}, ...args): Promise<js.JSHandle> {
return this._frameManager.mainFrame().waitForFunction(pageFunction, options, ...args);
}
@ -492,11 +512,11 @@ export class Page extends EventEmitter {
return this._frameManager.mainFrame().$$(selector);
}
$eval: types.$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$eval: types.$Eval = (selector, pageFunction, ...args) => {
return this._frameManager.mainFrame().$eval(selector, pageFunction, ...args as any);
}
$$eval: types.$$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$$eval: types.$$Eval = (selector, pageFunction, ...args) => {
return this._frameManager.mainFrame().$$eval(selector, pageFunction, ...args as any);
}
@ -504,7 +524,7 @@ export class Page extends EventEmitter {
return this._frameManager.mainFrame().$x(expression);
}
evaluateHandle: types.EvaluateHandle<JSHandle> = async (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
return this._frameManager.mainFrame().evaluateHandle(pageFunction, ...args as any);
}
@ -564,10 +584,10 @@ export class Page extends EventEmitter {
export class ConsoleMessage {
private _type: string;
private _args: JSHandle[];
private _args: js.JSHandle[];
private _location: any;
constructor(type: string, args: Array<JSHandle>, location) {
constructor(type: string, args: Array<js.JSHandle>, location) {
this._type = type;
this._args = args;
this._location = location;
@ -581,7 +601,7 @@ export class ConsoleMessage {
return this._type;
}
args(): Array<JSHandle> {
args(): Array<js.JSHandle> {
return this._args;
}

Просмотреть файл

@ -1,7 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { NetworkManager, Request, toInterceptableRequest } from '../NetworkManager';
import { NetworkManager, toInterceptableRequest } from '../NetworkManager';
import * as network from '../../network';
export class Interception {
private _networkManager: NetworkManager;
@ -18,15 +19,15 @@ export class Interception {
await this._networkManager.setRequestInterception(false);
}
async continue(request: Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
async continue(request: network.Request, overrides: { url?: string; method?: string; postData?: string; headers?: {[key: string]: string}; } = {}) {
return toInterceptableRequest(request).continue(overrides);
}
async fulfill(request: Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
async fulfill(request: network.Request, response: { status: number; headers: {[key: string]: string}; contentType: string; body: (string | Buffer); }) {
throw new Error('Not implemented');
}
async abort(request: Request, errorCode: string = 'failed') {
async abort(request: network.Request, errorCode: string = 'failed') {
return toInterceptableRequest(request).abort();
}
}

Просмотреть файл

@ -45,7 +45,6 @@ export type GotoOptions = NavigateOptions & {
};
export interface FrameDelegate {
timeoutSettings(): TimeoutSettings;
navigateFrame(frame: Frame, url: string, options?: GotoOptions): Promise<network.Response | null>;
waitForFrameNavigation(frame: Frame, options?: NavigateOptions): Promise<network.Response | null>;
setFrameContent(frame: Frame, html: string, options?: NavigateOptions): Promise<void>;
@ -54,6 +53,7 @@ export interface FrameDelegate {
export class Frame {
_delegate: FrameDelegate;
private _timeoutSettings: TimeoutSettings;
private _parentFrame: Frame;
private _url = '';
private _detached = false;
@ -61,8 +61,9 @@ export class Frame {
private _childFrames = new Set<Frame>();
private _name: string;
constructor(delegate: FrameDelegate, parentFrame: Frame | null) {
constructor(delegate: FrameDelegate, timeoutSettings: TimeoutSettings, parentFrame: Frame | null) {
this._delegate = delegate;
this._timeoutSettings = timeoutSettings;
this._parentFrame = parentFrame;
this._worlds.set('main', { contextPromise: new Promise(() => {}), contextResolveCallback: () => {}, context: null, waitTasks: new Set() });
@ -98,12 +99,12 @@ export class Frame {
return this._mainContext();
}
evaluateHandle: types.EvaluateHandle<js.JSHandle> = async (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
const context = await this._mainContext();
return context.evaluateHandle(pageFunction, ...args as any);
}
evaluate: types.Evaluate<js.JSHandle> = async (pageFunction, ...args) => {
evaluate: types.Evaluate = async (pageFunction, ...args) => {
const context = await this._mainContext();
return context.evaluate(pageFunction, ...args as any);
}
@ -120,13 +121,13 @@ export class Frame {
return document.$x(expression);
}
$eval: types.$Eval<js.JSHandle> = async (selector, pageFunction, ...args) => {
$eval: types.$Eval = async (selector, pageFunction, ...args) => {
const context = await this._mainContext();
const document = await context._document();
return document.$eval(selector, pageFunction, ...args as any);
}
$$eval: types.$$Eval<js.JSHandle> = async (selector, pageFunction, ...args) => {
$$eval: types.$$Eval = async (selector, pageFunction, ...args) => {
const context = await this._mainContext();
const document = await context._document();
return document.$$eval(selector, pageFunction, ...args as any);
@ -390,7 +391,7 @@ export class Frame {
visible?: boolean;
hidden?: boolean;
timeout?: number; } | undefined): Promise<dom.ElementHandle | null> {
const params = waitForSelectorOrXPath(selector, false /* isXPath */, { timeout: this._delegate.timeoutSettings().timeout(), ...options });
const params = waitForSelectorOrXPath(selector, false /* isXPath */, { timeout: this._timeoutSettings.timeout(), ...options });
const handle = await this._scheduleWaitTask(params, this._worlds.get('utility'));
if (!handle.asElement()) {
await handle.dispose();
@ -404,7 +405,7 @@ export class Frame {
visible?: boolean;
hidden?: boolean;
timeout?: number; } | undefined): Promise<dom.ElementHandle | null> {
const params = waitForSelectorOrXPath(xpath, true /* isXPath */, { timeout: this._delegate.timeoutSettings().timeout(), ...options });
const params = waitForSelectorOrXPath(xpath, true /* isXPath */, { timeout: this._timeoutSettings.timeout(), ...options });
const handle = await this._scheduleWaitTask(params, this._worlds.get('utility'));
if (!handle.asElement()) {
await handle.dispose();
@ -420,7 +421,7 @@ export class Frame {
...args): Promise<js.JSHandle> {
const {
polling = 'raf',
timeout = this._delegate.timeoutSettings().timeout(),
timeout = this._timeoutSettings.timeout(),
} = options;
const params: WaitTaskParams = {
predicateBody: pageFunction,

Просмотреть файл

@ -4,20 +4,17 @@
import * as fs from 'fs';
import * as path from 'path';
import { assert, helper } from './helper';
import * as types from './types';
import * as keyboardLayout from './USKeyboardLayout';
const readFileAsync = helper.promisify(fs.readFile);
export type Modifier = 'Alt' | 'Control' | 'Meta' | 'Shift';
export type Button = 'left' | 'right' | 'middle';
type Point = {
x: number;
y: number;
};
export type PointerActionOptions = {
modifiers?: Modifier[];
relativePoint?: Point;
relativePoint?: types.Point;
};
export type ClickOptions = PointerActionOptions & {

Просмотреть файл

@ -31,11 +31,11 @@ export class ExecutionContext {
return this._frame;
}
evaluate: types.Evaluate<JSHandle> = (pageFunction, ...args) => {
evaluate: types.Evaluate = (pageFunction, ...args) => {
return this._delegate.evaluate(this, true /* returnByValue */, pageFunction, ...args);
}
evaluateHandle: types.EvaluateHandle<JSHandle> = (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = (pageFunction, ...args) => {
return this._delegate.evaluate(this, false /* returnByValue */, pageFunction, ...args);
}
@ -71,11 +71,11 @@ export class JSHandle {
return this._context;
}
evaluate: types.EvaluateOn<JSHandle> = (pageFunction, ...args) => {
evaluate: types.EvaluateOn = (pageFunction, ...args) => {
return this._context.evaluate(pageFunction, this, ...args);
}
evaluateHandle: types.EvaluateHandleOn<JSHandle> = (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandleOn = (pageFunction, ...args) => {
return this._context.evaluateHandle(pageFunction, this, ...args);
}

Просмотреть файл

@ -1,13 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
type Boxed<Args extends any[], Handle> = { [Index in keyof Args]: Args[Index] | Handle };
import * as js from './javascript';
type Boxed<Args extends any[]> = { [Index in keyof Args]: Args[Index] | js.JSHandle };
type PageFunction<Args extends any[], R = any> = string | ((...args: Args) => R | Promise<R>);
type PageFunctionOn<On, Args extends any[], R = any> = string | ((on: On, ...args: Args) => R | Promise<R>);
export type Evaluate<Handle> = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args, Handle>) => Promise<R>;
export type EvaluateHandle<Handle> = <Args extends any[]>(pageFunction: PageFunction<Args>, ...args: Boxed<Args, Handle>) => Promise<Handle>;
export type $Eval<Handle> = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element, Args, R>, ...args: Boxed<Args, Handle>) => Promise<R>;
export type $$Eval<Handle> = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element[], Args, R>, ...args: Boxed<Args, Handle>) => Promise<R>;
export type EvaluateOn<Handle> = <Args extends any[], R>(pageFunction: PageFunctionOn<any, Args, R>, ...args: Boxed<Args, Handle>) => Promise<R>;
export type EvaluateHandleOn<Handle> = <Args extends any[]>(pageFunction: PageFunctionOn<any, Args>, ...args: Boxed<Args, Handle>) => Promise<Handle>;
export type Evaluate = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args>) => Promise<R>;
export type EvaluateHandle = <Args extends any[]>(pageFunction: PageFunction<Args>, ...args: Boxed<Args>) => Promise<js.JSHandle>;
export type $Eval = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element, Args, R>, ...args: Boxed<Args>) => Promise<R>;
export type $$Eval = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element[], Args, R>, ...args: Boxed<Args>) => Promise<R>;
export type EvaluateOn = <Args extends any[], R>(pageFunction: PageFunctionOn<any, Args, R>, ...args: Boxed<Args>) => Promise<R>;
export type EvaluateHandleOn = <Args extends any[]>(pageFunction: PageFunctionOn<any, Args>, ...args: Boxed<Args>) => Promise<js.JSHandle>;
export type Rect = { x: number, y: number, width: number, height: number };
export type Point = { x: number, y: number };

Просмотреть файл

@ -25,9 +25,6 @@ import * as js from '../javascript';
export const EVALUATION_SCRIPT_URL = '__playwright_evaluation_script__';
const SOURCE_URL_REGEX = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
export type ExecutionContext = js.ExecutionContext;
export type JSHandle = js.JSHandle;
export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
private _globalObjectId?: string;
_session: TargetSession;
@ -48,7 +45,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
this._contextDestroyedCallback();
}
async evaluate(context: ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
async evaluate(context: js.ExecutionContext, returnByValue: boolean, pageFunction: Function | string, ...args: any[]): Promise<any> {
const suffix = `//# sourceURL=${EVALUATION_SCRIPT_URL}`;
if (helper.isString(pageFunction)) {
@ -275,7 +272,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return this._globalObjectId;
}
async getProperties(handle: JSHandle): Promise<Map<string, JSHandle>> {
async getProperties(handle: js.JSHandle): Promise<Map<string, js.JSHandle>> {
const response = await this._session.send('Runtime.getProperties', {
objectId: toRemoteObject(handle).objectId,
ownProperties: true
@ -289,11 +286,11 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return result;
}
async releaseHandle(handle: JSHandle): Promise<void> {
async releaseHandle(handle: js.JSHandle): Promise<void> {
await releaseObject(this._session, toRemoteObject(handle));
}
async handleJSONValue(handle: JSHandle): Promise<any> {
async handleJSONValue(handle: js.JSHandle): Promise<any> {
const remoteObject = toRemoteObject(handle);
if (remoteObject.objectId) {
const response = await this._session.send('Runtime.callFunctionOn', {
@ -306,7 +303,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return valueFromRemoteObject(remoteObject);
}
handleToString(handle: JSHandle): string {
handleToString(handle: js.JSHandle): string {
const object = toRemoteObject(handle);
if (object.objectId) {
let type: string = object.subtype || object.type;
@ -318,7 +315,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
return 'JSHandle:' + valueFromRemoteObject(object);
}
private _convertArgument(arg: JSHandle | any) : Protocol.Runtime.CallArgument {
private _convertArgument(arg: js.JSHandle | any) : Protocol.Runtime.CallArgument {
const objectHandle = arg && (arg instanceof js.JSHandle) ? arg : null;
if (objectHandle) {
if (objectHandle._context._delegate !== this)
@ -337,10 +334,10 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
const remoteObjectSymbol = Symbol('RemoteObject');
export function toRemoteObject(handle: JSHandle): Protocol.Runtime.RemoteObject {
export function toRemoteObject(handle: js.JSHandle): Protocol.Runtime.RemoteObject {
return (handle as any)[remoteObjectSymbol];
}
export function markJSHandle(handle: JSHandle, remoteObject: Protocol.Runtime.RemoteObject) {
export function markJSHandle(handle: js.JSHandle, remoteObject: Protocol.Runtime.RemoteObject) {
(handle as any)[remoteObjectSymbol] = remoteObject;
}

Просмотреть файл

@ -21,11 +21,12 @@ import * as frames from '../frames';
import { assert, debugError, helper, RegisteredListener } from '../helper';
import * as js from '../javascript';
import * as dom from '../dom';
import * as network from '../network';
import { TimeoutSettings } from '../TimeoutSettings';
import { TargetSession } from './Connection';
import { Events } from './events';
import { ExecutionContext, ExecutionContextDelegate } from './ExecutionContext';
import { NetworkManager, NetworkManagerEvents, Request, Response } from './NetworkManager';
import { ExecutionContextDelegate } from './ExecutionContext';
import { NetworkManager, NetworkManagerEvents } from './NetworkManager';
import { Page } from './Page';
import { Protocol } from './protocol';
@ -42,18 +43,16 @@ type FrameData = {
id: string,
};
export type Frame = frames.Frame;
export class FrameManager extends EventEmitter implements frames.FrameDelegate {
_session: TargetSession;
_page: Page;
_networkManager: NetworkManager;
_timeoutSettings: TimeoutSettings;
_frames: Map<string, Frame>;
_contextIdToContext: Map<number, ExecutionContext>;
_frames: Map<string, frames.Frame>;
_contextIdToContext: Map<number, js.ExecutionContext>;
_isolatedWorlds: Set<string>;
_sessionListeners: RegisteredListener[];
_mainFrame: Frame;
_mainFrame: frames.Frame;
constructor(session: TargetSession, page: Page, timeoutSettings: TimeoutSettings) {
super();
@ -134,19 +133,19 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return this._page;
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._mainFrame;
}
frames(): Array<Frame> {
frames(): Array<frames.Frame> {
return Array.from(this._frames.values());
}
frame(frameId: string): Frame | null {
frame(frameId: string): frames.Frame | null {
return this._frames.get(frameId) || null;
}
_frameData(frame: Frame): FrameData {
_frameData(frame: frames.Frame): FrameData {
return (frame as any)[frameDataSymbol];
}
@ -155,7 +154,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return;
assert(parentFrameId);
const parentFrame = this._frames.get(parentFrameId);
const frame = new frames.Frame(this, parentFrame);
const frame = new frames.Frame(this, this._timeoutSettings, parentFrame);
const data: FrameData = {
id: frameId,
};
@ -182,7 +181,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
}
} else if (isMainFrame) {
// Initial frame navigation.
frame = new frames.Frame(this, null);
frame = new frames.Frame(this, this._timeoutSettings, null);
const data: FrameData = {
id: framePayload.id,
};
@ -236,7 +235,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
const frame = this._frames.get(frameId) || null;
if (!frame)
return;
const context: ExecutionContext = new js.ExecutionContext(new ExecutionContextDelegate(this._session, contextPayload), frame);
const context: js.ExecutionContext = new js.ExecutionContext(new ExecutionContextDelegate(this._session, contextPayload), frame);
if (frame) {
frame._contextCreated('main', context);
frame._contextCreated('utility', context);
@ -244,13 +243,13 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
this._contextIdToContext.set(contextPayload.id, context);
}
executionContextById(contextId: number): ExecutionContext {
executionContextById(contextId: number): js.ExecutionContext {
const context = this._contextIdToContext.get(contextId);
assert(context, 'INTERNAL ERROR: missing context with id = ' + contextId);
return context;
}
_removeFramesRecursively(frame: Frame) {
_removeFramesRecursively(frame: frames.Frame) {
for (const child of frame.childFrames())
this._removeFramesRecursively(child);
frame._detach();
@ -258,11 +257,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
this.emit(FrameManagerEvents.FrameDetached, frame);
}
timeoutSettings(): TimeoutSettings {
return this._timeoutSettings;
}
async navigateFrame(frame: Frame, url: string, options: { referer?: string; timeout?: number; waitUntil?: string | Array<string>; } | undefined = {}): Promise<Response | null> {
async navigateFrame(frame: frames.Frame, url: string, options: { referer?: string; timeout?: number; waitUntil?: string | Array<string>; } | undefined = {}): Promise<network.Response | null> {
const {
timeout = this._timeoutSettings.navigationTimeout(),
} = options;
@ -271,18 +266,18 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
return watchDog.waitForNavigation();
}
async waitForFrameNavigation(frame: Frame, options?: frames.NavigateOptions): Promise<Response | null> {
async waitForFrameNavigation(frame: frames.Frame, options?: frames.NavigateOptions): Promise<network.Response | null> {
// FIXME: this method only works for main frames.
const watchDog = new NextNavigationWatchdog(this, frame, 10000);
return watchDog.waitForNavigation();
}
async adoptElementHandle(elementHandle: dom.ElementHandle, context: ExecutionContext): Promise<dom.ElementHandle> {
async adoptElementHandle(elementHandle: dom.ElementHandle, context: js.ExecutionContext): Promise<dom.ElementHandle> {
assert(false, 'Multiple isolated worlds are not implemented');
return elementHandle;
}
async setFrameContent(frame: Frame, html: string, options: { timeout?: number; waitUntil?: string | Array<string>; } | undefined = {}) {
async setFrameContent(frame: frames.Frame, html: string, options: { timeout?: number; waitUntil?: string | Array<string>; } | undefined = {}) {
// We rely upon the fact that document.open() will trigger Page.loadEventFired.
const watchDog = new NextNavigationWatchdog(this, frame, 1000);
await frame.evaluate(html => {
@ -299,7 +294,7 @@ export class FrameManager extends EventEmitter implements frames.FrameDelegate {
*/
class NextNavigationWatchdog {
_frameManager: FrameManager;
_frame: Frame;
_frame: frames.Frame;
_newDocumentNavigationPromise: Promise<unknown>;
_newDocumentNavigationCallback: (value?: unknown) => void;
_sameDocumentNavigationPromise: Promise<unknown>;
@ -309,7 +304,7 @@ class NextNavigationWatchdog {
_timeoutPromise: Promise<unknown>;
_timeoutId: NodeJS.Timer;
constructor(frameManager: FrameManager, frame: Frame, timeout) {
constructor(frameManager: FrameManager, frame: frames.Frame, timeout) {
this._frameManager = frameManager;
this._frame = frame;
this._newDocumentNavigationPromise = new Promise(fulfill => {
@ -368,13 +363,13 @@ class NextNavigationWatchdog {
this._sameDocumentNavigationCallback();
}
_onRequest(request: Request) {
_onRequest(request: network.Request) {
if (request.frame() !== this._frame || !request.isNavigationRequest())
return;
this._navigationRequest = request;
}
navigationResponse(): Response | null {
navigationResponse(): network.Response | null {
return this._navigationRequest ? this._navigationRequest.response() : null;
}

Просмотреть файл

@ -20,15 +20,16 @@ import { debugError, helper } from '../helper';
import * as input from '../input';
import * as dom from '../dom';
import * as frames from '../frames';
import * as types from '../types';
import { TargetSession } from './Connection';
import { ExecutionContext, ExecutionContextDelegate, markJSHandle, toRemoteObject } from './ExecutionContext';
import { ExecutionContextDelegate, markJSHandle, toRemoteObject } from './ExecutionContext';
import { FrameManager } from './FrameManager';
import { Protocol } from './protocol';
import * as js from '../javascript';
const writeFileAsync = helper.promisify(fs.writeFile);
export function createJSHandle(context: ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject) {
export function createJSHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject) {
const frame = context.frame();
if (remoteObject.subtype === 'node' && frame) {
const frameManager = frame._delegate as FrameManager;
@ -57,7 +58,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return this._frameManager.page()._javascriptEnabled;
}
async boundingBox(handle: dom.ElementHandle): Promise<dom.Rect | null> {
async boundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
throw new Error('boundingBox() is not implemented');
}
@ -73,7 +74,7 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return buffer;
}
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: dom.Point): Promise<dom.Point> {
async ensurePointerActionPoint(handle: dom.ElementHandle, relativePoint?: types.Point): Promise<types.Point> {
await handle._scrollIntoViewIfNeeded();
if (!relativePoint)
return this._clickablePoint(handle);
@ -81,8 +82,8 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
return { x: box.x + relativePoint.x, y: box.y + relativePoint.y };
}
private async _clickablePoint(handle: dom.ElementHandle): Promise<dom.Point> {
const fromProtocolQuad = (quad: number[]): dom.Point[] => {
private async _clickablePoint(handle: dom.ElementHandle): Promise<types.Point> {
const fromProtocolQuad = (quad: number[]): types.Point[] => {
return [
{x: quad[0], y: quad[1]},
{x: quad[2], y: quad[3]},
@ -91,14 +92,14 @@ class DOMWorldDelegate implements dom.DOMWorldDelegate {
];
};
const intersectQuadWithViewport = (quad: dom.Point[], width: number, height: number): dom.Point[] => {
const intersectQuadWithViewport = (quad: types.Point[], width: number, height: number): types.Point[] => {
return quad.map(point => ({
x: Math.min(Math.max(point.x, 0), width),
y: Math.min(Math.max(point.y, 0), height),
}));
};
const computeQuadArea = (quad: dom.Point[]) => {
const computeQuadArea = (quad: types.Point[]) => {
// Compute sum of all directed areas of adjacent triangles
// https://en.wikipedia.org/wiki/Polygon#Simple_polygons
let area = 0;

Просмотреть файл

@ -17,10 +17,11 @@
import { EventEmitter } from 'events';
import { TargetSession } from './Connection';
import { Frame, FrameManager } from './FrameManager';
import { FrameManager } from './FrameManager';
import { assert, helper, RegisteredListener } from '../helper';
import { Protocol } from './protocol';
import * as network from '../network';
import * as frames from '../frames';
export const NetworkManagerEvents = {
Request: Symbol('Events.NetworkManager.Request'),
@ -29,9 +30,6 @@ export const NetworkManagerEvents = {
RequestFinished: Symbol('Events.NetworkManager.RequestFinished'),
};
export type Request = network.Request;
export type Response = network.Response;
export class NetworkManager extends EventEmitter {
private _sesssion: TargetSession;
private _frameManager: FrameManager;
@ -93,7 +91,7 @@ export class NetworkManager extends EventEmitter {
}
_onRequestWillBeSent(event: Protocol.Network.requestWillBeSentPayload, interceptionId: string | null) {
let redirectChain: Request[] = [];
let redirectChain: network.Request[] = [];
if (event.redirectResponse) {
const request = this._requestIdToRequest.get(event.requestId);
// If we connect late to the target, we could have missed the requestWillBeSent event.
@ -108,7 +106,7 @@ export class NetworkManager extends EventEmitter {
this.emit(NetworkManagerEvents.Request, request.request);
}
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): Response {
_createResponse(request: InterceptableRequest, responsePayload: Protocol.Network.Response): network.Response {
const remoteAddress: network.RemoteAddress = { ip: '', port: 0 };
const getResponseBody = async () => {
const response = await this._sesssion.send('Network.getResponseBody', { requestId: request._requestId });
@ -175,11 +173,11 @@ export function toInterceptableRequest(request: network.Request): InterceptableR
}
class InterceptableRequest {
readonly request: Request;
readonly request: network.Request;
_requestId: string;
_interceptionId: string;
constructor(frame: Frame | null, interceptionId: string, event: Protocol.Network.requestWillBeSentPayload, redirectChain: Request[]) {
constructor(frame: frames.Frame | null, interceptionId: string, event: Protocol.Network.requestWillBeSentPayload, redirectChain: network.Request[]) {
this._requestId = event.requestId;
// TODO(einbinder) this will fail if we are an XHR document request
const isNavigationRequest = event.type === 'Document';

Просмотреть файл

@ -24,11 +24,11 @@ import { TimeoutSettings } from '../TimeoutSettings';
import { Browser, BrowserContext } from './Browser';
import { TargetSession, TargetSessionEvents } from './Connection';
import { Events } from './events';
import { Frame, FrameManager, FrameManagerEvents } from './FrameManager';
import { FrameManager, FrameManagerEvents } from './FrameManager';
import { RawKeyboardImpl, RawMouseImpl } from './Input';
import { createJSHandle } from './JSHandle';
import { JSHandle, toRemoteObject } from './ExecutionContext';
import { NetworkManagerEvents, Response } from './NetworkManager';
import { toRemoteObject } from './ExecutionContext';
import { NetworkManagerEvents } from './NetworkManager';
import { Protocol } from './protocol';
import { valueFromRemoteObject } from './protocolHelper';
import { Target } from './Target';
@ -36,6 +36,9 @@ import { TaskQueue } from './TaskQueue';
import * as input from '../input';
import * as types from '../types';
import * as dom from '../dom';
import * as frames from '../frames';
import * as js from '../javascript';
import * as network from '../network';
import { Dialog, DialogType } from './Dialog';
const writeFileAsync = helper.promisify(fs.writeFile);
@ -195,7 +198,7 @@ export class Page extends EventEmitter {
this.emit(Events.Page.Console, new ConsoleMessage(derivedType, formattedText, handles, location));
}
mainFrame(): Frame {
mainFrame(): frames.Frame {
return this._frameManager.mainFrame();
}
@ -203,7 +206,7 @@ export class Page extends EventEmitter {
return this._keyboard;
}
frames(): Frame[] {
frames(): frames.Frame[] {
return this._frameManager.frames();
}
@ -224,16 +227,16 @@ export class Page extends EventEmitter {
return this.mainFrame().$(selector);
}
evaluateHandle: types.EvaluateHandle<JSHandle> = async (pageFunction, ...args) => {
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
const context = await this.mainFrame().executionContext();
return context.evaluateHandle(pageFunction, ...args as any);
}
$eval: types.$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$eval: types.$Eval = (selector, pageFunction, ...args) => {
return this.mainFrame().$eval(selector, pageFunction, ...args as any);
}
$$eval: types.$$Eval<JSHandle> = (selector, pageFunction, ...args) => {
$$eval: types.$$Eval = (selector, pageFunction, ...args) => {
return this.mainFrame().$$eval(selector, pageFunction, ...args as any);
}
@ -273,11 +276,11 @@ export class Page extends EventEmitter {
await this._frameManager.mainFrame().setContent(html, options);
}
async goto(url: string, options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<Response | null> {
async goto(url: string, options: { referer?: string; timeout?: number; waitUntil?: string | string[]; } | undefined): Promise<network.Response | null> {
return await this._frameManager.mainFrame().goto(url, options);
}
async reload(): Promise<Response | null> {
async reload(): Promise<network.Response | null> {
const [response] = await Promise.all([
this.waitForNavigation(),
this._session.send('Page.reload')
@ -285,7 +288,7 @@ export class Page extends EventEmitter {
return response;
}
async waitForNavigation(): Promise<Response | null> {
async waitForNavigation(): Promise<network.Response | null> {
return await this._frameManager.mainFrame().waitForNavigation();
}
@ -350,7 +353,7 @@ export class Page extends EventEmitter {
return this._viewport;
}
evaluate: types.Evaluate<JSHandle> = (pageFunction, ...args) => {
evaluate: types.Evaluate = (pageFunction, ...args) => {
return this._frameManager.mainFrame().evaluate(pageFunction, ...args as any);
}
@ -505,7 +508,7 @@ export class Page extends EventEmitter {
return this.mainFrame().type(selector, text, options);
}
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string | number; } = {}, ...args: any[]): Promise<JSHandle> {
waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string | number; } = {}, ...args: any[]): Promise<js.JSHandle> {
return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
}
@ -520,7 +523,7 @@ export class Page extends EventEmitter {
waitForFunction(pageFunction: Function, options: {
polling?: string | number;
timeout?: number; } = {},
...args: any[]): Promise<JSHandle> {
...args: any[]): Promise<js.JSHandle> {
return this.mainFrame().waitForFunction(pageFunction, options, ...args);
}
}
@ -561,10 +564,10 @@ type ConsoleMessageLocation = {
export class ConsoleMessage {
private _type: string;
private _text: string;
private _args: JSHandle[];
private _args: js.JSHandle[];
private _location: any;
constructor(type: string, text: string, args: JSHandle[], location: ConsoleMessageLocation = {}) {
constructor(type: string, text: string, args: js.JSHandle[], location: ConsoleMessageLocation = {}) {
this._type = type;
this._text = text;
this._args = args;
@ -579,7 +582,7 @@ export class ConsoleMessage {
return this._text;
}
args(): JSHandle[] {
args(): js.JSHandle[] {
return this._args;
}