feat(types): improve typing of .evaluate()
(#6096)
* feat(types): improve typing of `.evaluate()` This is the start of the work to take the types from the `@types/puppeteer` repository and port them into our repo so we can ship our built-in types out the box. This change types the `evaluate` function properly. It takes a generic type which is the type of the function you're passing, and the arguments and the return that you get back from the `evaluate` call are typed correctly.
This commit is contained in:
parent
a4d12a2b21
commit
46fc6ca41a
@ -96,6 +96,8 @@ module.exports = {
|
|||||||
"rules": {
|
"rules": {
|
||||||
"no-unused-vars": 0,
|
"no-unused-vars": 0,
|
||||||
"@typescript-eslint/no-unused-vars": 2,
|
"@typescript-eslint/no-unused-vars": 2,
|
||||||
|
"func-call-spacing": 0,
|
||||||
|
"@typescript-eslint/func-call-spacing": 2,
|
||||||
"semi": 0,
|
"semi": 0,
|
||||||
"@typescript-eslint/semi": 2,
|
"@typescript-eslint/semi": 2,
|
||||||
"@typescript-eslint/no-empty-function": 0,
|
"@typescript-eslint/no-empty-function": 0,
|
||||||
|
18
README.md
18
README.md
@ -292,9 +292,25 @@ Puppeteer creates its own browser user profile which it **cleans up on every run
|
|||||||
|
|
||||||
- debug your test inside chromium like a boss!
|
- debug your test inside chromium like a boss!
|
||||||
|
|
||||||
|
|
||||||
<!-- [END debugging] -->
|
<!-- [END debugging] -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- [START typescript] -->
|
||||||
|
## Usage with TypeScript
|
||||||
|
|
||||||
|
We have recently completed a migration to move the Puppeteer source code from JavaScript to TypeScript and we're currently working on shipping type definitions for TypeScript with Puppeteer's npm package.
|
||||||
|
|
||||||
|
Until this work is complete we recommend installing the Puppeteer type definitions from the [DefinitelyTyped](https://definitelytyped.org/) repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save-dev @types/puppeteer
|
||||||
|
```
|
||||||
|
|
||||||
|
The types that you'll see appearing in the Puppeteer source code are based off the great work of those who have contributed to the `@types/puppeteer` package. We really appreciate the hard work those people put in to providing high quality TypeScript definitions for Puppeteer's users.
|
||||||
|
|
||||||
|
<!-- [END typescript] -->
|
||||||
|
|
||||||
|
|
||||||
## Contributing to Puppeteer
|
## Contributing to Puppeteer
|
||||||
|
|
||||||
Check out [contributing guide](https://github.com/puppeteer/puppeteer/blob/main/CONTRIBUTING.md) to get an overview of Puppeteer development.
|
Check out [contributing guide](https://github.com/puppeteer/puppeteer/blob/main/CONTRIBUTING.md) to get an overview of Puppeteer development.
|
||||||
|
@ -11,7 +11,7 @@ If `pageFunction` returns a Promise, then `frame.$$eval` would wait for the prom
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -19,8 +19,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ If `pageFunction` returns a Promise, then `frame.$eval` would wait for the promi
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -19,8 +19,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
12
new-docs/puppeteer.evaluatefn.md
Normal file
12
new-docs/puppeteer.evaluatefn.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [EvaluateFn](./puppeteer.evaluatefn.md)
|
||||||
|
|
||||||
|
## EvaluateFn type
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export declare type EvaluateFn<T = any> = string | ((arg1: T, ...args: any[]) => any);
|
||||||
|
```
|
12
new-docs/puppeteer.evaluatefnreturntype.md
Normal file
12
new-docs/puppeteer.evaluatefnreturntype.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md)
|
||||||
|
|
||||||
|
## EvaluateFnReturnType type
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export declare type EvaluateFnReturnType<T extends EvaluateFn> = T extends (...args: any[]) => infer R ? R : unknown;
|
||||||
|
```
|
@ -7,7 +7,7 @@
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -15,8 +15,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -15,8 +15,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
@ -9,19 +9,19 @@ This method passes this handle as the first argument to `pageFunction`<!-- -->.
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
evaluate<ReturnType extends any>(pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
evaluate<T extends EvaluateFn>(pageFunction: T | string, ...args: SerializableOrJSHandle[]): Promise<EvaluateFnReturnType<T>>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | T \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
Promise<ReturnType>
|
Promise<[EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md)<!-- --><T>>
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
12
new-docs/puppeteer.jsonarray.md
Normal file
12
new-docs/puppeteer.jsonarray.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [JSONArray](./puppeteer.jsonarray.md)
|
||||||
|
|
||||||
|
## JSONArray type
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export declare type JSONArray = Serializable[];
|
||||||
|
```
|
12
new-docs/puppeteer.jsonobject.md
Normal file
12
new-docs/puppeteer.jsonobject.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [JSONObject](./puppeteer.jsonobject.md)
|
||||||
|
|
||||||
|
## JSONObject interface
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export interface JSONObject
|
||||||
|
```
|
@ -52,6 +52,7 @@
|
|||||||
| [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | |
|
| [BrowserFetcherOptions](./puppeteer.browserfetcheroptions.md) | |
|
||||||
| [ClickOptions](./puppeteer.clickoptions.md) | |
|
| [ClickOptions](./puppeteer.clickoptions.md) | |
|
||||||
| [ConsoleMessageLocation](./puppeteer.consolemessagelocation.md) | |
|
| [ConsoleMessageLocation](./puppeteer.consolemessagelocation.md) | |
|
||||||
|
| [JSONObject](./puppeteer.jsonobject.md) | |
|
||||||
| [KeyDefinition](./puppeteer.keydefinition.md) | Copyright 2017 Google Inc. 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. |
|
| [KeyDefinition](./puppeteer.keydefinition.md) | Copyright 2017 Google Inc. 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. |
|
||||||
| [Metrics](./puppeteer.metrics.md) | |
|
| [Metrics](./puppeteer.metrics.md) | |
|
||||||
| [PressOptions](./puppeteer.pressoptions.md) | |
|
| [PressOptions](./puppeteer.pressoptions.md) | |
|
||||||
@ -73,7 +74,12 @@
|
|||||||
| Type Alias | Description |
|
| Type Alias | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| [ConsoleMessageType](./puppeteer.consolemessagetype.md) | The supported types for console messages. |
|
| [ConsoleMessageType](./puppeteer.consolemessagetype.md) | The supported types for console messages. |
|
||||||
|
| [EvaluateFn](./puppeteer.evaluatefn.md) | |
|
||||||
|
| [EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md) | |
|
||||||
|
| [JSONArray](./puppeteer.jsonarray.md) | |
|
||||||
| [KeyInput](./puppeteer.keyinput.md) | |
|
| [KeyInput](./puppeteer.keyinput.md) | |
|
||||||
| [MouseButtonInput](./puppeteer.mousebuttoninput.md) | |
|
| [MouseButtonInput](./puppeteer.mousebuttoninput.md) | |
|
||||||
| [PuppeteerErrors](./puppeteer.puppeteererrors.md) | |
|
| [PuppeteerErrors](./puppeteer.puppeteererrors.md) | |
|
||||||
|
| [Serializable](./puppeteer.serializable.md) | |
|
||||||
|
| [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md) | |
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -15,8 +15,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<b>Signature:</b>
|
<b>Signature:</b>
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
$eval<ReturnType extends any>(selector: string, pageFunction: Function | string, ...args: unknown[]): Promise<ReturnType>;
|
$eval<ReturnType extends any>(selector: string, pageFunction: EvaluateFn | string, ...args: SerializableOrJSHandle[]): Promise<ReturnType>;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Parameters
|
## Parameters
|
||||||
@ -15,8 +15,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
|||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| selector | string | |
|
| selector | string | |
|
||||||
| pageFunction | Function \| string | |
|
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||||
| args | unknown\[\] | |
|
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||||
|
|
||||||
<b>Returns:</b>
|
<b>Returns:</b>
|
||||||
|
|
||||||
|
12
new-docs/puppeteer.serializable.md
Normal file
12
new-docs/puppeteer.serializable.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [Serializable](./puppeteer.serializable.md)
|
||||||
|
|
||||||
|
## Serializable type
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export declare type Serializable = number | string | boolean | null | JSONArray | JSONObject;
|
||||||
|
```
|
12
new-docs/puppeteer.serializableorjshandle.md
Normal file
12
new-docs/puppeteer.serializableorjshandle.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||||
|
|
||||||
|
[Home](./index.md) > [puppeteer](./puppeteer.md) > [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)
|
||||||
|
|
||||||
|
## SerializableOrJSHandle type
|
||||||
|
|
||||||
|
|
||||||
|
<b>Signature:</b>
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export declare type SerializableOrJSHandle = Serializable | JSHandle;
|
||||||
|
```
|
@ -48,3 +48,4 @@ export * from './common/Errors';
|
|||||||
export * from './common/Tracing';
|
export * from './common/Tracing';
|
||||||
export * from './common/WebWorker';
|
export * from './common/WebWorker';
|
||||||
export * from './common/USKeyboardLayout';
|
export * from './common/USKeyboardLayout';
|
||||||
|
export * from './common/EvalTypes';
|
||||||
|
@ -24,6 +24,7 @@ import { TimeoutSettings } from './TimeoutSettings';
|
|||||||
import { MouseButtonInput } from './Input';
|
import { MouseButtonInput } from './Input';
|
||||||
import { FrameManager, Frame } from './FrameManager';
|
import { FrameManager, Frame } from './FrameManager';
|
||||||
import { getQueryHandlerAndSelector, QueryHandler } from './QueryHandler';
|
import { getQueryHandlerAndSelector, QueryHandler } from './QueryHandler';
|
||||||
|
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||||
import { isNode } from '../environment';
|
import { isNode } from '../environment';
|
||||||
|
|
||||||
// This predicateQueryHandler is declared here so that TypeScript knows about it
|
// This predicateQueryHandler is declared here so that TypeScript knows about it
|
||||||
@ -155,8 +156,8 @@ export class DOMWorld {
|
|||||||
|
|
||||||
async $eval<ReturnType extends any>(
|
async $eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
const document = await this._document();
|
const document = await this._document();
|
||||||
return document.$eval<ReturnType>(selector, pageFunction, ...args);
|
return document.$eval<ReturnType>(selector, pageFunction, ...args);
|
||||||
@ -164,8 +165,8 @@ export class DOMWorld {
|
|||||||
|
|
||||||
async $$eval<ReturnType extends any>(
|
async $$eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
const document = await this._document();
|
const document = await this._document();
|
||||||
const value = await document.$$eval<ReturnType>(
|
const value = await document.$$eval<ReturnType>(
|
||||||
|
58
src/common/EvalTypes.ts
Normal file
58
src/common/EvalTypes.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2020 Google Inc. 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 { JSHandle } from './JSHandle';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type EvaluateFn<T = any> = string | ((arg1: T, ...args: any[]) => any);
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type EvaluateFnReturnType<T extends EvaluateFn> = T extends (
|
||||||
|
...args: any[]
|
||||||
|
) => infer R
|
||||||
|
? R
|
||||||
|
: unknown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type Serializable =
|
||||||
|
| number
|
||||||
|
| string
|
||||||
|
| boolean
|
||||||
|
| null
|
||||||
|
| JSONArray
|
||||||
|
| JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type JSONArray = Serializable[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface JSONObject {
|
||||||
|
[key: string]: Serializable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export type SerializableOrJSHandle = Serializable | JSHandle;
|
@ -29,6 +29,7 @@ import { MouseButtonInput } from './Input';
|
|||||||
import { Page } from './Page';
|
import { Page } from './Page';
|
||||||
import { HTTPResponse } from './HTTPResponse';
|
import { HTTPResponse } from './HTTPResponse';
|
||||||
import Protocol from '../protocol';
|
import Protocol from '../protocol';
|
||||||
|
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||||
|
|
||||||
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
||||||
|
|
||||||
@ -454,16 +455,16 @@ export class Frame {
|
|||||||
|
|
||||||
async $eval<ReturnType extends any>(
|
async $eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
return this._mainWorld.$eval<ReturnType>(selector, pageFunction, ...args);
|
return this._mainWorld.$eval<ReturnType>(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
async $$eval<ReturnType extends any>(
|
async $$eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
return this._mainWorld.$$eval<ReturnType>(selector, pageFunction, ...args);
|
return this._mainWorld.$$eval<ReturnType>(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,11 @@ import { KeyInput } from './USKeyboardLayout';
|
|||||||
import { FrameManager, Frame } from './FrameManager';
|
import { FrameManager, Frame } from './FrameManager';
|
||||||
import { getQueryHandlerAndSelector } from './QueryHandler';
|
import { getQueryHandlerAndSelector } from './QueryHandler';
|
||||||
import Protocol from '../protocol';
|
import Protocol from '../protocol';
|
||||||
|
import {
|
||||||
|
EvaluateFn,
|
||||||
|
SerializableOrJSHandle,
|
||||||
|
EvaluateFnReturnType,
|
||||||
|
} from './EvalTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
@ -113,11 +118,12 @@ export class JSHandle {
|
|||||||
* expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');
|
* expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
async evaluate<ReturnType extends any>(
|
|
||||||
pageFunction: Function | string,
|
async evaluate<T extends EvaluateFn>(
|
||||||
...args: unknown[]
|
pageFunction: T | string,
|
||||||
): Promise<ReturnType> {
|
...args: SerializableOrJSHandle[]
|
||||||
return await this.executionContext().evaluate<ReturnType>(
|
): Promise<EvaluateFnReturnType<T>> {
|
||||||
|
return await this.executionContext().evaluate<EvaluateFnReturnType<T>>(
|
||||||
pageFunction,
|
pageFunction,
|
||||||
this,
|
this,
|
||||||
...args
|
...args
|
||||||
@ -307,46 +313,48 @@ export class ElementHandle extends JSHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _scrollIntoViewIfNeeded(): Promise<void> {
|
private async _scrollIntoViewIfNeeded(): Promise<void> {
|
||||||
const error = await this.evaluate<Promise<string | false>>(
|
const error = await this.evaluate<
|
||||||
async (element: HTMLElement, pageJavascriptEnabled: boolean) => {
|
(
|
||||||
if (!element.isConnected) return 'Node is detached from document';
|
element: HTMLElement,
|
||||||
if (element.nodeType !== Node.ELEMENT_NODE)
|
pageJavascriptEnabled: boolean
|
||||||
return 'Node is not of type HTMLElement';
|
) => Promise<string | false>
|
||||||
// force-scroll if page's javascript is disabled.
|
>(async (element, pageJavascriptEnabled) => {
|
||||||
if (!pageJavascriptEnabled) {
|
if (!element.isConnected) return 'Node is detached from document';
|
||||||
element.scrollIntoView({
|
if (element.nodeType !== Node.ELEMENT_NODE)
|
||||||
block: 'center',
|
return 'Node is not of type HTMLElement';
|
||||||
inline: 'center',
|
// force-scroll if page's javascript is disabled.
|
||||||
// Chrome still supports behavior: instant but it's not in the spec
|
if (!pageJavascriptEnabled) {
|
||||||
// so TS shouts We don't want to make this breaking change in
|
element.scrollIntoView({
|
||||||
// Puppeteer yet so we'll ignore the line.
|
block: 'center',
|
||||||
// @ts-ignore
|
inline: 'center',
|
||||||
behavior: 'instant',
|
// Chrome still supports behavior: instant but it's not in the spec
|
||||||
});
|
// so TS shouts We don't want to make this breaking change in
|
||||||
return false;
|
// Puppeteer yet so we'll ignore the line.
|
||||||
}
|
// @ts-ignore
|
||||||
const visibleRatio = await new Promise((resolve) => {
|
behavior: 'instant',
|
||||||
const observer = new IntersectionObserver((entries) => {
|
|
||||||
resolve(entries[0].intersectionRatio);
|
|
||||||
observer.disconnect();
|
|
||||||
});
|
|
||||||
observer.observe(element);
|
|
||||||
});
|
});
|
||||||
if (visibleRatio !== 1.0) {
|
|
||||||
element.scrollIntoView({
|
|
||||||
block: 'center',
|
|
||||||
inline: 'center',
|
|
||||||
// Chrome still supports behavior: instant but it's not in the spec
|
|
||||||
// so TS shouts We don't want to make this breaking change in
|
|
||||||
// Puppeteer yet so we'll ignore the line.
|
|
||||||
// @ts-ignore
|
|
||||||
behavior: 'instant',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
this._page.isJavaScriptEnabled()
|
const visibleRatio = await new Promise((resolve) => {
|
||||||
);
|
const observer = new IntersectionObserver((entries) => {
|
||||||
|
resolve(entries[0].intersectionRatio);
|
||||||
|
observer.disconnect();
|
||||||
|
});
|
||||||
|
observer.observe(element);
|
||||||
|
});
|
||||||
|
if (visibleRatio !== 1.0) {
|
||||||
|
element.scrollIntoView({
|
||||||
|
block: 'center',
|
||||||
|
inline: 'center',
|
||||||
|
// Chrome still supports behavior: instant but it's not in the spec
|
||||||
|
// so TS shouts We don't want to make this breaking change in
|
||||||
|
// Puppeteer yet so we'll ignore the line.
|
||||||
|
// @ts-ignore
|
||||||
|
behavior: 'instant',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}, this._page.isJavaScriptEnabled());
|
||||||
|
|
||||||
if (error) throw new Error(error);
|
if (error) throw new Error(error);
|
||||||
}
|
}
|
||||||
@ -491,9 +499,9 @@ export class ElementHandle extends JSHandle {
|
|||||||
* relative to the {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory}
|
* relative to the {@link https://nodejs.org/api/process.html#process_process_cwd | current working directory}
|
||||||
*/
|
*/
|
||||||
async uploadFile(...filePaths: string[]): Promise<void> {
|
async uploadFile(...filePaths: string[]): Promise<void> {
|
||||||
const isMultiple = await this.evaluate<boolean>(
|
const isMultiple = await this.evaluate<
|
||||||
(element: HTMLInputElement) => element.multiple
|
(element: HTMLInputElement) => boolean
|
||||||
);
|
>((element) => element.multiple);
|
||||||
assert(
|
assert(
|
||||||
filePaths.length <= 1 || isMultiple,
|
filePaths.length <= 1 || isMultiple,
|
||||||
'Multiple file uploads only work with <input type=file multiple>'
|
'Multiple file uploads only work with <input type=file multiple>'
|
||||||
@ -772,15 +780,15 @@ export class ElementHandle extends JSHandle {
|
|||||||
*/
|
*/
|
||||||
async $eval<ReturnType extends any>(
|
async $eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
const elementHandle = await this.$(selector);
|
const elementHandle = await this.$(selector);
|
||||||
if (!elementHandle)
|
if (!elementHandle)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Error: failed to find element matching selector "${selector}"`
|
`Error: failed to find element matching selector "${selector}"`
|
||||||
);
|
);
|
||||||
const result = await elementHandle.evaluate<ReturnType>(
|
const result = await elementHandle.evaluate<(...args: any[]) => ReturnType>(
|
||||||
pageFunction,
|
pageFunction,
|
||||||
...args
|
...args
|
||||||
);
|
);
|
||||||
@ -813,8 +821,8 @@ export class ElementHandle extends JSHandle {
|
|||||||
*/
|
*/
|
||||||
async $$eval<ReturnType extends any>(
|
async $$eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
const defaultHandler = (element: Element, selector: string) =>
|
const defaultHandler = (element: Element, selector: string) =>
|
||||||
Array.from(element.querySelectorAll(selector));
|
Array.from(element.querySelectorAll(selector));
|
||||||
@ -827,7 +835,7 @@ export class ElementHandle extends JSHandle {
|
|||||||
queryHandler,
|
queryHandler,
|
||||||
updatedSelector
|
updatedSelector
|
||||||
);
|
);
|
||||||
const result = await arrayHandle.evaluate<ReturnType>(
|
const result = await arrayHandle.evaluate<(...args: any[]) => ReturnType>(
|
||||||
pageFunction,
|
pageFunction,
|
||||||
...args
|
...args
|
||||||
);
|
);
|
||||||
@ -868,16 +876,18 @@ export class ElementHandle extends JSHandle {
|
|||||||
* Resolves to true if the element is visible in the current viewport.
|
* Resolves to true if the element is visible in the current viewport.
|
||||||
*/
|
*/
|
||||||
async isIntersectingViewport(): Promise<boolean> {
|
async isIntersectingViewport(): Promise<boolean> {
|
||||||
return await this.evaluate<Promise<boolean>>(async (element) => {
|
return await this.evaluate<(element: Element) => Promise<boolean>>(
|
||||||
const visibleRatio = await new Promise((resolve) => {
|
async (element) => {
|
||||||
const observer = new IntersectionObserver((entries) => {
|
const visibleRatio = await new Promise((resolve) => {
|
||||||
resolve(entries[0].intersectionRatio);
|
const observer = new IntersectionObserver((entries) => {
|
||||||
observer.disconnect();
|
resolve(entries[0].intersectionRatio);
|
||||||
|
observer.disconnect();
|
||||||
|
});
|
||||||
|
observer.observe(element);
|
||||||
});
|
});
|
||||||
observer.observe(element);
|
return visibleRatio > 0;
|
||||||
});
|
}
|
||||||
return visibleRatio > 0;
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ import { FileChooser } from './FileChooser';
|
|||||||
import { ConsoleMessage, ConsoleMessageType } from './ConsoleMessage';
|
import { ConsoleMessage, ConsoleMessageType } from './ConsoleMessage';
|
||||||
import { PuppeteerLifeCycleEvent } from './LifecycleWatcher';
|
import { PuppeteerLifeCycleEvent } from './LifecycleWatcher';
|
||||||
import Protocol from '../protocol';
|
import Protocol from '../protocol';
|
||||||
|
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||||
|
|
||||||
const writeFileAsync = promisify(fs.writeFile);
|
const writeFileAsync = promisify(fs.writeFile);
|
||||||
|
|
||||||
@ -514,16 +515,16 @@ export class Page extends EventEmitter {
|
|||||||
|
|
||||||
async $eval<ReturnType extends any>(
|
async $eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
return this.mainFrame().$eval<ReturnType>(selector, pageFunction, ...args);
|
return this.mainFrame().$eval<ReturnType>(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
async $$eval<ReturnType extends any>(
|
async $$eval<ReturnType extends any>(
|
||||||
selector: string,
|
selector: string,
|
||||||
pageFunction: Function | string,
|
pageFunction: EvaluateFn | string,
|
||||||
...args: unknown[]
|
...args: SerializableOrJSHandle[]
|
||||||
): Promise<ReturnType> {
|
): Promise<ReturnType> {
|
||||||
return this.mainFrame().$$eval<ReturnType>(selector, pageFunction, ...args);
|
return this.mainFrame().$$eval<ReturnType>(selector, pageFunction, ...args);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user