chore: contain remote objects to browser-specific code
This commit is contained in:
parent
6486ac006e
commit
1282981c45
|
|
@ -26,6 +26,7 @@ import type { BidiSession } from './bidiConnection';
|
||||||
export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
private readonly _session: BidiSession;
|
private readonly _session: BidiSession;
|
||||||
readonly _target: bidi.Script.Target;
|
readonly _target: bidi.Script.Target;
|
||||||
|
private _handleFactory!: js.HandleFactory;
|
||||||
|
|
||||||
constructor(session: BidiSession, realmInfo: bidi.Script.RealmInfo) {
|
constructor(session: BidiSession, realmInfo: bidi.Script.RealmInfo) {
|
||||||
this._session = session;
|
this._session = session;
|
||||||
|
|
@ -42,6 +43,10 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHandleFactory(handleFactory: js.HandleFactory) {
|
||||||
|
this._handleFactory = handleFactory;
|
||||||
|
}
|
||||||
|
|
||||||
async rawEvaluateJSON(expression: string): Promise<any> {
|
async rawEvaluateJSON(expression: string): Promise<any> {
|
||||||
const response = await this._session.send('script.evaluate', {
|
const response = await this._session.send('script.evaluate', {
|
||||||
expression,
|
expression,
|
||||||
|
|
@ -98,37 +103,26 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
if (response.type === 'success') {
|
if (response.type === 'success') {
|
||||||
if (returnByValue)
|
if (returnByValue)
|
||||||
return parseEvaluationResultValue(BidiDeserializer.deserialize(response.result));
|
return parseEvaluationResultValue(BidiDeserializer.deserialize(response.result));
|
||||||
const objectId = 'handle' in response.result ? response.result.handle : undefined ;
|
return this._createHandle(response.result);
|
||||||
return utilityScript._context.createHandle({ objectId, ...response.result });
|
|
||||||
}
|
}
|
||||||
throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
|
throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
|
async getProperties(context: js.ExecutionContext, handle: js.JSHandle): Promise<Map<string, js.JSHandle>> {
|
||||||
const handle = this.createHandle(context, { objectId });
|
const names = await handle.evaluate(object => {
|
||||||
try {
|
const names = [];
|
||||||
const names = await handle.evaluate(object => {
|
const descriptors = Object.getOwnPropertyDescriptors(object);
|
||||||
const names = [];
|
for (const name in descriptors) {
|
||||||
const descriptors = Object.getOwnPropertyDescriptors(object);
|
if (descriptors[name]?.enumerable)
|
||||||
for (const name in descriptors) {
|
names.push(name);
|
||||||
if (descriptors[name]?.enumerable)
|
}
|
||||||
names.push(name);
|
return names;
|
||||||
}
|
});
|
||||||
return names;
|
const values = await Promise.all(names.map(name => handle.evaluateHandle((object, name) => object[name], name)));
|
||||||
});
|
const map = new Map<string, js.JSHandle>();
|
||||||
const values = await Promise.all(names.map(name => handle.evaluateHandle((object, name) => object[name], name)));
|
for (let i = 0; i < names.length; i++)
|
||||||
const map = new Map<string, js.JSHandle>();
|
map.set(names[i], values[i]);
|
||||||
for (let i = 0; i < names.length; i++)
|
return map;
|
||||||
map.set(names[i], values[i]);
|
|
||||||
return map;
|
|
||||||
} finally {
|
|
||||||
handle.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createHandle(context: js.ExecutionContext, jsRemoteObject: js.RemoteObject): js.JSHandle {
|
|
||||||
const remoteObject: bidi.Script.RemoteValue = jsRemoteObject as bidi.Script.RemoteValue;
|
|
||||||
return new js.JSHandle(context, remoteObject.type, renderPreview(remoteObject), jsRemoteObject.objectId, remoteObjectValue(remoteObject));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
||||||
|
|
@ -149,11 +143,11 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async remoteObjectForNodeId(nodeId: bidi.Script.SharedReference): Promise<js.RemoteObject> {
|
async remoteObjectForNodeId(nodeId: bidi.Script.SharedReference): Promise<js.JSHandle> {
|
||||||
const result = await this._remoteValueForReference(nodeId);
|
const result = await this._remoteValueForReference(nodeId);
|
||||||
if ('handle' in result)
|
if (!('handle' in result))
|
||||||
return { objectId: result.handle!, ...result };
|
throw new Error('Can\'t get remote object for nodeId');
|
||||||
throw new Error('Can\'t get remote object for nodeId');
|
return this._createHandle(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
async contentFrameIdForFrame(handle: dom.ElementHandle) {
|
async contentFrameIdForFrame(handle: dom.ElementHandle) {
|
||||||
|
|
@ -192,6 +186,13 @@ export class BidiExecutionContext implements js.ExecutionContextDelegate {
|
||||||
return response.result;
|
return response.result;
|
||||||
throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
|
throw new js.JavaScriptErrorInEvaluate('Unexpected response type: ' + JSON.stringify(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_createHandle(remoteObject: bidi.Script.RemoteValue): js.JSHandle {
|
||||||
|
if (remoteObject.type === 'node')
|
||||||
|
return this._handleFactory.createElementHandle(remoteObject.handle!);
|
||||||
|
const objectId = 'handle' in remoteObject ? remoteObject.handle : undefined;
|
||||||
|
return this._handleFactory.createJSHandle(remoteObject.type, renderPreview(remoteObject), objectId, remoteObjectValue(remoteObject));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPreview(remoteObject: bidi.Script.RemoteValue): string | undefined {
|
function renderPreview(remoteObject: bidi.Script.RemoteValue): string | undefined {
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,6 @@ export class BidiPage implements PageDelegate {
|
||||||
const frame = this._page._frameManager.frame(realmInfo.context);
|
const frame = this._page._frameManager.frame(realmInfo.context);
|
||||||
if (!frame)
|
if (!frame)
|
||||||
return;
|
return;
|
||||||
const delegate = new BidiExecutionContext(this._session, realmInfo);
|
|
||||||
let worldName: types.World;
|
let worldName: types.World;
|
||||||
if (!realmInfo.sandbox) {
|
if (!realmInfo.sandbox) {
|
||||||
worldName = 'main';
|
worldName = 'main';
|
||||||
|
|
@ -141,6 +140,7 @@ export class BidiPage implements PageDelegate {
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const delegate = new BidiExecutionContext(this._session, realmInfo);
|
||||||
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
const context = new dom.FrameExecutionContext(delegate, frame, worldName);
|
||||||
(context as any)[contextDelegateSymbol] = delegate;
|
(context as any)[contextDelegateSymbol] = delegate;
|
||||||
frame._contextCreated(worldName, context);
|
frame._contextCreated(worldName, context);
|
||||||
|
|
@ -242,7 +242,7 @@ export class BidiPage implements PageDelegate {
|
||||||
return;
|
return;
|
||||||
const callFrame = params.stackTrace?.callFrames[0];
|
const callFrame = params.stackTrace?.callFrames[0];
|
||||||
const location = callFrame ?? { url: '', lineNumber: 1, columnNumber: 1 };
|
const location = callFrame ?? { url: '', lineNumber: 1, columnNumber: 1 };
|
||||||
this._page._addConsoleMessage(entry.method, entry.args.map(arg => context.createHandle({ objectId: (arg as any).handle, ...arg })), location, params.text || undefined);
|
this._page._addConsoleMessage(entry.method, entry.args.map(arg => toBidiExecutionContext(context)._createHandle(arg)), location, params.text || undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
|
async navigateFrame(frame: frames.Frame, url: string, referrer: string | undefined): Promise<frames.GotoResult> {
|
||||||
|
|
@ -431,10 +431,6 @@ export class BidiPage implements PageDelegate {
|
||||||
return executionContext.frameIdForWindowHandle(windowHandle);
|
return executionContext.frameIdForWindowHandle(windowHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementHandle(remoteObject: bidi.Script.RemoteValue): boolean {
|
|
||||||
return remoteObject.type === 'node';
|
|
||||||
}
|
|
||||||
|
|
||||||
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
||||||
const box = await handle.evaluate(element => {
|
const box = await handle.evaluate(element => {
|
||||||
if (!(element instanceof Element))
|
if (!(element instanceof Element))
|
||||||
|
|
@ -532,10 +528,7 @@ export class BidiPage implements PageDelegate {
|
||||||
const fromContext = toBidiExecutionContext(handle._context);
|
const fromContext = toBidiExecutionContext(handle._context);
|
||||||
const nodeId = await fromContext.nodeIdForElementHandle(handle);
|
const nodeId = await fromContext.nodeIdForElementHandle(handle);
|
||||||
const executionContext = toBidiExecutionContext(to);
|
const executionContext = toBidiExecutionContext(to);
|
||||||
const objectId = await executionContext.remoteObjectForNodeId(nodeId);
|
return await executionContext.remoteObjectForNodeId(nodeId) as dom.ElementHandle<T>;
|
||||||
if (objectId)
|
|
||||||
return to.createHandle(objectId) as dom.ElementHandle<T>;
|
|
||||||
throw new Error('Failed to adopt element handle.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,17 @@ import type { Protocol } from './protocol';
|
||||||
export class CRExecutionContext implements js.ExecutionContextDelegate {
|
export class CRExecutionContext implements js.ExecutionContextDelegate {
|
||||||
_client: CRSession;
|
_client: CRSession;
|
||||||
_contextId: number;
|
_contextId: number;
|
||||||
|
private _handleFactory!: js.HandleFactory;
|
||||||
|
|
||||||
constructor(client: CRSession, contextPayload: Protocol.Runtime.ExecutionContextDescription) {
|
constructor(client: CRSession, contextPayload: Protocol.Runtime.ExecutionContextDescription) {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
this._contextId = contextPayload.id;
|
this._contextId = contextPayload.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHandleFactory(handleFactory: js.HandleFactory) {
|
||||||
|
this._handleFactory = handleFactory;
|
||||||
|
}
|
||||||
|
|
||||||
async rawEvaluateJSON(expression: string): Promise<any> {
|
async rawEvaluateJSON(expression: string): Promise<any> {
|
||||||
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', {
|
const { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', {
|
||||||
expression,
|
expression,
|
||||||
|
|
@ -69,25 +74,27 @@ export class CRExecutionContext implements js.ExecutionContextDelegate {
|
||||||
}).catch(rewriteError);
|
}).catch(rewriteError);
|
||||||
if (exceptionDetails)
|
if (exceptionDetails)
|
||||||
throw new js.JavaScriptErrorInEvaluate(getExceptionMessage(exceptionDetails));
|
throw new js.JavaScriptErrorInEvaluate(getExceptionMessage(exceptionDetails));
|
||||||
return returnByValue ? parseEvaluationResultValue(remoteObject.value) : utilityScript._context.createHandle(remoteObject);
|
return returnByValue ? parseEvaluationResultValue(remoteObject.value) : this._createHandle(remoteObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
|
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
|
||||||
const response = await this._client.send('Runtime.getProperties', {
|
const response = await this._client.send('Runtime.getProperties', {
|
||||||
objectId,
|
objectId: object._objectId!,
|
||||||
ownProperties: true
|
ownProperties: true
|
||||||
});
|
});
|
||||||
const result = new Map();
|
const result = new Map();
|
||||||
for (const property of response.result) {
|
for (const property of response.result) {
|
||||||
if (!property.enumerable || !property.value)
|
if (!property.enumerable || !property.value)
|
||||||
continue;
|
continue;
|
||||||
result.set(property.name, context.createHandle(property.value));
|
result.set(property.name, this._createHandle(property.value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
_createHandle(remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
||||||
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
if (remoteObject.subtype === 'node')
|
||||||
|
return this._handleFactory.createElementHandle(remoteObject.objectId!);
|
||||||
|
return this._handleFactory.createJSHandle(remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ import type { InitScript, PageDelegate } from '../page';
|
||||||
import type { Progress } from '../progress';
|
import type { Progress } from '../progress';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
import type * as channels from '@protocol/channels';
|
import type * as channels from '@protocol/channels';
|
||||||
|
import type * as js from '../javascript';
|
||||||
|
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
const UTILITY_WORLD_NAME = '__playwright_utility_world__';
|
||||||
|
|
@ -281,10 +282,6 @@ export class CRPage implements PageDelegate {
|
||||||
return this._sessionForHandle(handle)._getOwnerFrame(handle);
|
return this._sessionForHandle(handle)._getOwnerFrame(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementHandle(remoteObject: any): boolean {
|
|
||||||
return (remoteObject as Protocol.Runtime.RemoteObject).subtype === 'node';
|
|
||||||
}
|
|
||||||
|
|
||||||
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
||||||
return this._sessionForHandle(handle)._getBoundingBox(handle);
|
return this._sessionForHandle(handle)._getBoundingBox(handle);
|
||||||
}
|
}
|
||||||
|
|
@ -739,7 +736,7 @@ class FrameSession {
|
||||||
session.on('Target.attachedToTarget', event => this._onAttachedToTarget(event));
|
session.on('Target.attachedToTarget', event => this._onAttachedToTarget(event));
|
||||||
session.on('Target.detachedFromTarget', event => this._onDetachedFromTarget(event));
|
session.on('Target.detachedFromTarget', event => this._onDetachedFromTarget(event));
|
||||||
session.on('Runtime.consoleAPICalled', event => {
|
session.on('Runtime.consoleAPICalled', event => {
|
||||||
const args = event.args.map(o => worker._existingExecutionContext!.createHandle(o));
|
const args = event.args.map(o => toCRExecutionContext(worker._existingExecutionContext!)._createHandle(o));
|
||||||
this._page._addConsoleMessage(event.type, args, toConsoleMessageLocation(event.stackTrace));
|
this._page._addConsoleMessage(event.type, args, toConsoleMessageLocation(event.stackTrace));
|
||||||
});
|
});
|
||||||
session.on('Runtime.exceptionThrown', exception => this._page.emitOnContextOnceInitialized(BrowserContext.Events.PageError, exceptionToError(exception.exceptionDetails), this._page));
|
session.on('Runtime.exceptionThrown', exception => this._page.emitOnContextOnceInitialized(BrowserContext.Events.PageError, exceptionToError(exception.exceptionDetails), this._page));
|
||||||
|
|
@ -802,7 +799,7 @@ class FrameSession {
|
||||||
const context = this._contextIdToContext.get(event.executionContextId);
|
const context = this._contextIdToContext.get(event.executionContextId);
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
const values = event.args.map(arg => context.createHandle(arg));
|
const values = event.args.map(arg => toCRExecutionContext(context)._createHandle(arg));
|
||||||
this._page._addConsoleMessage(event.type, values, toConsoleMessageLocation(event.stackTrace));
|
this._page._addConsoleMessage(event.type, values, toConsoleMessageLocation(event.stackTrace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1171,7 +1168,7 @@ class FrameSession {
|
||||||
});
|
});
|
||||||
if (!result || result.object.subtype === 'null')
|
if (!result || result.object.subtype === 'null')
|
||||||
throw new Error(dom.kUnableToAdoptErrorMessage);
|
throw new Error(dom.kUnableToAdoptErrorMessage);
|
||||||
return to.createHandle(result.object).asElement()!;
|
return toCRExecutionContext(to)._createHandle(result.object).asElement()!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1246,3 +1243,7 @@ function calculateUserAgentMetadata(options: types.BrowserContextOptions) {
|
||||||
metadata.architecture = 'arm';
|
metadata.architecture = 'arm';
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toCRExecutionContext(executionContext: js.ExecutionContext): CRExecutionContext {
|
||||||
|
return executionContext._delegate as CRExecutionContext;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,6 @@ export class FrameExecutionContext extends js.ExecutionContext {
|
||||||
return js.evaluateExpression(this, expression, { ...options, returnByValue: false }, arg);
|
return js.evaluateExpression(this, expression, { ...options, returnByValue: false }, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
override createHandle(remoteObject: js.RemoteObject): js.JSHandle {
|
|
||||||
if (this.frame._page._delegate.isElementHandle(remoteObject))
|
|
||||||
return new ElementHandle(this, remoteObject.objectId!);
|
|
||||||
return super.createHandle(remoteObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
injectedScript(): Promise<js.JSHandle<InjectedScript>> {
|
injectedScript(): Promise<js.JSHandle<InjectedScript>> {
|
||||||
if (!this._injectedScriptPromise) {
|
if (!this._injectedScriptPromise) {
|
||||||
const custom: string[] = [];
|
const custom: string[] = [];
|
||||||
|
|
@ -115,6 +109,10 @@ export class FrameExecutionContext extends js.ExecutionContext {
|
||||||
}
|
}
|
||||||
return this._injectedScriptPromise;
|
return this._injectedScriptPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override createElementHandle(objectId: js.ObjectId): ElementHandle {
|
||||||
|
return new ElementHandle(this, objectId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||||
|
|
@ -124,7 +122,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||||
declare readonly _objectId: string;
|
declare readonly _objectId: string;
|
||||||
readonly _frame: frames.Frame;
|
readonly _frame: frames.Frame;
|
||||||
|
|
||||||
constructor(context: FrameExecutionContext, objectId: string) {
|
constructor(context: FrameExecutionContext, objectId: js.ObjectId) {
|
||||||
super(context, 'node', undefined, objectId);
|
super(context, 'node', undefined, objectId);
|
||||||
this._page = context.frame._page;
|
this._page = context.frame._page;
|
||||||
this._frame = context.frame;
|
this._frame = context.frame;
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ export class ElectronApplication extends SdkObject {
|
||||||
}
|
}
|
||||||
if (!this._nodeExecutionContext)
|
if (!this._nodeExecutionContext)
|
||||||
return;
|
return;
|
||||||
const args = event.args.map(arg => this._nodeExecutionContext!.createHandle(arg));
|
const args = event.args.map(arg => toCRExecutionContext(this._nodeExecutionContext!)._createHandle(arg));
|
||||||
const message = new ConsoleMessage(null, event.type, undefined, args, toConsoleMessageLocation(event.stackTrace));
|
const message = new ConsoleMessage(null, event.type, undefined, args, toConsoleMessageLocation(event.stackTrace));
|
||||||
this.emit(ElectronApplication.Events.Console, message);
|
this.emit(ElectronApplication.Events.Console, message);
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +151,10 @@ export class ElectronApplication extends SdkObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toCRExecutionContext(executionContext: js.ExecutionContext): CRExecutionContext {
|
||||||
|
return executionContext._delegate as CRExecutionContext;
|
||||||
|
}
|
||||||
|
|
||||||
export class Electron extends SdkObject {
|
export class Electron extends SdkObject {
|
||||||
constructor(playwright: Playwright) {
|
constructor(playwright: Playwright) {
|
||||||
super(playwright, 'electron');
|
super(playwright, 'electron');
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,17 @@ import type { Protocol } from './protocol';
|
||||||
export class FFExecutionContext implements js.ExecutionContextDelegate {
|
export class FFExecutionContext implements js.ExecutionContextDelegate {
|
||||||
_session: FFSession;
|
_session: FFSession;
|
||||||
_executionContextId: string;
|
_executionContextId: string;
|
||||||
|
private _handleFactory!: js.HandleFactory;
|
||||||
|
|
||||||
constructor(session: FFSession, executionContextId: string) {
|
constructor(session: FFSession, executionContextId: string) {
|
||||||
this._session = session;
|
this._session = session;
|
||||||
this._executionContextId = executionContextId;
|
this._executionContextId = executionContextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHandleFactory(handleFactory: js.HandleFactory) {
|
||||||
|
this._handleFactory = handleFactory;
|
||||||
|
}
|
||||||
|
|
||||||
async rawEvaluateJSON(expression: string): Promise<any> {
|
async rawEvaluateJSON(expression: string): Promise<any> {
|
||||||
const payload = await this._session.send('Runtime.evaluate', {
|
const payload = await this._session.send('Runtime.evaluate', {
|
||||||
expression,
|
expression,
|
||||||
|
|
@ -66,22 +71,24 @@ export class FFExecutionContext implements js.ExecutionContextDelegate {
|
||||||
checkException(payload.exceptionDetails);
|
checkException(payload.exceptionDetails);
|
||||||
if (returnByValue)
|
if (returnByValue)
|
||||||
return parseEvaluationResultValue(payload.result!.value);
|
return parseEvaluationResultValue(payload.result!.value);
|
||||||
return utilityScript._context.createHandle(payload.result!);
|
return toFFExecutionContext(utilityScript._context)._createHandle(payload.result!);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
|
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
|
||||||
const response = await this._session.send('Runtime.getObjectProperties', {
|
const response = await this._session.send('Runtime.getObjectProperties', {
|
||||||
executionContextId: this._executionContextId,
|
executionContextId: this._executionContextId,
|
||||||
objectId,
|
objectId: object._objectId!,
|
||||||
});
|
});
|
||||||
const result = new Map();
|
const result = new Map();
|
||||||
for (const property of response.properties)
|
for (const property of response.properties)
|
||||||
result.set(property.name, context.createHandle(property.value));
|
result.set(property.name, toFFExecutionContext(context)._createHandle(property.value));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
_createHandle(remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
||||||
return new js.JSHandle(context, remoteObject.subtype || remoteObject.type || '', renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
if (remoteObject.subtype === 'node')
|
||||||
|
return this._handleFactory.createElementHandle(remoteObject.objectId!);
|
||||||
|
return this._handleFactory.createJSHandle(remoteObject.subtype || remoteObject.type || '', renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
||||||
|
|
@ -135,3 +142,7 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
|
||||||
if ('value' in object)
|
if ('value' in object)
|
||||||
return String(object.value);
|
return String(object.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toFFExecutionContext(executionContext: js.ExecutionContext): FFExecutionContext {
|
||||||
|
return executionContext._delegate as FFExecutionContext;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { InitScript } from '../page';
|
||||||
import { Page, Worker } from '../page';
|
import { Page, Worker } from '../page';
|
||||||
import { getAccessibilityTree } from './ffAccessibility';
|
import { getAccessibilityTree } from './ffAccessibility';
|
||||||
import { FFSession } from './ffConnection';
|
import { FFSession } from './ffConnection';
|
||||||
import { FFExecutionContext } from './ffExecutionContext';
|
import { FFExecutionContext, toFFExecutionContext } from './ffExecutionContext';
|
||||||
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './ffInput';
|
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './ffInput';
|
||||||
import { FFNetworkManager } from './ffNetworkManager';
|
import { FFNetworkManager } from './ffNetworkManager';
|
||||||
import { debugLogger } from '../utils/debugLogger';
|
import { debugLogger } from '../utils/debugLogger';
|
||||||
|
|
@ -234,7 +234,7 @@ export class FFPage implements PageDelegate {
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
// Juggler reports 'warn' for some internal messages generated by the browser.
|
// Juggler reports 'warn' for some internal messages generated by the browser.
|
||||||
this._page._addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => context.createHandle(arg)), location);
|
this._page._addConsoleMessage(type === 'warn' ? 'warning' : type, args.map(arg => toFFExecutionContext(context)._createHandle(arg)), location);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDialogOpened(params: Protocol.Page.dialogOpenedPayload) {
|
_onDialogOpened(params: Protocol.Page.dialogOpenedPayload) {
|
||||||
|
|
@ -262,7 +262,7 @@ export class FFPage implements PageDelegate {
|
||||||
const context = this._contextIdToContext.get(executionContextId);
|
const context = this._contextIdToContext.get(executionContextId);
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
const handle = context.createHandle(element).asElement()!;
|
const handle = toFFExecutionContext(context)._createHandle(element).asElement()!;
|
||||||
await this._page._onFileChooserOpened(handle);
|
await this._page._onFileChooserOpened(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -286,7 +286,7 @@ export class FFPage implements PageDelegate {
|
||||||
workerSession.on('Runtime.console', event => {
|
workerSession.on('Runtime.console', event => {
|
||||||
const { type, args, location } = event;
|
const { type, args, location } = event;
|
||||||
const context = worker._existingExecutionContext!;
|
const context = worker._existingExecutionContext!;
|
||||||
this._page._addConsoleMessage(type, args.map(arg => context.createHandle(arg)), location);
|
this._page._addConsoleMessage(type, args.map(arg => toFFExecutionContext(context)._createHandle(arg)), location);
|
||||||
});
|
});
|
||||||
// Note: we receive worker exceptions directly from the page.
|
// Note: we receive worker exceptions directly from the page.
|
||||||
}
|
}
|
||||||
|
|
@ -443,10 +443,6 @@ export class FFPage implements PageDelegate {
|
||||||
return ownerFrameId || null;
|
return ownerFrameId || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementHandle(remoteObject: any): boolean {
|
|
||||||
return remoteObject.subtype === 'node';
|
|
||||||
}
|
|
||||||
|
|
||||||
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
||||||
const quads = await this.getContentQuads(handle);
|
const quads = await this.getContentQuads(handle);
|
||||||
if (!quads || !quads.length)
|
if (!quads || !quads.length)
|
||||||
|
|
@ -535,7 +531,7 @@ export class FFPage implements PageDelegate {
|
||||||
});
|
});
|
||||||
if (!result.remoteObject)
|
if (!result.remoteObject)
|
||||||
throw new Error(dom.kUnableToAdoptErrorMessage);
|
throw new Error(dom.kUnableToAdoptErrorMessage);
|
||||||
return to.createHandle(result.remoteObject) as dom.ElementHandle<T>;
|
return toFFExecutionContext(to)._createHandle(result.remoteObject) as dom.ElementHandle<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccessibilityTree(needle?: dom.ElementHandle) {
|
async getAccessibilityTree(needle?: dom.ElementHandle) {
|
||||||
|
|
@ -564,7 +560,7 @@ export class FFPage implements PageDelegate {
|
||||||
});
|
});
|
||||||
if (!result.remoteObject)
|
if (!result.remoteObject)
|
||||||
throw new Error('Frame has been detached.');
|
throw new Error('Frame has been detached.');
|
||||||
return context.createHandle(result.remoteObject) as dom.ElementHandle;
|
return toFFExecutionContext(context)._createHandle(result.remoteObject) as dom.ElementHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldToggleStyleSheetToSyncAnimations(): boolean {
|
shouldToggleStyleSheetToSyncAnimations(): boolean {
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,6 @@ import type * as dom from './dom';
|
||||||
import type { UtilityScript } from './injected/utilityScript';
|
import type { UtilityScript } from './injected/utilityScript';
|
||||||
|
|
||||||
export type ObjectId = string;
|
export type ObjectId = string;
|
||||||
export type RemoteObject = {
|
|
||||||
objectId?: ObjectId,
|
|
||||||
value?: any
|
|
||||||
};
|
|
||||||
|
|
||||||
interface TaggedAsJSHandle<T> {
|
interface TaggedAsJSHandle<T> {
|
||||||
__jshandle: T;
|
__jshandle: T;
|
||||||
|
|
@ -55,21 +51,27 @@ export interface ExecutionContextDelegate {
|
||||||
rawEvaluateJSON(expression: string): Promise<any>;
|
rawEvaluateJSON(expression: string): Promise<any>;
|
||||||
rawEvaluateHandle(expression: string): Promise<ObjectId>;
|
rawEvaluateHandle(expression: string): Promise<ObjectId>;
|
||||||
evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: JSHandle<any>, values: any[], objectIds: ObjectId[]): Promise<any>;
|
evaluateWithArguments(expression: string, returnByValue: boolean, utilityScript: JSHandle<any>, values: any[], objectIds: ObjectId[]): Promise<any>;
|
||||||
getProperties(context: ExecutionContext, objectId: ObjectId): Promise<Map<string, JSHandle>>;
|
getProperties(context: ExecutionContext, object: JSHandle): Promise<Map<string, JSHandle>>;
|
||||||
createHandle(context: ExecutionContext, remoteObject: RemoteObject): JSHandle;
|
|
||||||
releaseHandle(objectId: ObjectId): Promise<void>;
|
releaseHandle(objectId: ObjectId): Promise<void>;
|
||||||
|
setHandleFactory(factory: HandleFactory): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ExecutionContext extends SdkObject {
|
export interface HandleFactory {
|
||||||
private _delegate: ExecutionContextDelegate;
|
createElementHandle(objectId: ObjectId): dom.ElementHandle;
|
||||||
|
createJSHandle(type: string, preview: string | undefined, objectId?: ObjectId, value?: any): JSHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExecutionContext extends SdkObject implements HandleFactory {
|
||||||
|
_delegate: ExecutionContextDelegate;
|
||||||
private _utilityScriptPromise: Promise<JSHandle> | undefined;
|
private _utilityScriptPromise: Promise<JSHandle> | undefined;
|
||||||
private _contextDestroyedScope = new LongStandingScope();
|
private _contextDestroyedScope = new LongStandingScope();
|
||||||
readonly worldNameForTest: string;
|
readonly worldNameForTest: string;
|
||||||
|
|
||||||
constructor(parent: SdkObject, delegate: ExecutionContextDelegate, worldNameForTest: string) {
|
constructor(parent: SdkObject, delegate: ExecutionContextDelegate, worldNameForTest: string, handleFactory?: HandleFactory) {
|
||||||
super(parent, 'execution-context');
|
super(parent, 'execution-context');
|
||||||
this.worldNameForTest = worldNameForTest;
|
this.worldNameForTest = worldNameForTest;
|
||||||
this._delegate = delegate;
|
this._delegate = delegate;
|
||||||
|
delegate.setHandleFactory(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
contextDestroyed(reason: string) {
|
contextDestroyed(reason: string) {
|
||||||
|
|
@ -93,12 +95,8 @@ export class ExecutionContext extends SdkObject {
|
||||||
return this._raceAgainstContextDestroyed(this._delegate.evaluateWithArguments(expression, returnByValue, utilityScript, values, objectIds));
|
return this._raceAgainstContextDestroyed(this._delegate.evaluateWithArguments(expression, returnByValue, utilityScript, values, objectIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
getProperties(context: ExecutionContext, objectId: ObjectId): Promise<Map<string, JSHandle>> {
|
getProperties(context: ExecutionContext, object: JSHandle): Promise<Map<string, JSHandle>> {
|
||||||
return this._raceAgainstContextDestroyed(this._delegate.getProperties(context, objectId));
|
return this._raceAgainstContextDestroyed(this._delegate.getProperties(context, object));
|
||||||
}
|
|
||||||
|
|
||||||
createHandle(remoteObject: RemoteObject): JSHandle {
|
|
||||||
return this._delegate.createHandle(this, remoteObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseHandle(objectId: ObjectId): Promise<void> {
|
releaseHandle(objectId: ObjectId): Promise<void> {
|
||||||
|
|
@ -125,6 +123,14 @@ export class ExecutionContext extends SdkObject {
|
||||||
async doSlowMo() {
|
async doSlowMo() {
|
||||||
// overridden in FrameExecutionContext
|
// overridden in FrameExecutionContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createElementHandle(objectId: string): dom.ElementHandle {
|
||||||
|
throw new Error('Not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
createJSHandle(type: string, preview: string | undefined, objectId?: ObjectId, value?: any): JSHandle {
|
||||||
|
return new JSHandle(this, type, preview, objectId, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class JSHandle<T = any> extends SdkObject {
|
export class JSHandle<T = any> extends SdkObject {
|
||||||
|
|
@ -183,7 +189,7 @@ export class JSHandle<T = any> extends SdkObject {
|
||||||
async getProperties(): Promise<Map<string, JSHandle>> {
|
async getProperties(): Promise<Map<string, JSHandle>> {
|
||||||
if (!this._objectId)
|
if (!this._objectId)
|
||||||
return new Map();
|
return new Map();
|
||||||
return this._context.getProperties(this._context, this._objectId);
|
return this._context.getProperties(this._context, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
rawValue() {
|
rawValue() {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ export interface PageDelegate {
|
||||||
setBackgroundColor(color?: { r: number; g: number; b: number; a: number; }): Promise<void>;
|
setBackgroundColor(color?: { r: number; g: number; b: number; a: number; }): Promise<void>;
|
||||||
takeScreenshot(progress: Progress, format: string, documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined, fitsViewport: boolean, scale: 'css' | 'device'): Promise<Buffer>;
|
takeScreenshot(progress: Progress, format: string, documentRect: types.Rect | undefined, viewportRect: types.Rect | undefined, quality: number | undefined, fitsViewport: boolean, scale: 'css' | 'device'): Promise<Buffer>;
|
||||||
|
|
||||||
isElementHandle(remoteObject: any): boolean;
|
|
||||||
adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>>;
|
adoptElementHandle<T extends Node>(handle: dom.ElementHandle<T>, to: dom.FrameExecutionContext): Promise<dom.ElementHandle<T>>;
|
||||||
getContentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null>; // Only called for frame owner elements.
|
getContentFrame(handle: dom.ElementHandle): Promise<frames.Frame | null>; // Only called for frame owner elements.
|
||||||
getOwnerFrame(handle: dom.ElementHandle): Promise<string | null>; // Returns frameId.
|
getOwnerFrame(handle: dom.ElementHandle): Promise<string | null>; // Returns frameId.
|
||||||
|
|
@ -834,6 +833,7 @@ export class Worker extends SdkObject {
|
||||||
_createExecutionContext(delegate: js.ExecutionContextDelegate) {
|
_createExecutionContext(delegate: js.ExecutionContextDelegate) {
|
||||||
this._existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
|
this._existingExecutionContext = new js.ExecutionContext(this, delegate, 'worker');
|
||||||
this._executionContextCallback(this._existingExecutionContext);
|
this._executionContextCallback(this._existingExecutionContext);
|
||||||
|
return this._existingExecutionContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
url(): string {
|
url(): string {
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,17 @@ import type { WKSession } from './wkConnection';
|
||||||
export class WKExecutionContext implements js.ExecutionContextDelegate {
|
export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
private readonly _session: WKSession;
|
private readonly _session: WKSession;
|
||||||
readonly _contextId: number | undefined;
|
readonly _contextId: number | undefined;
|
||||||
|
private _handleFactory!: js.HandleFactory;
|
||||||
|
|
||||||
constructor(session: WKSession, contextId: number | undefined) {
|
constructor(session: WKSession, contextId: number | undefined) {
|
||||||
this._session = session;
|
this._session = session;
|
||||||
this._contextId = contextId;
|
this._contextId = contextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setHandleFactory(handleFactory: js.HandleFactory) {
|
||||||
|
this._handleFactory = handleFactory;
|
||||||
|
}
|
||||||
|
|
||||||
async rawEvaluateJSON(expression: string): Promise<any> {
|
async rawEvaluateJSON(expression: string): Promise<any> {
|
||||||
try {
|
try {
|
||||||
const response = await this._session.send('Runtime.evaluate', {
|
const response = await this._session.send('Runtime.evaluate', {
|
||||||
|
|
@ -79,29 +84,31 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
throw new js.JavaScriptErrorInEvaluate(response.result.description);
|
throw new js.JavaScriptErrorInEvaluate(response.result.description);
|
||||||
if (returnByValue)
|
if (returnByValue)
|
||||||
return parseEvaluationResultValue(response.result.value);
|
return parseEvaluationResultValue(response.result.value);
|
||||||
return utilityScript._context.createHandle(response.result);
|
return toWKExecutionContext(utilityScript._context)._createHandle(response.result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw rewriteError(error);
|
throw rewriteError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProperties(context: js.ExecutionContext, objectId: js.ObjectId): Promise<Map<string, js.JSHandle>> {
|
async getProperties(context: js.ExecutionContext, object: js.JSHandle): Promise<Map<string, js.JSHandle>> {
|
||||||
const response = await this._session.send('Runtime.getProperties', {
|
const response = await this._session.send('Runtime.getProperties', {
|
||||||
objectId,
|
objectId: object._objectId!,
|
||||||
ownProperties: true
|
ownProperties: true
|
||||||
});
|
});
|
||||||
const result = new Map();
|
const result = new Map();
|
||||||
for (const property of response.properties) {
|
for (const property of response.properties) {
|
||||||
if (!property.enumerable || !property.value)
|
if (!property.enumerable || !property.value)
|
||||||
continue;
|
continue;
|
||||||
result.set(property.name, context.createHandle(property.value));
|
result.set(property.name, toWKExecutionContext(context)._createHandle(property.value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
createHandle(context: js.ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
_createHandle(remoteObject: Protocol.Runtime.RemoteObject): js.JSHandle {
|
||||||
|
if (remoteObject.subtype === 'node')
|
||||||
|
return this._handleFactory.createElementHandle(remoteObject.objectId!);
|
||||||
const isPromise = remoteObject.className === 'Promise';
|
const isPromise = remoteObject.className === 'Promise';
|
||||||
return new js.JSHandle(context, isPromise ? 'promise' : remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
return this._handleFactory.createJSHandle(isPromise ? 'promise' : remoteObject.subtype || remoteObject.type, renderPreview(remoteObject), remoteObject.objectId, potentiallyUnserializableValue(remoteObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
async releaseHandle(objectId: js.ObjectId): Promise<void> {
|
||||||
|
|
@ -139,3 +146,7 @@ function renderPreview(object: Protocol.Runtime.RemoteObject): string | undefine
|
||||||
return js.sparseArrayToString(object.preview.properties!);
|
return js.sparseArrayToString(object.preview.properties!);
|
||||||
return object.description;
|
return object.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toWKExecutionContext(executionContext: js.ExecutionContext): WKExecutionContext {
|
||||||
|
return executionContext._delegate as WKExecutionContext;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import { PageBinding } from '../page';
|
||||||
import { Page } from '../page';
|
import { Page } from '../page';
|
||||||
import { getAccessibilityTree } from './wkAccessibility';
|
import { getAccessibilityTree } from './wkAccessibility';
|
||||||
import { WKSession } from './wkConnection';
|
import { WKSession } from './wkConnection';
|
||||||
import { WKExecutionContext } from './wkExecutionContext';
|
import { toWKExecutionContext, WKExecutionContext } from './wkExecutionContext';
|
||||||
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './wkInput';
|
import { RawKeyboardImpl, RawMouseImpl, RawTouchscreenImpl } from './wkInput';
|
||||||
import { WKInterceptableRequest, WKRouteImpl } from './wkInterceptableRequest';
|
import { WKInterceptableRequest, WKRouteImpl } from './wkInterceptableRequest';
|
||||||
import { WKProvisionalPage } from './wkProvisionalPage';
|
import { WKProvisionalPage } from './wkProvisionalPage';
|
||||||
|
|
@ -562,7 +562,7 @@ export class WKPage implements PageDelegate {
|
||||||
}
|
}
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
handles.push(context.createHandle(p));
|
handles.push(toWKExecutionContext(context)._createHandle(p));
|
||||||
}
|
}
|
||||||
this._lastConsoleMessage = {
|
this._lastConsoleMessage = {
|
||||||
derivedType,
|
derivedType,
|
||||||
|
|
@ -611,7 +611,7 @@ export class WKPage implements PageDelegate {
|
||||||
let handle;
|
let handle;
|
||||||
try {
|
try {
|
||||||
const context = await this._page._frameManager.frame(event.frameId)!._mainContext();
|
const context = await this._page._frameManager.frame(event.frameId)!._mainContext();
|
||||||
handle = context.createHandle(event.element).asElement()!;
|
handle = toWKExecutionContext(context)._createHandle(event.element).asElement()!;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// During async processing, frame/context may go away. We should not throw.
|
// During async processing, frame/context may go away. We should not throw.
|
||||||
return;
|
return;
|
||||||
|
|
@ -869,10 +869,6 @@ export class WKPage implements PageDelegate {
|
||||||
return nodeInfo.ownerFrameId || null;
|
return nodeInfo.ownerFrameId || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementHandle(remoteObject: any): boolean {
|
|
||||||
return (remoteObject as Protocol.Runtime.RemoteObject).subtype === 'node';
|
|
||||||
}
|
|
||||||
|
|
||||||
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
async getBoundingBox(handle: dom.ElementHandle): Promise<types.Rect | null> {
|
||||||
const quads = await this.getContentQuads(handle);
|
const quads = await this.getContentQuads(handle);
|
||||||
if (!quads || !quads.length)
|
if (!quads || !quads.length)
|
||||||
|
|
@ -962,7 +958,7 @@ export class WKPage implements PageDelegate {
|
||||||
});
|
});
|
||||||
if (!result || result.object.subtype === 'null')
|
if (!result || result.object.subtype === 'null')
|
||||||
throw new Error(dom.kUnableToAdoptErrorMessage);
|
throw new Error(dom.kUnableToAdoptErrorMessage);
|
||||||
return to.createHandle(result.object) as dom.ElementHandle<T>;
|
return toWKExecutionContext(to)._createHandle(result.object) as dom.ElementHandle<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
async getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||||
|
|
@ -986,7 +982,7 @@ export class WKPage implements PageDelegate {
|
||||||
});
|
});
|
||||||
if (!result || result.object.subtype === 'null')
|
if (!result || result.object.subtype === 'null')
|
||||||
throw new Error('Frame has been detached.');
|
throw new Error('Frame has been detached.');
|
||||||
return context.createHandle(result.object) as dom.ElementHandle;
|
return toWKExecutionContext(context)._createHandle(result.object) as dom.ElementHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _maybeCancelCoopNavigationRequest(provisionalPage: WKProvisionalPage) {
|
private _maybeCancelCoopNavigationRequest(provisionalPage: WKProvisionalPage) {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
import { eventsHelper } from '../utils/eventsHelper';
|
import { eventsHelper } from '../utils/eventsHelper';
|
||||||
import { Worker } from '../page';
|
import { Worker } from '../page';
|
||||||
import { WKSession } from './wkConnection';
|
import { WKSession } from './wkConnection';
|
||||||
import { WKExecutionContext } from './wkExecutionContext';
|
import { toWKExecutionContext, WKExecutionContext } from './wkExecutionContext';
|
||||||
|
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { RegisteredListener } from '../utils/eventsHelper';
|
import type { RegisteredListener } from '../utils/eventsHelper';
|
||||||
|
|
@ -95,7 +95,7 @@ export class WKWorkers {
|
||||||
derivedType = 'timeEnd';
|
derivedType = 'timeEnd';
|
||||||
|
|
||||||
const handles = (parameters || []).map(p => {
|
const handles = (parameters || []).map(p => {
|
||||||
return worker._existingExecutionContext!.createHandle(p);
|
return toWKExecutionContext(worker._existingExecutionContext!)._createHandle(p);
|
||||||
});
|
});
|
||||||
const location: types.ConsoleMessageLocation = {
|
const location: types.ConsoleMessageLocation = {
|
||||||
url: url || '',
|
url: url || '',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue