chore: cleanup multiple definitions and types (#109)
This commit is contained in:
Родитель
c3393039b0
Коммит
961556a596
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
21
src/dom.ts
21
src/dom.ts
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
19
src/types.ts
19
src/types.ts
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче