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": {
|
||||
"no-unused-vars": 0,
|
||||
"@typescript-eslint/no-unused-vars": 2,
|
||||
"func-call-spacing": 0,
|
||||
"@typescript-eslint/func-call-spacing": 2,
|
||||
"semi": 0,
|
||||
"@typescript-eslint/semi": 2,
|
||||
"@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!
|
||||
|
||||
|
||||
<!-- [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
|
||||
|
||||
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>
|
||||
|
||||
```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
|
||||
@ -19,8 +19,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
@ -11,7 +11,7 @@ If `pageFunction` returns a Promise, then `frame.$eval` would wait for the promi
|
||||
<b>Signature:</b>
|
||||
|
||||
```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
|
||||
@ -19,8 +19,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<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>
|
||||
|
||||
```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
|
||||
@ -15,8 +15,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<b>Signature:</b>
|
||||
|
||||
```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
|
||||
@ -15,8 +15,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
@ -9,19 +9,19 @@ This method passes this handle as the first argument to `pageFunction`<!-- -->.
|
||||
<b>Signature:</b>
|
||||
|
||||
```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
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | T \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
Promise<ReturnType>
|
||||
Promise<[EvaluateFnReturnType](./puppeteer.evaluatefnreturntype.md)<!-- --><T>>
|
||||
|
||||
## 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) | |
|
||||
| [ClickOptions](./puppeteer.clickoptions.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. |
|
||||
| [Metrics](./puppeteer.metrics.md) | |
|
||||
| [PressOptions](./puppeteer.pressoptions.md) | |
|
||||
@ -73,7 +74,12 @@
|
||||
| Type Alias | Description |
|
||||
| --- | --- |
|
||||
| [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) | |
|
||||
| [MouseButtonInput](./puppeteer.mousebuttoninput.md) | |
|
||||
| [PuppeteerErrors](./puppeteer.puppeteererrors.md) | |
|
||||
| [Serializable](./puppeteer.serializable.md) | |
|
||||
| [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md) | |
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<b>Signature:</b>
|
||||
|
||||
```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
|
||||
@ -15,8 +15,8 @@ $$eval<ReturnType extends any>(selector: string, pageFunction: Function | string
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<b>Signature:</b>
|
||||
|
||||
```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
|
||||
@ -15,8 +15,8 @@ $eval<ReturnType extends any>(selector: string, pageFunction: Function | string,
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| selector | string | |
|
||||
| pageFunction | Function \| string | |
|
||||
| args | unknown\[\] | |
|
||||
| pageFunction | [EvaluateFn](./puppeteer.evaluatefn.md) \| string | |
|
||||
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
|
||||
|
||||
<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/WebWorker';
|
||||
export * from './common/USKeyboardLayout';
|
||||
export * from './common/EvalTypes';
|
||||
|
@ -24,6 +24,7 @@ import { TimeoutSettings } from './TimeoutSettings';
|
||||
import { MouseButtonInput } from './Input';
|
||||
import { FrameManager, Frame } from './FrameManager';
|
||||
import { getQueryHandlerAndSelector, QueryHandler } from './QueryHandler';
|
||||
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||
import { isNode } from '../environment';
|
||||
|
||||
// This predicateQueryHandler is declared here so that TypeScript knows about it
|
||||
@ -155,8 +156,8 @@ export class DOMWorld {
|
||||
|
||||
async $eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
const document = await this._document();
|
||||
return document.$eval<ReturnType>(selector, pageFunction, ...args);
|
||||
@ -164,8 +165,8 @@ export class DOMWorld {
|
||||
|
||||
async $$eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
const document = await this._document();
|
||||
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 { HTTPResponse } from './HTTPResponse';
|
||||
import Protocol from '../protocol';
|
||||
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||
|
||||
const UTILITY_WORLD_NAME = '__puppeteer_utility_world__';
|
||||
|
||||
@ -454,16 +455,16 @@ export class Frame {
|
||||
|
||||
async $eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
return this._mainWorld.$eval<ReturnType>(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async $$eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
return this._mainWorld.$$eval<ReturnType>(selector, pageFunction, ...args);
|
||||
}
|
||||
|
@ -23,6 +23,11 @@ import { KeyInput } from './USKeyboardLayout';
|
||||
import { FrameManager, Frame } from './FrameManager';
|
||||
import { getQueryHandlerAndSelector } from './QueryHandler';
|
||||
import Protocol from '../protocol';
|
||||
import {
|
||||
EvaluateFn,
|
||||
SerializableOrJSHandle,
|
||||
EvaluateFnReturnType,
|
||||
} from './EvalTypes';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -113,11 +118,12 @@ export class JSHandle {
|
||||
* expect(await tweetHandle.evaluate(node => node.innerText)).toBe('10');
|
||||
* ```
|
||||
*/
|
||||
async evaluate<ReturnType extends any>(
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
): Promise<ReturnType> {
|
||||
return await this.executionContext().evaluate<ReturnType>(
|
||||
|
||||
async evaluate<T extends EvaluateFn>(
|
||||
pageFunction: T | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<EvaluateFnReturnType<T>> {
|
||||
return await this.executionContext().evaluate<EvaluateFnReturnType<T>>(
|
||||
pageFunction,
|
||||
this,
|
||||
...args
|
||||
@ -307,46 +313,48 @@ export class ElementHandle extends JSHandle {
|
||||
}
|
||||
|
||||
private async _scrollIntoViewIfNeeded(): Promise<void> {
|
||||
const error = await this.evaluate<Promise<string | false>>(
|
||||
async (element: HTMLElement, pageJavascriptEnabled: boolean) => {
|
||||
if (!element.isConnected) return 'Node is detached from document';
|
||||
if (element.nodeType !== Node.ELEMENT_NODE)
|
||||
return 'Node is not of type HTMLElement';
|
||||
// force-scroll if page's javascript is disabled.
|
||||
if (!pageJavascriptEnabled) {
|
||||
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;
|
||||
}
|
||||
const visibleRatio = await new Promise((resolve) => {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
resolve(entries[0].intersectionRatio);
|
||||
observer.disconnect();
|
||||
});
|
||||
observer.observe(element);
|
||||
const error = await this.evaluate<
|
||||
(
|
||||
element: HTMLElement,
|
||||
pageJavascriptEnabled: boolean
|
||||
) => Promise<string | false>
|
||||
>(async (element, pageJavascriptEnabled) => {
|
||||
if (!element.isConnected) return 'Node is detached from document';
|
||||
if (element.nodeType !== Node.ELEMENT_NODE)
|
||||
return 'Node is not of type HTMLElement';
|
||||
// force-scroll if page's javascript is disabled.
|
||||
if (!pageJavascriptEnabled) {
|
||||
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',
|
||||
});
|
||||
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()
|
||||
);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -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}
|
||||
*/
|
||||
async uploadFile(...filePaths: string[]): Promise<void> {
|
||||
const isMultiple = await this.evaluate<boolean>(
|
||||
(element: HTMLInputElement) => element.multiple
|
||||
);
|
||||
const isMultiple = await this.evaluate<
|
||||
(element: HTMLInputElement) => boolean
|
||||
>((element) => element.multiple);
|
||||
assert(
|
||||
filePaths.length <= 1 || isMultiple,
|
||||
'Multiple file uploads only work with <input type=file multiple>'
|
||||
@ -772,15 +780,15 @@ export class ElementHandle extends JSHandle {
|
||||
*/
|
||||
async $eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
const elementHandle = await this.$(selector);
|
||||
if (!elementHandle)
|
||||
throw new Error(
|
||||
`Error: failed to find element matching selector "${selector}"`
|
||||
);
|
||||
const result = await elementHandle.evaluate<ReturnType>(
|
||||
const result = await elementHandle.evaluate<(...args: any[]) => ReturnType>(
|
||||
pageFunction,
|
||||
...args
|
||||
);
|
||||
@ -813,8 +821,8 @@ export class ElementHandle extends JSHandle {
|
||||
*/
|
||||
async $$eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
const defaultHandler = (element: Element, selector: string) =>
|
||||
Array.from(element.querySelectorAll(selector));
|
||||
@ -827,7 +835,7 @@ export class ElementHandle extends JSHandle {
|
||||
queryHandler,
|
||||
updatedSelector
|
||||
);
|
||||
const result = await arrayHandle.evaluate<ReturnType>(
|
||||
const result = await arrayHandle.evaluate<(...args: any[]) => ReturnType>(
|
||||
pageFunction,
|
||||
...args
|
||||
);
|
||||
@ -868,16 +876,18 @@ export class ElementHandle extends JSHandle {
|
||||
* Resolves to true if the element is visible in the current viewport.
|
||||
*/
|
||||
async isIntersectingViewport(): Promise<boolean> {
|
||||
return await this.evaluate<Promise<boolean>>(async (element) => {
|
||||
const visibleRatio = await new Promise((resolve) => {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
resolve(entries[0].intersectionRatio);
|
||||
observer.disconnect();
|
||||
return await this.evaluate<(element: Element) => Promise<boolean>>(
|
||||
async (element) => {
|
||||
const visibleRatio = await new Promise((resolve) => {
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
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 { PuppeteerLifeCycleEvent } from './LifecycleWatcher';
|
||||
import Protocol from '../protocol';
|
||||
import { EvaluateFn, SerializableOrJSHandle } from './EvalTypes';
|
||||
|
||||
const writeFileAsync = promisify(fs.writeFile);
|
||||
|
||||
@ -514,16 +515,16 @@ export class Page extends EventEmitter {
|
||||
|
||||
async $eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
return this.mainFrame().$eval<ReturnType>(selector, pageFunction, ...args);
|
||||
}
|
||||
|
||||
async $$eval<ReturnType extends any>(
|
||||
selector: string,
|
||||
pageFunction: Function | string,
|
||||
...args: unknown[]
|
||||
pageFunction: EvaluateFn | string,
|
||||
...args: SerializableOrJSHandle[]
|
||||
): Promise<ReturnType> {
|
||||
return this.mainFrame().$$eval<ReturnType>(selector, pageFunction, ...args);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user