Skip to content

Commit

Permalink
chore(evaluate): respect signals when evaluating on handle (#5847)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Mar 17, 2021
1 parent 7011e57 commit 5ae731a
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 83 deletions.
4 changes: 2 additions & 2 deletions src/dispatchers/electronDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ export class ElectronApplicationDispatcher extends Dispatcher<ElectronApplicatio

async evaluateExpression(params: channels.ElectronApplicationEvaluateExpressionParams): Promise<channels.ElectronApplicationEvaluateExpressionResult> {
const handle = this._object._nodeElectronHandle!;
return { value: serializeResult(await handle.evaluateExpression(params.expression, params.isFunction, true /* returnByValue */, parseArgument(params.arg))) };
return { value: serializeResult(await handle.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, true /* returnByValue */, parseArgument(params.arg))) };
}

async evaluateExpressionHandle(params: channels.ElectronApplicationEvaluateExpressionHandleParams): Promise<channels.ElectronApplicationEvaluateExpressionHandleResult> {
const handle = this._object._nodeElectronHandle!;
const result = await handle.evaluateExpression(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg));
const result = await handle.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg));
return { handle: createHandle(this._scope, result) };
}

Expand Down
4 changes: 2 additions & 2 deletions src/dispatchers/elementHandlerDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,11 @@ export class ElementHandleDispatcher extends JSHandleDispatcher implements chann
}

