mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: introduce evaluateInUtility private api (#3907)
This is an experimental client-side api. We'll experiment with it in plugins like tracing.
This commit is contained in:
parent
36f2420b0f
commit
dc06f0a75c
@ -176,6 +176,16 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _evaluateHandleInUtility<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<SmartHandle<R>>;
|
||||||
|
async _evaluateHandleInUtility<R>(pageFunction: Func1<void, R>, arg?: any): Promise<SmartHandle<R>>;
|
||||||
|
async _evaluateHandleInUtility<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<SmartHandle<R>> {
|
||||||
|
assertMaxArguments(arguments.length, 2);
|
||||||
|
return this._wrapApiCall(this._apiName('_evaluateHandleInUtility'), async () => {
|
||||||
|
const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' });
|
||||||
|
return JSHandle.from(result.handle) as SmartHandle<R>;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R>;
|
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R>;
|
||||||
async evaluate<R>(pageFunction: Func1<void, R>, arg?: any): Promise<R>;
|
async evaluate<R>(pageFunction: Func1<void, R>, arg?: any): Promise<R>;
|
||||||
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R> {
|
async evaluate<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R> {
|
||||||
@ -186,6 +196,16 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _evaluateInUtility<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R>;
|
||||||
|
async _evaluateInUtility<R>(pageFunction: Func1<void, R>, arg?: any): Promise<R>;
|
||||||
|
async _evaluateInUtility<R, Arg>(pageFunction: Func1<Arg, R>, arg: Arg): Promise<R> {
|
||||||
|
assertMaxArguments(arguments.length, 2);
|
||||||
|
return this._wrapApiCall(this._apiName('evaluate'), async () => {
|
||||||
|
const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg), world: 'utility' });
|
||||||
|
return parseResult(result.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async $(selector: string): Promise<ElementHandle<Element> | null> {
|
async $(selector: string): Promise<ElementHandle<Element> | null> {
|
||||||
return this._wrapApiCall(this._apiName('$'), async () => {
|
return this._wrapApiCall(this._apiName('$'), async () => {
|
||||||
const result = await this._channel.querySelector({ selector });
|
const result = await this._channel.querySelector({ selector });
|
||||||
|
@ -93,7 +93,7 @@ function waitForEvent<T = void>(emitter: EventEmitter, event: string, predicate?
|
|||||||
}
|
}
|
||||||
|
|
||||||
function waitForTimeout(timeout: number): { promise: Promise<void>, dispose: () => void } {
|
function waitForTimeout(timeout: number): { promise: Promise<void>, dispose: () => void } {
|
||||||
let timeoutId: number;
|
let timeoutId: any;
|
||||||
const promise = new Promise<void>(resolve => timeoutId = setTimeout(resolve, timeout));
|
const promise = new Promise<void>(resolve => timeoutId = setTimeout(resolve, timeout));
|
||||||
const dispose = () => clearTimeout(timeoutId);
|
const dispose = () => clearTimeout(timeoutId);
|
||||||
return { promise, dispose };
|
return { promise, dispose };
|
||||||
|
@ -65,11 +65,11 @@ export class FrameDispatcher extends Dispatcher<Frame, channels.FrameInitializer
|
|||||||
}
|
}
|
||||||
|
|
||||||
async evaluateExpression(params: channels.FrameEvaluateExpressionParams): Promise<channels.FrameEvaluateExpressionResult> {
|
async evaluateExpression(params: channels.FrameEvaluateExpressionParams): Promise<channels.FrameEvaluateExpressionResult> {
|
||||||
return { value: serializeResult(await this._frame._evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg))) };
|
return { value: serializeResult(await this._frame._evaluateExpression(params.expression, params.isFunction, parseArgument(params.arg), params.world)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
async evaluateExpressionHandle(params: channels.FrameEvaluateExpressionHandleParams): Promise<channels.FrameEvaluateExpressionHandleResult> {
|
async evaluateExpressionHandle(params: channels.FrameEvaluateExpressionHandleParams): Promise<channels.FrameEvaluateExpressionHandleResult> {
|
||||||
return { handle: createHandle(this._scope, await this._frame._evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg))) };
|
return { handle: createHandle(this._scope, await this._frame._evaluateExpressionHandle(params.expression, params.isFunction, parseArgument(params.arg), params.world)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForSelector(params: channels.FrameWaitForSelectorParams): Promise<channels.FrameWaitForSelectorResult> {
|
async waitForSelector(params: channels.FrameWaitForSelectorParams): Promise<channels.FrameWaitForSelectorResult> {
|
||||||
|
@ -1264,9 +1264,10 @@ export type FrameEvaluateExpressionParams = {
|
|||||||
expression: string,
|
expression: string,
|
||||||
isFunction: boolean,
|
isFunction: boolean,
|
||||||
arg: SerializedArgument,
|
arg: SerializedArgument,
|
||||||
|
world?: 'main' | 'utility',
|
||||||
};
|
};
|
||||||
export type FrameEvaluateExpressionOptions = {
|
export type FrameEvaluateExpressionOptions = {
|
||||||
|
world?: 'main' | 'utility',
|
||||||
};
|
};
|
||||||
export type FrameEvaluateExpressionResult = {
|
export type FrameEvaluateExpressionResult = {
|
||||||
value: SerializedValue,
|
value: SerializedValue,
|
||||||
@ -1275,9 +1276,10 @@ export type FrameEvaluateExpressionHandleParams = {
|
|||||||
expression: string,
|
expression: string,
|
||||||
isFunction: boolean,
|
isFunction: boolean,
|
||||||
arg: SerializedArgument,
|
arg: SerializedArgument,
|
||||||
|
world?: 'main' | 'utility',
|
||||||
};
|
};
|
||||||
export type FrameEvaluateExpressionHandleOptions = {
|
export type FrameEvaluateExpressionHandleOptions = {
|
||||||
|
world?: 'main' | 'utility',
|
||||||
};
|
};
|
||||||
export type FrameEvaluateExpressionHandleResult = {
|
export type FrameEvaluateExpressionHandleResult = {
|
||||||
handle: JSHandleChannel,
|
handle: JSHandleChannel,
|
||||||
|
@ -1049,6 +1049,11 @@ Frame:
|
|||||||
expression: string
|
expression: string
|
||||||
isFunction: boolean
|
isFunction: boolean
|
||||||
arg: SerializedArgument
|
arg: SerializedArgument
|
||||||
|
world:
|
||||||
|
type: enum?
|
||||||
|
literals:
|
||||||
|
- main
|
||||||
|
- utility
|
||||||
returns:
|
returns:
|
||||||
value: SerializedValue
|
value: SerializedValue
|
||||||
|
|
||||||
@ -1057,6 +1062,11 @@ Frame:
|
|||||||
expression: string
|
expression: string
|
||||||
isFunction: boolean
|
isFunction: boolean
|
||||||
arg: SerializedArgument
|
arg: SerializedArgument
|
||||||
|
world:
|
||||||
|
type: enum?
|
||||||
|
literals:
|
||||||
|
- main
|
||||||
|
- utility
|
||||||
returns:
|
returns:
|
||||||
handle: JSHandle
|
handle: JSHandle
|
||||||
|
|
||||||
|
@ -493,11 +493,13 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
|||||||
expression: tString,
|
expression: tString,
|
||||||
isFunction: tBoolean,
|
isFunction: tBoolean,
|
||||||
arg: tType('SerializedArgument'),
|
arg: tType('SerializedArgument'),
|
||||||
|
world: tOptional(tEnum(['main', 'utility'])),
|
||||||
});
|
});
|
||||||
scheme.FrameEvaluateExpressionHandleParams = tObject({
|
scheme.FrameEvaluateExpressionHandleParams = tObject({
|
||||||
expression: tString,
|
expression: tString,
|
||||||
isFunction: tBoolean,
|
isFunction: tBoolean,
|
||||||
arg: tType('SerializedArgument'),
|
arg: tType('SerializedArgument'),
|
||||||
|
world: tOptional(tEnum(['main', 'utility'])),
|
||||||
});
|
});
|
||||||
scheme.FrameFillParams = tObject({
|
scheme.FrameFillParams = tObject({
|
||||||
selector: tString,
|
selector: tString,
|
||||||
|
@ -523,17 +523,19 @@ export class Frame extends EventEmitter {
|
|||||||
return this._context('utility');
|
return this._context('utility');
|
||||||
}
|
}
|
||||||
|
|
||||||
async _evaluateExpressionHandle(expression: string, isFunction: boolean, arg: any): Promise<any> {
|
async _evaluateExpressionHandle(expression: string, isFunction: boolean, arg: any, world: types.World = 'main'): Promise<any> {
|
||||||
const context = await this._mainContext();
|
const context = await this._context(world);
|
||||||
const handle = await context.evaluateExpressionHandleInternal(expression, isFunction, arg);
|
const handle = await context.evaluateExpressionHandleInternal(expression, isFunction, arg);
|
||||||
await this._page._doSlowMo();
|
if (world === 'main')
|
||||||
|
await this._page._doSlowMo();
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _evaluateExpression(expression: string, isFunction: boolean, arg: any): Promise<any> {
|
async _evaluateExpression(expression: string, isFunction: boolean, arg: any, world: types.World = 'main'): Promise<any> {
|
||||||
const context = await this._mainContext();
|
const context = await this._context(world);
|
||||||
const value = await context.evaluateExpressionInternal(expression, isFunction, arg);
|
const value = await context.evaluateExpressionInternal(expression, isFunction, arg);
|
||||||
await this._page._doSlowMo();
|
if (world === 'main')
|
||||||
|
await this._page._doSlowMo();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
import { it, expect, options } from './playwright.fixtures';
|
import { it, expect, options } from './playwright.fixtures';
|
||||||
|
|
||||||
import utils from './utils';
|
import utils from './utils';
|
||||||
|
import type { Frame } from '../src/client/frame';
|
||||||
|
|
||||||
it('should have different execution contexts', async ({ page, server }) => {
|
it('should have different execution contexts', async ({ page, server }) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
@ -180,3 +181,23 @@ it('evaluateHandle should work', async ({page, server}) => {
|
|||||||
const windowHandle = await mainFrame.evaluateHandle(() => window);
|
const windowHandle = await mainFrame.evaluateHandle(() => window);
|
||||||
expect(windowHandle).toBeTruthy();
|
expect(windowHandle).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('evaluateInUtility should work', async ({page}) => {
|
||||||
|
await page.setContent('<body>hello</body>');
|
||||||
|
const mainFrame = page.mainFrame() as any as Frame;
|
||||||
|
await mainFrame.evaluate(() => window['foo'] = 42);
|
||||||
|
expect(await mainFrame.evaluate(() => window['foo'])).toBe(42);
|
||||||
|
expect(await mainFrame._evaluateInUtility(() => window['foo'])).toBe(undefined);
|
||||||
|
expect(await mainFrame._evaluateInUtility(() => document.body.textContent)).toBe('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('evaluateHandleInUtility should work', async ({page}) => {
|
||||||
|
await page.setContent('<body>hello</body>');
|
||||||
|
const mainFrame = page.mainFrame() as any as Frame;
|
||||||
|
await mainFrame.evaluate(() => window['foo'] = 42);
|
||||||
|
expect(await mainFrame.evaluate(() => window['foo'])).toBe(42);
|
||||||
|
const handle1 = await mainFrame._evaluateHandleInUtility(() => window['foo']);
|
||||||
|
expect(await handle1.jsonValue()).toBe(undefined);
|
||||||
|
const handle2 = await mainFrame._evaluateHandleInUtility(() => document.body);
|
||||||
|
expect(await handle2.evaluate(body => body.textContent)).toBe('hello');
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user