diff --git a/docs/src/api/class-frame.md b/docs/src/api/class-frame.md index de7735b599bdc..b13d3aa9e6d20 100644 --- a/docs/src/api/class-frame.md +++ b/docs/src/api/class-frame.md @@ -757,9 +757,6 @@ Optional argument to pass to [`param: expression`]. ### option: Frame.evaluate.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Frame.evaluate.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ### option: Frame.evaluate.world = %%-js-evaluate-world-%% * since: v1.64 @@ -878,9 +875,6 @@ Optional argument to pass to [`param: expression`]. ### option: Frame.evaluateHandle.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Frame.evaluateHandle.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ## async method: Frame.fill * since: v1.8 * discouraged: Use locator-based [`method: Locator.fill`] instead. Read more about [locators](../locators.md). diff --git a/docs/src/api/class-jshandle.md b/docs/src/api/class-jshandle.md index 9910841d11874..5a883bf8892d6 100644 --- a/docs/src/api/class-jshandle.md +++ b/docs/src/api/class-jshandle.md @@ -99,9 +99,6 @@ Optional argument to pass to [`param: expression`]. ### option: JSHandle.evaluate.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: JSHandle.evaluate.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ## async method: JSHandle.evaluateHandle * since: v1.8 - returns: <[JSHandle]> @@ -132,9 +129,6 @@ Optional argument to pass to [`param: expression`]. ### option: JSHandle.evaluateHandle.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: JSHandle.evaluateHandle.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ## async method: JSHandle.getProperties * since: v1.8 - returns: <[Map]<[string], [JSHandle]>> diff --git a/docs/src/api/class-locator.md b/docs/src/api/class-locator.md index 22f5dfbee7a2e..a92f8d0c8021c 100644 --- a/docs/src/api/class-locator.md +++ b/docs/src/api/class-locator.md @@ -1181,9 +1181,6 @@ Optional argument to pass to [`param: expression`]. ### option: Locator.evaluate.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Locator.evaluate.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ### option: Locator.evaluate.world = %%-js-evaluate-world-%% * since: v1.64 @@ -1292,9 +1289,6 @@ Optional argument to pass to [`param: expression`]. ### option: Locator.evaluateHandle.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Locator.evaluateHandle.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ### option: Locator.evaluateHandle.timeout * since: v1.14 * langs: python, java, csharp diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index 6d8a65d002613..03d1f91fc1632 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -1608,9 +1608,6 @@ Optional argument to pass to [`param: expression`]. ### option: Page.evaluate.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Page.evaluate.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ### option: Page.evaluate.world = %%-js-evaluate-world-%% * since: v1.64 @@ -1726,9 +1723,6 @@ Optional argument to pass to [`param: expression`]. ### option: Page.evaluateHandle.exposeFunctions = %%-js-evaluate-expose-functions-%% * since: v1.62 -### option: Page.evaluateHandle.serialize = %%-js-evaluate-serialize-%% -* since: v1.64 - ## async method: Page.exposeBinding * since: v1.8 - returns: <[Disposable]> diff --git a/docs/src/api/params.md b/docs/src/api/params.md index e8e4080e1e8be..89e14b0a57200 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -590,12 +590,6 @@ to a function, the function is automatically invoked. Function to be evaluated in the page context. -## js-evaluate-serialize -* langs: js -- `serialize` <[Array]<[SerializationType]<"Map"|"Set">>> - -Additional built-in types to preserve in the evaluation argument and return value, including nested collections and circular references. Supports `"Map"` and `"Set"`. For example, `serialize: ['Map', 'Set']` preserves both [Map] and [Set] instances. Defaults to an empty array, in which case these types are serialized as plain objects. - ## js-evaluate-expose-functions * langs: js - `exposeFunctions` <[boolean]> diff --git a/packages/injected/src/storageScript.ts b/packages/injected/src/storageScript.ts index 6f917aa2681e6..efb3054cef573 100644 --- a/packages/injected/src/storageScript.ts +++ b/packages/injected/src/storageScript.ts @@ -78,7 +78,7 @@ export class StorageScript { trivial = false; return { fallThrough: v }; - }, { serialize: ['Map', 'Set'] }); + }, { extendedSerialization: true }); if (trivial) return { trivial: value }; return { encoded }; diff --git a/packages/injected/src/utilityScript.ts b/packages/injected/src/utilityScript.ts index af98c76550a61..5c257ef25d7ca 100644 --- a/packages/injected/src/utilityScript.ts +++ b/packages/injected/src/utilityScript.ts @@ -65,7 +65,7 @@ export class UtilityScript { (global as any).builtins = this.builtins; } - evaluate(isFunction: boolean | undefined, returnByValue: boolean, serialize: ('Map' | 'Set')[] | undefined, expression: string, argCount: number, ...argsAndHandles: any[]) { + evaluate(isFunction: boolean | undefined, returnByValue: boolean, expression: string, argCount: number, ...argsAndHandles: any[]) { const args = argsAndHandles.slice(0, argCount); const handles = argsAndHandles.slice(argCount); const parameters = []; @@ -82,20 +82,20 @@ export class UtilityScript { if (typeof result === 'function') result = result(...parameters); } - return returnByValue ? this._promiseAwareJsonValueNoThrow(result, serialize) : result; + return returnByValue ? this._promiseAwareJsonValueNoThrow(result) : result; } - jsonValue(returnByValue: true, value: any, serialize?: ('Map' | 'Set')[]) { + jsonValue(returnByValue: true, value: any) { // Special handling of undefined to work-around multi-step returnByValue handling in WebKit. if (value === undefined) return undefined; - return serializeAsCallArgument(value, (value: any) => ({ fallThrough: value }), { serialize }); + return serializeAsCallArgument(value, (value: any) => ({ fallThrough: value })); } - private _promiseAwareJsonValueNoThrow(value: any, serialize?: ('Map' | 'Set')[]) { + private _promiseAwareJsonValueNoThrow(value: any) { const safeJson = (value: any) => { try { - return this.jsonValue(true, value, serialize); + return this.jsonValue(true, value); } catch (e) { return undefined; } diff --git a/packages/isomorphic/utilityScriptSerializers.ts b/packages/isomorphic/utilityScriptSerializers.ts index 6027e77e1f5a7..7132bc86266a0 100644 --- a/packages/isomorphic/utilityScriptSerializers.ts +++ b/packages/isomorphic/utilityScriptSerializers.ts @@ -46,7 +46,7 @@ type HandleOrValue = { h: number } | { fn: string } | { fallThrough: any }; type VisitorInfo = { visited: Map; lastId: number; - serialize?: ('Map' | 'Set')[]; + extendedSerialization?: boolean; }; function isRegExp(obj: any): obj is RegExp { @@ -231,8 +231,8 @@ export function parseEvaluationResultValue(value: SerializedValue, handles: any[ return value; } -export function serializeAsCallArgument(value: any, handleSerializer: (value: any) => HandleOrValue, options: { serialize?: ('Map' | 'Set')[] } = {}): SerializedValue { - return serialize(value, handleSerializer, { visited: new Map(), lastId: 0, serialize: options.serialize }); +export function serializeAsCallArgument(value: any, handleSerializer: (value: any) => HandleOrValue, options: { extendedSerialization?: boolean } = {}): SerializedValue { + return serialize(value, handleSerializer, { visited: new Map(), lastId: 0, extendedSerialization: options.extendedSerialization }); } function serialize(value: any, handleSerializer: (value: any) => HandleOrValue, visitorInfo: VisitorInfo): SerializedValue { @@ -308,33 +308,35 @@ function innerSerialize(value: any, handleSerializer: (value: any) => HandleOrVa if (id) return { ref: id }; - if (visitorInfo.serialize?.includes('Map') && isMap(value)) { - const m: { k: SerializedValue, v: SerializedValue }[] = []; - const id = ++visitorInfo.lastId; - visitorInfo.visited.set(value, id); - const iterator = value.entries(); - const next = new Map().entries().next; - while (true) { - const entry = next.call(iterator); - if (entry.done) - break; - m.push({ k: serialize(entry.value[0], handleSerializer, visitorInfo), v: serialize(entry.value[1], handleSerializer, visitorInfo) }); + if (visitorInfo.extendedSerialization) { + if (isMap(value)) { + const m: { k: SerializedValue, v: SerializedValue }[] = []; + const id = ++visitorInfo.lastId; + visitorInfo.visited.set(value, id); + const iterator = value.entries(); + const next = new Map().entries().next; + while (true) { + const entry = next.call(iterator); + if (entry.done) + break; + m.push({ k: serialize(entry.value[0], handleSerializer, visitorInfo), v: serialize(entry.value[1], handleSerializer, visitorInfo) }); + } + return { m, id }; } - return { m, id }; - } - if (visitorInfo.serialize?.includes('Set') && isSet(value)) { - const s: SerializedValue[] = []; - const id = ++visitorInfo.lastId; - visitorInfo.visited.set(value, id); - const iterator = value.values(); - const next = new Set().values().next; - while (true) { - const entry = next.call(iterator); - if (entry.done) - break; - s.push(serialize(entry.value, handleSerializer, visitorInfo)); + if (isSet(value)) { + const s: SerializedValue[] = []; + const id = ++visitorInfo.lastId; + visitorInfo.visited.set(value, id); + const iterator = value.values(); + const next = new Set().values().next; + while (true) { + const entry = next.call(iterator); + if (entry.done) + break; + s.push(serialize(entry.value, handleSerializer, visitorInfo)); + } + return { s, id }; } - return { s, id }; } if (Array.isArray(value)) { diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index 34b649bf75716..63634431f02f4 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -134,7 +134,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the value of the * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression) invocation. @@ -187,7 +187,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the value of the @@ -235,7 +235,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the value of the * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression) invocation as a @@ -282,7 +282,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * Adds a script which would be evaluated in one of the following scenarios: @@ -5988,7 +5988,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). @@ -6037,7 +6037,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the return value of @@ -6087,7 +6087,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression) as a @@ -6136,7 +6136,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator) @@ -12101,7 +12101,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; + evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). @@ -12124,7 +12124,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; + evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise; /** * Returns the return value of @@ -12148,7 +12148,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression) @@ -12171,7 +12171,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**. @@ -14366,7 +14366,7 @@ export interface Locator { * [`pageFunction`](https://playwright.dev/docs/api/class-locator#locator-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Execute JavaScript code in the page, taking the matching element as an argument, and return a * [JSHandle](https://playwright.dev/docs/api/class-jshandle) with the result. @@ -14400,7 +14400,7 @@ export interface Locator { * [`pageFunction`](https://playwright.dev/docs/api/class-locator#locator-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean }): Promise>; /** * Execute JavaScript code in the page, taking all matching elements as an argument. * diff --git a/packages/playwright-core/src/client/channels.d.ts b/packages/playwright-core/src/client/channels.d.ts index 91c4df4d4fec2..c6603cfad0cfc 100644 --- a/packages/playwright-core/src/client/channels.d.ts +++ b/packages/playwright-core/src/client/channels.d.ts @@ -2566,12 +2566,10 @@ export type FrameEvaluateExpressionParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type FrameEvaluateExpressionOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type FrameEvaluateExpressionResult = { @@ -2581,11 +2579,9 @@ export type FrameEvaluateExpressionHandleParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], }; export type FrameEvaluateExpressionHandleOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], }; export type FrameEvaluateExpressionHandleResult = { handle: JSHandleChannel, @@ -3060,12 +3056,10 @@ export type JSHandleEvaluateExpressionParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type JSHandleEvaluateExpressionOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type JSHandleEvaluateExpressionResult = { @@ -3075,11 +3069,9 @@ export type JSHandleEvaluateExpressionHandleParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], }; export type JSHandleEvaluateExpressionHandleOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], }; export type JSHandleEvaluateExpressionHandleResult = { handle: JSHandleChannel, diff --git a/packages/playwright-core/src/client/frame.ts b/packages/playwright-core/src/client/frame.ts index accf6079cf8ec..1dea08fa16476 100644 --- a/packages/playwright-core/src/client/frame.ts +++ b/packages/playwright-core/src/client/frame.ts @@ -36,7 +36,7 @@ import { Waiter } from './waiter'; import { WebMCP } from './webmcp'; import { TimeoutSettings, kNoTimeout } from './timeoutSettings'; -import type { EvaluateOptions, EvaluateHandleOptions, WorldOptions } from './jsHandle'; +import type { EvaluateOptions, ExposeFunctionsOptions, WorldOptions } from './jsHandle'; import type { LocatorOptions } from './locator'; import type { Page } from './page'; import type { DropPayload, FilePayload, LifecycleEvent, SelectOption, SelectOptionOptions, StrictOptions, TimeoutOptions, WaitForFunctionOptions } from './types'; @@ -210,19 +210,19 @@ export class Frame extends ChannelOwner implements api.Fr return ElementHandle.from((await this._channel.frameElement({}, kNoTimeout)).element); } - async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg, options?: EvaluateHandleOptions): Promise> { + async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg, options?: ExposeFunctionsOptions): Promise> { assertMaxArguments(arguments.length, 3); assertEvaluateOptions(options); - const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._page, arg, options) : serializeArgument(arg, undefined, options); - const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, serialize: options?.serialize }, kNoTimeout); + const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._page, arg) : serializeArgument(arg); + const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg }, kNoTimeout); return JSHandle.from(result.handle) as any as structs.SmartHandle; } async evaluate(pageFunction: structs.PageFunction, arg?: Arg, options?: EvaluateOptions): Promise { assertMaxArguments(arguments.length, 3); assertEvaluateOptions(options); - const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._page, arg, options) : serializeArgument(arg, undefined, options); - const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, world: options?.world, serialize: options?.serialize }, kNoTimeout); + const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._page, arg) : serializeArgument(arg); + const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, world: options?.world }, kNoTimeout); return parseResult(result.value); } diff --git a/packages/playwright-core/src/client/jsHandle.ts b/packages/playwright-core/src/client/jsHandle.ts index bfcf903b63e09..8a73882ce7bc6 100644 --- a/packages/playwright-core/src/client/jsHandle.ts +++ b/packages/playwright-core/src/client/jsHandle.ts @@ -40,22 +40,22 @@ export class JSHandle extends ChannelOwner im this._channel.on('previewUpdated', ({ preview }) => this._preview = preview); } - async evaluate(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: EvaluateHandleOptions): Promise { + async evaluate(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: ExposeFunctionsOptions): Promise { assertEvaluateOptions(options); - return await this._evaluate(pageFunction, arg, { exposeFunctions: options?.exposeFunctions, serialize: options?.serialize }); + return await this._evaluate(pageFunction, arg, { exposeFunctions: options?.exposeFunctions }); } async _evaluate(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: EvaluateOptions): Promise { assertEvaluateOptions(options); - const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._parentOfType('Page') as Page | undefined, arg, options) : serializeArgument(arg, undefined, options); - const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, world: options?.world, serialize: options?.serialize }, kNoTimeout); + const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._parentOfType('Page') as Page | undefined, arg) : serializeArgument(arg); + const result = await this._channel.evaluateExpression({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, world: options?.world }, kNoTimeout); return parseResult(result.value); } - async evaluateHandle(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: EvaluateHandleOptions): Promise> { + async evaluateHandle(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: ExposeFunctionsOptions): Promise> { assertEvaluateOptions(options); - const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._parentOfType('Page') as Page | undefined, arg, options) : serializeArgument(arg, undefined, options); - const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg, serialize: options?.serialize }, kNoTimeout); + const serializedArg = options?.exposeFunctions ? await serializeArgumentWithCallbacks(this, this._parentOfType('Page') as Page | undefined, arg) : serializeArgument(arg); + const result = await this._channel.evaluateExpressionHandle({ expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializedArg }, kNoTimeout); return JSHandle.from(result.handle) as any as structs.SmartHandle; } @@ -100,7 +100,7 @@ export class JSHandle extends ChannelOwner im // This function takes care of converting all JSHandles to their channels, // so that generic channel serializer converts them to guids. -export function serializeArgument(arg: any, registerCallback?: (callback: Function) => string, options?: SerializationOptions): channels.SerializedArgument { +export function serializeArgument(arg: any, registerCallback?: (callback: Function) => string): channels.SerializedArgument { const handles: channels.Channel[] = []; const pushHandle = (channel: channels.Channel): number => { handles.push(channel); @@ -112,17 +112,15 @@ export function serializeArgument(arg: any, registerCallback?: (callback: Functi if (typeof value === 'function' && registerCallback) return { fn: registerCallback(value as Function) }; return { fallThrough: value }; - }, options); + }); return { value, handles }; } export type WorldOptions = { world?: 'main' | 'utility' }; export type ExposeFunctionsOptions = { exposeFunctions?: boolean }; -export type SerializationOptions = { serialize?: ('Map' | 'Set')[] }; -export type EvaluateHandleOptions = ExposeFunctionsOptions & SerializationOptions; -export type EvaluateOptions = EvaluateHandleOptions & WorldOptions; +export type EvaluateOptions = ExposeFunctionsOptions & WorldOptions; -export async function serializeArgumentWithCallbacks(owner: ChannelOwner, page: Page | undefined, arg: any, options?: SerializationOptions): Promise { +export async function serializeArgumentWithCallbacks(owner: ChannelOwner, page: Page | undefined, arg: any): Promise { return await owner._wrapApiCall(async () => { const exposePromises: Promise[] = []; const serialized = serializeArgument(arg, callback => { @@ -131,7 +129,7 @@ export async function serializeArgumentWithCallbacks(owner: ChannelOwner, p const name = kFunctionBindingPrefix + createGuid(); exposePromises.push(page._exposeEvaluateCallback(name, callback)); return name; - }, options); + }); await Promise.all(exposePromises); return serialized; }, { internal: true }); @@ -149,8 +147,6 @@ export function assertMaxArguments(count: number, max: number): asserts count { export function assertEvaluateOptions(options: any) { if (options !== undefined && (typeof options !== 'object' || options === null || Array.isArray(options))) throw new Error('Too many arguments. If you need to pass more than 1 argument to the function wrap them in an object.'); - if (options?.serialize !== undefined && (!Array.isArray(options.serialize) || options.serialize.some((type: unknown) => type !== 'Map' && type !== 'Set'))) - throw new Error('serialize: expected an array of (Map|Set)'); if (options?.exposeFunctions && options?.world === 'utility') throw new Error('Option "exposeFunctions" is not supported in the "utility" world.'); } diff --git a/packages/playwright-core/src/client/locator.ts b/packages/playwright-core/src/client/locator.ts index c282a1484eb15..caf2ba828a4d8 100644 --- a/packages/playwright-core/src/client/locator.ts +++ b/packages/playwright-core/src/client/locator.ts @@ -28,7 +28,7 @@ import { DisposableStub } from './disposable'; import { kNoTimeout } from './timeoutSettings'; import type { ExpectResult, Frame } from './frame'; -import type { EvaluateOptions, EvaluateHandleOptions, WorldOptions } from './jsHandle'; +import type { EvaluateOptions, ExposeFunctionsOptions, WorldOptions } from './jsHandle'; import type { DropPayload, FilePayload, FrameExpectParams, Rect, SelectOption, SelectOptionOptions, TimeoutOptions } from './types'; import type * as structs from '../../types/structs'; import type * as api from '../../types/types'; @@ -145,7 +145,7 @@ export class Locator implements api.Locator { return await this._frame.$$eval(this._selector, pageFunction, arg, options); } - async evaluateHandle(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: TimeoutOptions & EvaluateHandleOptions): Promise> { + async evaluateHandle(pageFunction: structs.PageFunctionOn, arg?: Arg, options?: TimeoutOptions & ExposeFunctionsOptions): Promise> { return await this._withElement(h => h.evaluateHandle(pageFunction, arg, options), { title: 'Evaluate', timeout: options?.timeout, signal: options?.signal }); } diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 7a3d6fad752bd..9b08fbf3298e9 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -50,7 +50,7 @@ import { TimeoutSettings, kNoTimeout } from './timeoutSettings'; import { mkdirIfNeeded } from './fileUtils'; import { ConsoleMessage } from './consoleMessage'; import type { BrowserContext } from './browserContext'; -import type { EvaluateOptions, EvaluateHandleOptions, ExposeFunctionsOptions, WorldOptions } from './jsHandle'; +import type { EvaluateOptions, ExposeFunctionsOptions, WorldOptions } from './jsHandle'; import type { Clock } from './clock'; import type { APIRequestContext } from './fetch'; import type { WaitForNavigationOptions } from './frame'; @@ -341,7 +341,7 @@ export class Page extends ChannelOwner implements api.Page return await this._mainFrame.dispatchEvent(selector, type, eventInit, options); } - async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg, options?: EvaluateHandleOptions): Promise> { + async evaluateHandle(pageFunction: structs.PageFunction, arg?: Arg, options?: ExposeFunctionsOptions): Promise> { assertMaxArguments(arguments.length, 3); return await this._mainFrame.evaluateHandle(pageFunction, arg, options); } diff --git a/packages/playwright-core/src/server/channels.d.ts b/packages/playwright-core/src/server/channels.d.ts index f9ff479a4fd91..47fc7c62eaae2 100644 --- a/packages/playwright-core/src/server/channels.d.ts +++ b/packages/playwright-core/src/server/channels.d.ts @@ -2567,12 +2567,10 @@ export type FrameEvaluateExpressionParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type FrameEvaluateExpressionOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type FrameEvaluateExpressionResult = { @@ -2582,11 +2580,9 @@ export type FrameEvaluateExpressionHandleParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], }; export type FrameEvaluateExpressionHandleOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], }; export type FrameEvaluateExpressionHandleResult = { handle: JSHandleChannel, @@ -3061,12 +3057,10 @@ export type JSHandleEvaluateExpressionParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type JSHandleEvaluateExpressionOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], world?: 'main' | 'utility', }; export type JSHandleEvaluateExpressionResult = { @@ -3076,11 +3070,9 @@ export type JSHandleEvaluateExpressionHandleParams = { expression: string, isFunction?: boolean, arg: SerializedArgument, - serialize?: ('Map' | 'Set')[], }; export type JSHandleEvaluateExpressionHandleOptions = { isFunction?: boolean, - serialize?: ('Map' | 'Set')[], }; export type JSHandleEvaluateExpressionHandleResult = { handle: JSHandleChannel, diff --git a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts index 3268ee07ded29..f724a147750e6 100644 --- a/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/elementHandlerDispatcher.ts @@ -56,8 +56,8 @@ export class ElementHandleDispatcher extends JSHandleDispatcher } override async evaluateExpression(params: channels.JSHandleEvaluateExpressionParams, progress: Progress): Promise { - const value = await this._elementHandle.evaluateExpression(progress, params.expression, { isFunction: params.isFunction, world: params.world, serialize: params.serialize }, parseArgument(params.arg)); - return { value: serializeResult(value, params) }; + const value = await this._elementHandle.evaluateExpression(progress, params.expression, { isFunction: params.isFunction, world: params.world }, parseArgument(params.arg)); + return { value: serializeResult(value) }; } async ownerFrame(params: channels.ElementHandleOwnerFrameParams, progress: Progress): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts b/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts index f2773bc7c442f..6242949f5a44d 100644 --- a/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/frameDispatcher.ts @@ -84,11 +84,11 @@ export class FrameDispatcher extends Dispatcher { - return { value: serializeResult(await this._frame.evaluateExpression(progress, params.expression, { isFunction: params.isFunction, world: params.world, serialize: params.serialize }, parseArgument(params.arg)), params) }; + return { value: serializeResult(await this._frame.evaluateExpression(progress, params.expression, { isFunction: params.isFunction, world: params.world }, parseArgument(params.arg))) }; } async evaluateExpressionHandle(params: channels.FrameEvaluateExpressionHandleParams, progress: Progress): Promise { - return { handle: ElementHandleDispatcher.fromJSOrElementHandle(this, await this._frame.evaluateExpressionHandle(progress, params.expression, { isFunction: params.isFunction, serialize: params.serialize }, parseArgument(params.arg))) }; + return { handle: ElementHandleDispatcher.fromJSOrElementHandle(this, await this._frame.evaluateExpressionHandle(progress, params.expression, { isFunction: params.isFunction }, parseArgument(params.arg))) }; } async waitForSelector(params: channels.FrameWaitForSelectorParams, progress: Progress): Promise { diff --git a/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts b/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts index 6c489f87904e3..c2aa99a892d0c 100644 --- a/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/jsHandleDispatcher.ts @@ -45,12 +45,12 @@ export class JSHandleDispatcher { if (params.world) throw new Error(`Only element handles can be evaluated in the "${params.world}" world`); - const jsHandle = await this._object.evaluateExpression(progress, params.expression, { isFunction: params.isFunction, serialize: params.serialize }, parseArgument(params.arg)); - return { value: serializeResult(jsHandle, params) }; + const jsHandle = await this._object.evaluateExpression(progress, params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)); + return { value: serializeResult(jsHandle) }; } async evaluateExpressionHandle(params: channels.JSHandleEvaluateExpressionHandleParams, progress: Progress): Promise { - const jsHandle = await this._object.evaluateExpressionHandle(progress, params.expression, { isFunction: params.isFunction, serialize: params.serialize }, parseArgument(params.arg)); + const jsHandle = await this._object.evaluateExpressionHandle(progress, params.expression, { isFunction: params.isFunction }, parseArgument(params.arg)); // If "jsHandle" is an ElementHandle, it belongs to the same frame as "this". return { handle: ElementHandleDispatcher.fromJSOrElementHandle(this.parentScope() as FrameDispatcher, jsHandle) }; } @@ -91,6 +91,6 @@ export function parseValue(v: channels.SerializedValue): any { return parseSerializedValue(v, []); } -export function serializeResult(arg: any, options?: { serialize?: ('Map' | 'Set')[] }): channels.SerializedValue { - return serializeValue(arg, value => ({ fallThrough: value }), options); +export function serializeResult(arg: any): channels.SerializedValue { + return serializeValue(arg, value => ({ fallThrough: value })); } diff --git a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts index 59295be3ea38e..766da9915343c 100644 --- a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts @@ -601,7 +601,7 @@ export class BindingCallDispatcher extends Dispatcher serializeResult(arg)), + args: args.map(serializeResult), }); this._promise = new Promise((resolve, reject) => { this._resolve = resolve; diff --git a/packages/playwright-core/src/server/dom.ts b/packages/playwright-core/src/server/dom.ts index 551e9eb368e91..35c364705b15f 100644 --- a/packages/playwright-core/src/server/dom.ts +++ b/packages/playwright-core/src/server/dom.ts @@ -84,11 +84,11 @@ export class FrameExecutionContext extends js.ExecutionContext { return js.evaluate(this, false /* returnByValue */, pageFunction, arg); } - async evaluateExpression(expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg?: any): Promise { + async evaluateExpression(expression: string, options: { isFunction?: boolean }, arg?: any): Promise { return js.evaluateExpression(this, expression, { ...options, returnByValue: true }, arg); } - async evaluateExpressionHandle(expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg?: any): Promise> { + async evaluateExpressionHandle(expression: string, options: { isFunction?: boolean }, arg?: any): Promise> { return js.evaluateExpression(this, expression, { ...options, returnByValue: false }, arg); } @@ -882,13 +882,13 @@ export class ElementHandle extends js.JSHandle { return this._frame.selectors.queryAll(selector, this); } - override async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] }, arg: any): Promise { + override async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World }, arg: any): Promise { return await progress.race(this.internalEvaluateExpression(expression, options, arg)); } - override async internalEvaluateExpression(expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] }, arg: any): Promise { + override async internalEvaluateExpression(expression: string, options: { isFunction?: boolean, world?: types.World }, arg: any): Promise { const context = options.world ? await this._frame.context(options.world) : this._context; - return await js.evaluateExpression(context, expression, { isFunction: options.isFunction, serialize: options.serialize, returnByValue: true }, this, arg); + return await js.evaluateExpression(context, expression, { isFunction: options.isFunction, returnByValue: true }, this, arg); } async evalOnSelector(progress: Progress, target: types.SelectorTarget, expression: string, options: { isFunction?: boolean, world?: types.World }, arg: any): Promise { diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 3bd1af6843df5..3e635e85f5a51 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -814,21 +814,21 @@ export class Frame extends SdkObject { return this.context('utility'); } - async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] } = {}, arg?: any): Promise { + async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise { return await progress.race(this._evaluateExpression(expression, options, arg)); } - private async _evaluateExpression(expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] } = {}, arg?: any): Promise { + private async _evaluateExpression(expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise { const context = await this.context(options.world ?? 'main'); const value = await context.evaluateExpression(expression, options, arg); return value; } - async evaluateExpressionHandle(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] } = {}, arg?: any): Promise> { + async evaluateExpressionHandle(progress: Progress, expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise> { return await progress.race(this._evaluateExpressionHandle(expression, options, arg)); } - private async _evaluateExpressionHandle(expression: string, options: { isFunction?: boolean, world?: types.World, serialize?: ('Map' | 'Set')[] } = {}, arg?: any): Promise> { + private async _evaluateExpressionHandle(expression: string, options: { isFunction?: boolean, world?: types.World } = {}, arg?: any): Promise> { const context = await this.context(options.world ?? 'main'); const value = await context.evaluateExpressionHandle(expression, options, arg); return value; diff --git a/packages/playwright-core/src/server/javascript.ts b/packages/playwright-core/src/server/javascript.ts index 420d4ec669c0f..adaae310f1bf2 100644 --- a/packages/playwright-core/src/server/javascript.ts +++ b/packages/playwright-core/src/server/javascript.ts @@ -143,11 +143,11 @@ export class JSHandle extends SdkObject { (globalThis as any).leakedJSHandles.set(this, new Error('Leaked JSHandle')); } - async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg: any) { + async evaluateExpression(progress: Progress, expression: string, options: { isFunction?: boolean }, arg: any) { return await progress.race(this.internalEvaluateExpression(expression, options, arg)); } - async evaluateExpressionHandle(progress: Progress, expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg: any): Promise> { + async evaluateExpressionHandle(progress: Progress, expression: string, options: { isFunction?: boolean }, arg: any): Promise> { return await progress.race(this._evaluateExpressionHandle(expression, options, arg)); } @@ -171,11 +171,11 @@ export class JSHandle extends SdkObject { return evaluate(this._context, false /* returnByValue */, pageFunction, this, arg); } - async internalEvaluateExpression(expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg: any) { + async internalEvaluateExpression(expression: string, options: { isFunction?: boolean }, arg: any) { return await evaluateExpression(this._context, expression, { ...options, returnByValue: true }, this, arg); } - private async _evaluateExpressionHandle(expression: string, options: { isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, arg: any): Promise> { + private async _evaluateExpressionHandle(expression: string, options: { isFunction?: boolean }, arg: any): Promise> { return await evaluateExpression(this._context, expression, { ...options, returnByValue: false }, this, arg); } @@ -254,7 +254,7 @@ export async function evaluate(context: ExecutionContext, returnByValue: boolean return evaluateExpression(context, String(pageFunction), { returnByValue, isFunction: typeof pageFunction === 'function' }, ...args); } -export async function evaluateExpression(context: ExecutionContext, expression: string, options: { returnByValue?: boolean, isFunction?: boolean, serialize?: ('Map' | 'Set')[] }, ...args: any[]): Promise { +export async function evaluateExpression(context: ExecutionContext, expression: string, options: { returnByValue?: boolean, isFunction?: boolean }, ...args: any[]): Promise { expression = normalizeEvaluationExpression(expression, options.isFunction); const handles: (Promise)[] = []; const toDispose: Promise[] = []; @@ -276,7 +276,7 @@ export async function evaluateExpression(context: ExecutionContext, expression: return { h: pushHandle(adopted) }; } return { fallThrough: handle }; - }, options)); + })); const utilityScriptObjects: JSHandle[] = []; for (const handle of await Promise.all(handles)) { @@ -286,7 +286,7 @@ export async function evaluateExpression(context: ExecutionContext, expression: } // See UtilityScript for arguments. - const utilityScriptValues = [options.isFunction, options.returnByValue, options.serialize, expression, args.length, ...args]; + const utilityScriptValues = [options.isFunction, options.returnByValue, expression, args.length, ...args]; const script = `(utilityScript, ...args) => utilityScript.evaluate(...args)`; try { diff --git a/packages/playwright-core/types/structs.d.ts b/packages/playwright-core/types/structs.d.ts index a5b6c922a7a5a..3b671e99ac17b 100644 --- a/packages/playwright-core/types/structs.d.ts +++ b/packages/playwright-core/types/structs.d.ts @@ -27,8 +27,6 @@ export type EvaluationArgument = {}; export type NoHandles = Arg extends JSHandle ? never : - Arg extends Map ? Map, NoHandles> : - Arg extends Set ? Set> : Arg extends (...args: infer T) => PromiseLike ? (...args: T) => Promise> : Arg extends (...args: infer T) => infer R ? (...args: T) => NoHandles : Arg extends object ? { [Key in keyof Arg]: NoHandles } : @@ -36,8 +34,6 @@ export type NoHandles = export type Unboxed = Arg extends ElementHandle ? T : Arg extends JSHandle ? T : - Arg extends Map ? Map, Unboxed> : - Arg extends Set ? Set> : Arg extends (...args: infer T) => PromiseLike ? (...args: T) => Promise> : Arg extends (...args: infer T) => infer R ? (...args: T) => Unboxed : Arg extends NoHandles ? Arg : diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 34b649bf75716..63634431f02f4 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -134,7 +134,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the value of the * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression) invocation. @@ -187,7 +187,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the value of the @@ -235,7 +235,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the value of the * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression) invocation as a @@ -282,7 +282,7 @@ export interface Page { * [`pageFunction`](https://playwright.dev/docs/api/class-page#page-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * Adds a script which would be evaluated in one of the following scenarios: @@ -5988,7 +5988,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). @@ -6037,7 +6037,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Returns the return value of @@ -6087,7 +6087,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression) as a @@ -6136,7 +6136,7 @@ export interface Frame { * [`pageFunction`](https://playwright.dev/docs/api/class-frame#frame-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * **NOTE** Use locator-based [frame.locator(selector[, options])](https://playwright.dev/docs/api/class-frame#frame-locator) @@ -12101,7 +12101,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; + evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). @@ -12124,7 +12124,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; + evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise; /** * Returns the return value of @@ -12148,7 +12148,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns the return value of * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression) @@ -12171,7 +12171,7 @@ export interface JSHandle { * [`pageFunction`](https://playwright.dev/docs/api/class-elementhandle#element-handle-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; /** * Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**. @@ -14366,7 +14366,7 @@ export interface Locator { * [`pageFunction`](https://playwright.dev/docs/api/class-locator#locator-evaluate-option-expression). * @param options */ - evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; /** * Execute JavaScript code in the page, taking the matching element as an argument, and return a * [JSHandle](https://playwright.dev/docs/api/class-jshandle) with the result. @@ -14400,7 +14400,7 @@ export interface Locator { * [`pageFunction`](https://playwright.dev/docs/api/class-locator#locator-evaluate-handle-option-expression). * @param options */ - evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean }): Promise>; /** * Execute JavaScript code in the page, taking all matching elements as an argument. * diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index ddd84a685b970..4ea9c43c3b003 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -513,7 +513,7 @@ const playwrightFixtures: Fixtures { if (!baseURL) throw new Error('mount() requires `baseURL` to point at the component gallery. Set it in your Playwright config.'); diff --git a/packages/protocol/spec/frame.yml b/packages/protocol/spec/frame.yml index e0bea36e2ee22..dfac57e523cfe 100644 --- a/packages/protocol/spec/frame.yml +++ b/packages/protocol/spec/frame.yml @@ -339,13 +339,6 @@ Frame: expression: string isFunction: boolean? arg: SerializedArgument - serialize: - type: array? - items: - type: enum - literals: - - Map - - Set world: type: enum? literals: @@ -363,13 +356,6 @@ Frame: expression: string isFunction: boolean? arg: SerializedArgument - serialize: - type: array? - items: - type: enum - literals: - - Map - - Set returns: handle: JSHandle flags: diff --git a/packages/protocol/spec/handles.yml b/packages/protocol/spec/handles.yml index 15e17c3ecf6fc..00e581fe657f9 100644 --- a/packages/protocol/spec/handles.yml +++ b/packages/protocol/spec/handles.yml @@ -29,13 +29,6 @@ JSHandle: expression: string isFunction: boolean? arg: SerializedArgument - serialize: - type: array? - items: - type: enum - literals: - - Map - - Set world: type: enum? literals: @@ -53,13 +46,6 @@ JSHandle: expression: string isFunction: boolean? arg: SerializedArgument - serialize: - type: array? - items: - type: enum - literals: - - Map - - Set returns: handle: JSHandle flags: diff --git a/packages/protocol/spec/serialized.yml b/packages/protocol/spec/serialized.yml index 0b82544a8daeb..e40ee4803ce45 100644 --- a/packages/protocol/spec/serialized.yml +++ b/packages/protocol/spec/serialized.yml @@ -77,18 +77,6 @@ SerializedValue: properties: k: string v: SerializedValue - # Map entries. - me: - type: array? - items: - type: object - properties: - k: SerializedValue - v: SerializedValue - # Set entries. - se: - type: array? - items: SerializedValue # An index in the handles array from SerializedArgument. h: int? # Name of a page-side callback that routes back to a client-side function. diff --git a/packages/protocol/src/serializers.ts b/packages/protocol/src/serializers.ts index ef59330e6eac8..0b245c1b8f24c 100644 --- a/packages/protocol/src/serializers.ts +++ b/packages/protocol/src/serializers.ts @@ -111,20 +111,6 @@ function innerParseSerializedValue(value: SerializedValue, handles: any[] | unde result[k] = innerParseSerializedValue(v, handles, refs, [...accessChain, k]); return result; } - if (value.me !== undefined) { - const result = new Map(); - refs.set(value.id!, result); - for (const { k, v } of value.me) - result.set(innerParseSerializedValue(k, handles, refs, accessChain), innerParseSerializedValue(v, handles, refs, accessChain)); - return result; - } - if (value.se !== undefined) { - const result = new Set(); - refs.set(value.id!, result); - for (const item of value.se) - result.add(innerParseSerializedValue(item, handles, refs, accessChain)); - return result; - } if (value.h !== undefined) { if (handles === undefined) throw new Error('Unexpected handle'); @@ -142,11 +128,10 @@ export type HandleOrValue = { h: number } | { fn: string } | { fallThrough: any type VisitorInfo = { visited: Map; lastId: number; - serialize?: ('Map' | 'Set')[]; }; -export function serializeValue(value: any, handleSerializer: (value: any) => HandleOrValue, options: { serialize?: ('Map' | 'Set')[] } = {}): SerializedValue { - return innerSerializeValue(value, handleSerializer, { lastId: 0, visited: new Map(), serialize: options.serialize }, []); +export function serializeValue(value: any, handleSerializer: (value: any) => HandleOrValue): SerializedValue { + return innerSerializeValue(value, handleSerializer, { lastId: 0, visited: new Map() }, []); } export function serializePlainValue(arg: any): SerializedValue { @@ -199,23 +184,6 @@ function innerSerializeValue(value: any, handleSerializer: (value: any) => Handl if (id) return { ref: id }; - if (visitorInfo.serialize?.includes('Map') && value instanceof Map) { - const me: { k: SerializedValue, v: SerializedValue }[] = []; - const id = ++visitorInfo.lastId; - visitorInfo.visited.set(value, id); - for (const [k, v] of value) - me.push({ k: innerSerializeValue(k, handleSerializer, visitorInfo, accessChain), v: innerSerializeValue(v, handleSerializer, visitorInfo, accessChain) }); - return { me, id }; - } - if (visitorInfo.serialize?.includes('Set') && value instanceof Set) { - const se: SerializedValue[] = []; - const id = ++visitorInfo.lastId; - visitorInfo.visited.set(value, id); - for (const item of value) - se.push(innerSerializeValue(item, handleSerializer, visitorInfo, accessChain)); - return { se, id }; - } - if (Array.isArray(value)) { const a = []; const id = ++visitorInfo.lastId; diff --git a/packages/protocol/src/structs.d.ts b/packages/protocol/src/structs.d.ts index 1d230fda89c07..084e3c13e74fb 100644 --- a/packages/protocol/src/structs.d.ts +++ b/packages/protocol/src/structs.d.ts @@ -297,11 +297,6 @@ export type SerializedValue = { k: string, v: SerializedValue, }[], - me?: { - k: SerializedValue, - v: SerializedValue, - }[], - se?: SerializedValue[], h?: number, fn?: string, id?: number, diff --git a/packages/protocol/src/validator.ts b/packages/protocol/src/validator.ts index 81b4f86a51e38..2921e6b0ccf86 100644 --- a/packages/protocol/src/validator.ts +++ b/packages/protocol/src/validator.ts @@ -1399,7 +1399,6 @@ scheme.FrameEvaluateExpressionParams = tObject({ expression: tString, isFunction: tOptional(tBoolean), arg: tType('SerializedArgument'), - serialize: tOptional(tArray(tEnum(['Map', 'Set']))), world: tOptional(tEnum(['main', 'utility'])), }); scheme.FrameEvaluateExpressionResult = tObject({ @@ -1409,7 +1408,6 @@ scheme.FrameEvaluateExpressionHandleParams = tObject({ expression: tString, isFunction: tOptional(tBoolean), arg: tType('SerializedArgument'), - serialize: tOptional(tArray(tEnum(['Map', 'Set']))), }); scheme.FrameEvaluateExpressionHandleResult = tObject({ handle: tChannel(['ElementHandle', 'JSHandle']), @@ -1715,7 +1713,6 @@ scheme.JSHandleEvaluateExpressionParams = tObject({ expression: tString, isFunction: tOptional(tBoolean), arg: tType('SerializedArgument'), - serialize: tOptional(tArray(tEnum(['Map', 'Set']))), world: tOptional(tEnum(['main', 'utility'])), }); scheme.ElementHandleEvaluateExpressionParams = tType('JSHandleEvaluateExpressionParams'); @@ -1727,7 +1724,6 @@ scheme.JSHandleEvaluateExpressionHandleParams = tObject({ expression: tString, isFunction: tOptional(tBoolean), arg: tType('SerializedArgument'), - serialize: tOptional(tArray(tEnum(['Map', 'Set']))), }); scheme.ElementHandleEvaluateExpressionHandleParams = tType('JSHandleEvaluateExpressionHandleParams'); scheme.JSHandleEvaluateExpressionHandleResult = tObject({ @@ -3082,11 +3078,6 @@ scheme.SerializedValue = tObject({ k: tString, v: tType('SerializedValue'), }))), - me: tOptional(tArray(tObject({ - k: tType('SerializedValue'), - v: tType('SerializedValue'), - }))), - se: tOptional(tArray(tType('SerializedValue'))), h: tOptional(tInt), fn: tOptional(tString), id: tOptional(tInt), diff --git a/tests/page/page-evaluate-serialization.spec.ts b/tests/page/page-evaluate-serialization.spec.ts deleted file mode 100644 index 1c1f7e63b9b6b..0000000000000 --- a/tests/page/page-evaluate-serialization.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * 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 { test, expect } from './pageTest'; - -test('should serialize selected types in evaluate', async ({ page }) => { - const value = new Map([['key', new Set([1, 2])]]); - const result = await page.evaluate(value => { - if (!(value instanceof Map) || !(value.get('key') instanceof Set)) - throw new Error('Expected Map and Set arguments'); - value.get('key')!.add(3); - return value; - }, value, { serialize: ['Map', 'Set'] }); - expect(result).toEqual(new Map([['key', new Set([1, 2, 3])]])); - expect(await page.evaluate(value => value, value, { serialize: [] })).toEqual({}); - const collections = { map: new Map([['key', 1]]), set: new Set([2]) }; - for (const type of ['Map', 'Set'] as const) { - const result = await page.evaluate(value => ({ - map: value.map instanceof Map, - set: value.set instanceof Set, - value, - created: { map: new Map([['key', 1]]), set: new Set([2]) }, - }), collections, { serialize: [type] }); - const expected = { map: type === 'Map' ? collections.map : {}, set: type === 'Set' ? collections.set : {} }; - expect(result).toEqual({ map: type === 'Map', set: type === 'Set', value: expected, created: expected }); - } -}); - -test('should serialize Map and Set with handles', async ({ page }) => { - const value = new Map([['key', new Set([1, 2])]]); - const handle = await page.evaluateHandle(value => value, value, { serialize: ['Map', 'Set'] }); - expect(await handle.evaluate(value => value instanceof Map && value.get('key') instanceof Set)).toBe(true); - expect(await handle.evaluate((value, set) => ({ value, set }), new Set([3]), { serialize: ['Map', 'Set'] })).toEqual({ value, set: new Set([3]) }); - expect(await handle.evaluate(value => value)).toEqual({}); - await handle.dispose(); -}); - -test('should serialize Map and Set with locators', async ({ page }) => { - await page.setContent('
hello
'); - const value = new Map([['key', new Set([1, 2])]]); - const result = await page.locator('div').evaluate((element, value) => ({ text: element.textContent, value }), value, { serialize: ['Map', 'Set'] }); - expect(result).toEqual({ text: 'hello', value }); -}); - -test('should reject invalid serialization types', async ({ page }) => { - // @ts-expect-error Invalid serialization type. - await expect(page.evaluate(() => 42, undefined, { serialize: ['Blob'] })).rejects.toThrow('serialize: expected an array of (Map|Set)'); - // @ts-expect-error Serialization types must be an array. - await expect(page.evaluate(() => 42, undefined, { serialize: 'Map' })).rejects.toThrow('serialize: expected an array of (Map|Set)'); -}); diff --git a/tests/playwright-test/playwright.mount.spec.ts b/tests/playwright-test/playwright.mount.spec.ts deleted file mode 100644 index 0927f92bad1b4..0000000000000 --- a/tests/playwright-test/playwright.mount.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright Microsoft Corporation. All rights reserved. - * - * 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 { test, expect } from './playwright-test-fixtures'; - -test('mount and update should preserve Map and Set props with callbacks', async ({ runInlineTest, server }) => { - server.setRoute('/gallery.html', (req, res) => { - res.setHeader('Content-Type', 'text/html'); - res.end(` -
- - `); - }); - const result = await runInlineTest({ - 'playwright.config.ts': ` - module.exports = { use: { baseURL: '${server.PREFIX}/gallery.html' } }; - `, - 'mount.spec.ts': ` - import { test, expect } from '@playwright/test'; - - test('collections', async ({ mount }) => { - const received: string[] = []; - const callback = async (text: string) => { received.push(text); }; - const component = await mount('collections', { - values: new Map([['numbers', new Set([1, 2, 2])]]), - callbacks: new Map([['change', new Set([callback])]]), - }); - await expect(component).toHaveText('collections: 1, 2'); - expect(received).toEqual(['collections: 1, 2']); - - await component.update({ - values: new Map([['numbers', new Set([3, 4])]]), - callbacks: new Map([['change', new Set([callback])]]), - }); - await expect(component).toHaveText('collections: 3, 4'); - expect(received).toEqual(['collections: 1, 2', 'collections: 3, 4']); - }); - `, - }); - expect(result.exitCode).toBe(0); - expect(result.passed).toBe(1); -}); diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 0b186e03539ce..ebde294dffa21 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -38,11 +38,11 @@ type ZodSchema = ZodTypeAny | z3.ZodTypeAny; type InferZodSchema = T extends z3.ZodTypeAny ? z3.infer : T extends ZodTypeAny ? z.infer : never; export interface Page { - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; addInitScript(script: PageFunction | { path?: string, content?: string }, arg?: Arg, options?: { exposeFunctions?: boolean }): Promise; @@ -85,11 +85,11 @@ export interface Page { } export interface Frame { - evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; - evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; + evaluate(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; - evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; - evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; + evaluateHandle(pageFunction: PageFunction, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; $(selector: K, options?: { strict: boolean }): Promise | null>; $(selector: string, options?: { strict: boolean }): Promise | null>; @@ -156,11 +156,11 @@ export interface Worker { } export interface JSHandle { - evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; - evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise; + evaluate(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise; + evaluate(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise; - evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; - evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg: Arg, options?: { exposeFunctions?: boolean }): Promise>; + evaluateHandle(pageFunction: PageFunctionOn, arg?: any, options?: { exposeFunctions?: boolean }): Promise>; jsonValue(): Promise; asElement(): T extends Node ? ElementHandle : null; @@ -194,8 +194,8 @@ export interface ElementHandle extends JSHandle { } export interface Locator { - evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[], world?: 'main'|'utility' }): Promise; - evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, serialize?: ('Map'|'Set')[] }): Promise>; + evaluate(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean, world?: 'main'|'utility' }): Promise; + evaluateHandle(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal, exposeFunctions?: boolean }): Promise>; evaluateAll(pageFunction: PageFunctionOn, arg?: Arg, options?: { world?: 'main'|'utility' }): Promise; waitForFunction(pageFunction: PageFunctionOn, arg?: Arg, options?: { timeout?: number, signal?: AbortSignal }): Promise; elementHandle(options?: { timeout?: number, signal?: AbortSignal }): Promise>; diff --git a/utils/generate_types/test/test.ts b/utils/generate_types/test/test.ts index 68069e258bb14..3d098fc0f4931 100644 --- a/utils/generate_types/test/test.ts +++ b/utils/generate_types/test/test.ts @@ -336,18 +336,6 @@ playwright.chromium.launch().then(async browser => { await browser.close(); })(); -// Collection serialization unboxes handles inside collections. -(async () => { - const body = await page.evaluateHandle(() => document.body); - const input = { map: new Map([[body, new Set([body])]]) }; - const value = await page.evaluate(({ map }) => { - const elements = map.get(document.body)!; - const assertion: AssertType, typeof elements> = true; - return new Set([...elements].map(element => element.tagName)); - }, input, { serialize: ['Map', 'Set'] }); - const assertion: AssertType, typeof value> = true; -})(); - // test $eval and $$eval (async () => { const browser = await playwright.firefox.launch(); @@ -1061,3 +1049,4 @@ import { Geolocation, HTTPCredentials, } from 'playwright'; +