async evalOnSelector(params: channels.ElementHandleEvalOnSelectorParams, metadata: CallMetadata): Promise<channels.ElementHandleEvalOnSelectorResult> {
return { value: serializeResult(await this._elementHandle.$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
return { value: serializeResult(await this._elementHandle.evalOnSelectorAndWaitForSignals(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
}

async evalOnSelectorAll(params: channels.ElementHandleEvalOnSelectorAllParams, metadata: CallMetadata): Promise<channels.ElementHandleEvalOnSelectorAllResult> {
return { value: serializeResult(await this._elementHandle.$$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
return { value: serializeResult(await this._elementHandle.evalOnSelectorAllAndWaitForSignals(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
}

async waitForElementState(params: channels.ElementHandleWaitForElementStateParams, metadata: CallMetadata): Promise<void> {
Expand Down
4 changes: 2 additions & 2 deletions src/dispatchers/frameDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameInitializer
}

async evalOnSelector(params: channels.FrameEvalOnSelectorParams, metadata: CallMetadata): Promise<channels.FrameEvalOnSelectorResult> {
return { value: serializeResult(await this._frame._$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
return { value: serializeResult(await this._frame.evalOnSelectorAndWaitForSignals(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
}

async evalOnSelectorAll(params: channels.FrameEvalOnSelectorAllParams, metadata: CallMetadata): Promise<channels.FrameEvalOnSelectorAllResult> {
return { value: serializeResult(await this._frame._$$evalExpression(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
return { value: serializeResult(await this._frame.evalOnSelectorAllAndWaitForSignals(params.selector, params.expression, params.isFunction, parseArgument(params.arg))) };
}

async querySelector(params: channels.FrameQuerySelectorParams, metadata: CallMetadata): Promise<channels.FrameQuerySelectorResult> {
Expand Down
4 changes: 2 additions & 2 deletions src/dispatchers/jsHandleDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ export class JSHandleDispatcher extends Dispatcher<js.JSHandle, channels.JSHandl
}

async evaluateExpression(params: channels.JSHandleEvaluateExpressionParams): Promise<channels.JSHandleEvaluateExpressionResult> {
return { value: serializeResult(await this._object.evaluateExpression(params.expression, params.isFunction, true /* returnByValue */, parseArgument(params.arg))) };
return { value: serializeResult(await this._object.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, true /* returnByValue */, parseArgument(params.arg))) };
}

async evaluateExpressionHandle(params: channels.JSHandleEvaluateExpressionHandleParams): Promise<channels.JSHandleEvaluateExpressionHandleResult> {
const jsHandle = await this._object.evaluateExpression(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg));
const jsHandle = await this._object.evaluateExpressionAndWaitForSignals(params.expression, params.isFunction, false /* returnByValue */, parseArgument(params.arg));
return { handle: createHandle(this._scope, jsHandle) };
}

Expand Down
4 changes: 2 additions & 2 deletions src/dispatchers/pageDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,11 @@ export class WorkerDispatcher extends Dispatcher<Worker, channels.WorkerInitiali
}

async evaluateExpression(params: channels.WorkerEvaluateExpressionParams, metadata: CallMetadata): Promise<channels.WorkerEvaluateExpressionResult> {
return { value: serializeResult(await this._object._evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg))) };
return { value: serializeResult(await this._object.evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg))) };
}

async evaluateExpressionHandle(params: channels.WorkerEvaluateExpressionHandleParams, metadata: CallMetadata): Promise<channels.WorkerEvaluateExpressionHandleResult> {
return { handle: createHandle(this._scope, await this._object._evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg))) };
return { handle: createHandle(this._scope, await this._object.evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg))) };
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/server/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export class FrameExecutionContext extends js.ExecutionContext {
this.world = world;
}

async waitForSignalsCreatedBy<T>(action: () => Promise<T>): Promise<T> {
return this.frame._page._frameManager.waitForSignalsCreatedBy(null, false, action);
}

adoptIfNeeded(handle: js.JSHandle): Promise<js.JSHandle> | null {
if (handle instanceof ElementHandle && handle._context !== this)
return this.frame._page._delegate.adoptElementHandle(handle, this);
Expand Down Expand Up @@ -654,18 +658,18 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
return this._page.selectors._queryAll(this._context.frame, selector, this, true /* adoptToMain */);
}

async $evalExpression(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evalOnSelectorAndWaitForSignals(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
const handle = await this._page.selectors._query(this._context.frame, selector, this);
if (!handle)
throw new Error(`Error: failed to find element matching selector "${selector}"`);
const result = await handle.evaluateExpression(expression, isFunction, true, arg);
const result = await handle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);
handle.dispose();
return result;
}

async $$evalExpression(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evalOnSelectorAllAndWaitForSignals(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
const arrayHandle = await this._page.selectors._queryArray(this._context.frame, selector, this);
const result = await arrayHandle.evaluateExpression(expression, isFunction, true, arg);
const result = await arrayHandle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);
arrayHandle.dispose();
return result;
}
Expand Down
8 changes: 4 additions & 4 deletions src/server/frames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,18 +656,18 @@ export class Frame extends SdkObject {
await this._page._doSlowMo();
}

async _$evalExpression(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evalOnSelectorAndWaitForSignals(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
const handle = await this.$(selector);
if (!handle)
throw new Error(`Error: failed to find element matching selector "${selector}"`);
const result = await handle.evaluateExpression(expression, isFunction, true, arg);
const result = await handle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);
handle.dispose();
return result;
}

async _$$evalExpression(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evalOnSelectorAllAndWaitForSignals(selector: string, expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
const arrayHandle = await this._page.selectors._queryArray(this, selector);
const result = await arrayHandle.evaluateExpression(expression, isFunction, true, arg);
const result = await arrayHandle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);
arrayHandle.dispose();
return result;
}
Expand Down
12 changes: 10 additions & 2 deletions src/server/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ export class ExecutionContext extends SdkObject {
this._delegate = delegate;
}

async waitForSignalsCreatedBy<T>(action: () => Promise<T>): Promise<T> {
return action();
}

adoptIfNeeded(handle: JSHandle): Promise<JSHandle> | null {
return null;
}
Expand Down Expand Up @@ -122,8 +126,8 @@ export class JSHandle<T = any> extends SdkObject {
return evaluate(this._context, false /* returnByValue */, pageFunction, this, arg);
}

async evaluateExpression(expression: string, isFunction: boolean | undefined, returnByValue: boolean, arg: any) {
const value = await evaluateExpression(this._context, returnByValue, expression, isFunction, this, arg);
async evaluateExpressionAndWaitForSignals(expression: string, isFunction: boolean | undefined, returnByValue: boolean, arg: any) {
const value = await evaluateExpressionAndWaitForSignals(this._context, returnByValue, expression, isFunction, this, arg);
await this._context.doSlowMo();
return value;
}
Expand Down Expand Up @@ -225,6 +229,10 @@ export async function evaluateExpression(context: ExecutionContext, returnByValu
}
}

export async function evaluateExpressionAndWaitForSignals(context: ExecutionContext, returnByValue: boolean, expression: string, isFunction?: boolean, ...args: any[]): Promise<any> {
return await context.waitForSignalsCreatedBy(() => evaluateExpression(context, returnByValue, expression, isFunction, ...args));
}

export function parseUnserializableValue(unserializableValue: string): any {
if (unserializableValue === 'NaN')
return NaN;
Expand Down
4 changes: 2 additions & 2 deletions src/server/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,11 +528,11 @@ export class Worker extends SdkObject {
return this._url;
}

async _evaluateExpression(expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evaluateExpression(expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
return js.evaluateExpression(await this._executionContextPromise, true /* returnByValue */, expression, isFunction, arg);
}

async _evaluateExpressionHandle(expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
async evaluateExpressionHandle(expression: string, isFunction: boolean | undefined, arg: any): Promise<any> {
return js.evaluateExpression(await this._executionContextPromise, false /* returnByValue */, expression, isFunction, arg);
}
}
Expand Down
Loading

0 comments on commit 5ae731a

Please sign in to comment.