chore: use abstract for implemented methods (#10774)

This commit is contained in:
jrandolf 2023-08-23 18:00:34 +02:00 committed by GitHub
parent 27636afacf
commit 5f8d2a43b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 106 additions and 182 deletions

View File

@ -10,7 +10,7 @@ If the element is a form input, you can use [ElementHandle.autofill()](./puppete
```typescript
class ElementHandle {
autofill(data: AutofillData): Promise<void>;
abstract autofill(data: AutofillData): Promise<void>;
}
```

View File

@ -10,7 +10,10 @@ This method scrolls element into view if needed, and then uses [Page.mouse](./pu
```typescript
class ElementHandle {
click(this: ElementHandle<Element>, options?: ClickOptions): Promise<void>;
abstract click(
this: ElementHandle<Element>,
options?: ClickOptions
): Promise<void>;
}
```

View File

@ -4,13 +4,13 @@ sidebar_label: ElementHandle.contentFrame
# ElementHandle.contentFrame() method
Resolves the frame associated with the element.
Resolves the frame associated with the element, if any. Always exists for HTMLIFrameElements.
#### Signature:
```typescript
class ElementHandle {
contentFrame(this: ElementHandle<HTMLIFrameElement>): Promise<Frame>;
abstract contentFrame(this: ElementHandle<HTMLIFrameElement>): Promise<Frame>;
}
```

View File

@ -8,7 +8,7 @@ sidebar_label: ElementHandle.contentFrame_1
```typescript
class ElementHandle {
contentFrame(): Promise<Frame | null>;
abstract contentFrame(): Promise<Frame | null>;
}
```

View File

@ -10,7 +10,7 @@ This method scrolls element into view if needed, and then uses [Page](./puppetee
```typescript
class ElementHandle {
hover(this: ElementHandle<Element>): Promise<void>;
abstract hover(this: ElementHandle<Element>): Promise<void>;
}
```

View File

@ -9,7 +9,7 @@ ElementHandle represents an in-page DOM element.
#### Signature:
```typescript
export declare class ElementHandle<ElementType extends Node = Element> extends JSHandle<ElementType>
export declare abstract class ElementHandle<ElementType extends Node = Element> extends JSHandle<ElementType>
```
**Extends:** [JSHandle](./puppeteer.jshandle.md)&lt;ElementType&gt;
@ -41,9 +41,9 @@ The constructor for this class is marked as internal. Third-party code should no
## Properties
| Property | Modifiers | Type | Description |
| -------- | --------------------- | ----------------------------- | ----------- |
| frame | <code>readonly</code> | [Frame](./puppeteer.frame.md) | |
| Property | Modifiers | Type | Description |
| -------- | --------------------- | ----------------------------- | ------------------------------------------ |
| frame | <code>readonly</code> | [Frame](./puppeteer.frame.md) | Frame corresponding to the current handle. |
## Methods
@ -60,7 +60,7 @@ The constructor for this class is marked as internal. Third-party code should no
| [boxModel()](./puppeteer.elementhandle.boxmodel.md) | | This method returns boxes of the element, or <code>null</code> if the element is not visible. |
| [click(this, options)](./puppeteer.elementhandle.click.md) | | This method scrolls element into view if needed, and then uses [Page.mouse](./puppeteer.page.md) to click in the center of the element. If the element is detached from DOM, the method throws an error. |
| [clickablePoint(offset)](./puppeteer.elementhandle.clickablepoint.md) | | Returns the middle point within an element unless a specific offset is provided. |
| [contentFrame(this)](./puppeteer.elementhandle.contentframe.md) | | Resolves the frame associated with the element. |
| [contentFrame(this)](./puppeteer.elementhandle.contentframe.md) | | Resolves the frame associated with the element, if any. Always exists for HTMLIFrameElements. |
| [contentFrame()](./puppeteer.elementhandle.contentframe_1.md) | | |
| [drag(this, target)](./puppeteer.elementhandle.drag.md) | | This method creates and captures a dragevent from the element. |
| [dragAndDrop(this, target, options)](./puppeteer.elementhandle.draganddrop.md) | | This method triggers a dragenter, dragover, and drop on the element. |

View File

@ -10,7 +10,10 @@ Focuses the element, and then uses [Keyboard.down()](./puppeteer.keyboard.down.m
```typescript
class ElementHandle {
press(key: KeyInput, options?: Readonly<KeyPressOptions>): Promise<void>;
abstract press(
key: KeyInput,
options?: Readonly<KeyPressOptions>
): Promise<void>;
}
```

View File

@ -10,7 +10,7 @@ This method scrolls element into view if needed, and then uses [Touchscreen.tap(
```typescript
class ElementHandle {
tap(this: ElementHandle<Element>): Promise<void>;
abstract tap(this: ElementHandle<Element>): Promise<void>;
}
```

View File

@ -8,7 +8,7 @@ sidebar_label: ElementHandle.touchEnd
```typescript
class ElementHandle {
touchEnd(this: ElementHandle<Element>): Promise<void>;
abstract touchEnd(this: ElementHandle<Element>): Promise<void>;
}
```

View File

@ -8,7 +8,7 @@ sidebar_label: ElementHandle.touchMove
```typescript
class ElementHandle {
touchMove(this: ElementHandle<Element>): Promise<void>;
abstract touchMove(this: ElementHandle<Element>): Promise<void>;
}
```

View File

@ -8,7 +8,7 @@ sidebar_label: ElementHandle.touchStart
```typescript
class ElementHandle {
touchStart(this: ElementHandle<Element>): Promise<void>;
abstract touchStart(this: ElementHandle<Element>): Promise<void>;
}
```

View File

@ -12,7 +12,10 @@ To press a special key, like `Control` or `ArrowDown`, use [ElementHandle.press(
```typescript
class ElementHandle {
type(text: string, options?: Readonly<KeyboardTypeOptions>): Promise<void>;
abstract type(
text: string,
options?: Readonly<KeyboardTypeOptions>
): Promise<void>;
}
```

View File

@ -10,7 +10,7 @@ Either `null` or the handle itself if the handle is an instance of [ElementHandl
```typescript
class JSHandle {
asElement(): ElementHandle<Node> | null;
abstract asElement(): ElementHandle<Node> | null;
}
```

View File

@ -10,7 +10,7 @@ Releases the object referenced by the handle for garbage collection.
```typescript
class JSHandle {
dispose(): Promise<void>;
abstract dispose(): Promise<void>;
}
```

View File

@ -10,7 +10,7 @@ Evaluates the given function with the current handle as its first argument.
```typescript
class JSHandle {
evaluate<
abstract evaluate<
Params extends unknown[],
Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
>(

View File

@ -10,7 +10,7 @@ Evaluates the given function with the current handle as its first argument.
```typescript
class JSHandle {
evaluateHandle<
abstract evaluateHandle<
Params extends unknown[],
Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
>(

View File

@ -10,13 +10,13 @@ Gets a map of handles representing the properties of the current handle.
```typescript
class JSHandle {
getProperties(): Promise<Map<string, JSHandle>>;
abstract getProperties(): Promise<Map<string, JSHandle<unknown>>>;
}
```
**Returns:**
Promise&lt;Map&lt;string, [JSHandle](./puppeteer.jshandle.md)&gt;&gt;
Promise&lt;Map&lt;string, [JSHandle](./puppeteer.jshandle.md)&lt;unknown&gt;&gt;&gt;
## Example

View File

@ -10,7 +10,7 @@ Fetches a single property from the referenced object.
```typescript
class JSHandle {
getProperty<K extends keyof T>(
abstract getProperty<K extends keyof T>(
propertyName: HandleOr<K>
): Promise<HandleFor<T[K]>>;
}

View File

@ -8,7 +8,7 @@ sidebar_label: JSHandle.getProperty_1
```typescript
class JSHandle {
getProperty(propertyName: string): Promise<JSHandle<unknown>>;
abstract getProperty(propertyName: string): Promise<JSHandle<unknown>>;
}
```

View File

@ -1,25 +0,0 @@
---
sidebar_label: JSHandle.getProperty_2
---
# JSHandle.getProperty() method
#### Signature:
```typescript
class JSHandle {
getProperty<K extends keyof T>(
propertyName: HandleOr<K>
): Promise<HandleFor<T[K]>>;
}
```
## Parameters
| Parameter | Type | Description |
| ------------ | -------------------------------------------- | ----------- |
| propertyName | [HandleOr](./puppeteer.handleor.md)&lt;K&gt; | |
**Returns:**
Promise&lt;[HandleFor](./puppeteer.handlefor.md)&lt;T\[K\]&gt;&gt;

View File

@ -10,7 +10,7 @@ A vanilla object representing the serializable portions of the referenced object
```typescript
class JSHandle {
jsonValue(): Promise<T>;
abstract jsonValue(): Promise<T>;
}
```

View File

@ -13,7 +13,7 @@ Handles can be used as arguments for any evaluation function such as [Page.$eval
#### Signature:
```typescript
export declare class JSHandle<T = unknown>
export declare abstract class JSHandle<T = unknown>
```
## Remarks
@ -43,7 +43,6 @@ const windowHandle = await page.evaluateHandle(() => window);
| [getProperties()](./puppeteer.jshandle.getproperties.md) | | Gets a map of handles representing the properties of the current handle. |
| [getProperty(propertyName)](./puppeteer.jshandle.getproperty.md) | | Fetches a single property from the referenced object. |
| [getProperty(propertyName)](./puppeteer.jshandle.getproperty_1.md) | | |
| [getProperty(propertyName)](./puppeteer.jshandle.getproperty_2.md) | | |
| [jsonValue()](./puppeteer.jshandle.jsonvalue.md) | | A vanilla object representing the serializable portions of the referenced object. |
| [remoteObject()](./puppeteer.jshandle.remoteobject.md) | | Provides access to the [Protocol.Runtime.RemoteObject](https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-RemoteObject) backing this handle. |
| [toString()](./puppeteer.jshandle.tostring.md) | | Returns a string representation of the JSHandle. |

View File

@ -10,7 +10,7 @@ Provides access to the [Protocol.Runtime.RemoteObject](https://chromedevtools.gi
```typescript
class JSHandle {
remoteObject(): Protocol.Runtime.RemoteObject;
abstract remoteObject(): Protocol.Runtime.RemoteObject;
}
```

View File

@ -10,7 +10,7 @@ Returns a string representation of the JSHandle.
```typescript
class JSHandle {
toString(): string;
abstract toString(): string;
}
```

View File

@ -17,8 +17,6 @@
import {Protocol} from 'devtools-protocol';
import {Frame} from '../api/Frame.js';
import {CDPSession} from '../common/Connection.js';
import {ExecutionContext} from '../common/ExecutionContext.js';
import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js';
import {WaitForSelectorOptions} from '../common/IsolatedWorld.js';
import {LazyArg} from '../common/LazyArg.js';
@ -39,9 +37,9 @@ import {assert} from '../util/assert.js';
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
import {
KeyboardTypeOptions,
KeyPressOptions,
MouseClickOptions,
KeyboardTypeOptions,
} from './Input.js';
import {JSHandle} from './JSHandle.js';
import {ScreenshotOptions} from './Page.js';
@ -143,7 +141,7 @@ export interface Point {
* @public
*/
export class ElementHandle<
export abstract class ElementHandle<
ElementType extends Node = Element,
> extends JSHandle<ElementType> {
/**
@ -242,6 +240,13 @@ export class ElementHandle<
return this.handle.toString();
}
/**
* @internal
*/
override remoteObject(): Protocol.Runtime.RemoteObject {
return this.handle.remoteObject();
}
/**
* @internal
*/
@ -254,22 +259,9 @@ export class ElementHandle<
}
/**
* @internal
* Frame corresponding to the current handle.
*/
override executionContext(): ExecutionContext {
throw new Error('Not implemented');
}
/**
* @internal
*/
override get client(): CDPSession {
throw new Error('Not implemented');
}
get frame(): Frame {
throw new Error('Not implemented');
}
abstract get frame(): Frame;
/**
* Queries the current element for an element matching the given selector.
@ -629,13 +621,11 @@ export class ElementHandle<
}
/**
* Resolves the frame associated with the element.
* Resolves the frame associated with the element, if any. Always exists for
* HTMLIFrameElements.
*/
async contentFrame(this: ElementHandle<HTMLIFrameElement>): Promise<Frame>;
async contentFrame(): Promise<Frame | null>;
async contentFrame(): Promise<Frame | null> {
throw new Error('Not implemented');
}
abstract contentFrame(this: ElementHandle<HTMLIFrameElement>): Promise<Frame>;
abstract contentFrame(): Promise<Frame | null>;
/**
* Returns the middle point within an element unless a specific offset is provided.
@ -650,22 +640,17 @@ export class ElementHandle<
* uses {@link Page} to hover over the center of the element.
* If the element is detached from DOM, the method throws an error.
*/
async hover(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
abstract hover(this: ElementHandle<Element>): Promise<void>;
/**
* This method scrolls element into view if needed, and then
* uses {@link Page | Page.mouse} to click in the center of the element.
* If the element is detached from DOM, the method throws an error.
*/
async click(
abstract click(
this: ElementHandle<Element>,
options?: ClickOptions
): Promise<void>;
async click(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
/**
* This method creates and captures a dragevent from the element.
@ -807,21 +792,13 @@ export class ElementHandle<
* {@link Touchscreen.tap} to tap in the center of the element.
* If the element is detached from DOM, the method throws an error.
*/
async tap(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
abstract tap(this: ElementHandle<Element>): Promise<void>;
async touchStart(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
abstract touchStart(this: ElementHandle<Element>): Promise<void>;
async touchMove(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
abstract touchMove(this: ElementHandle<Element>): Promise<void>;
async touchEnd(this: ElementHandle<Element>): Promise<void> {
throw new Error('Not implemented');
}
abstract touchEnd(this: ElementHandle<Element>): Promise<void>;
/**
* Calls {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus | focus} on the element.
@ -860,13 +837,10 @@ export class ElementHandle<
*
* @param options - Delay in milliseconds. Defaults to 0.
*/
async type(
abstract type(
text: string,
options?: Readonly<KeyboardTypeOptions>
): Promise<void>;
async type(): Promise<void> {
throw new Error('Not implemented');
}
/**
* Focuses the element, and then uses {@link Keyboard.down} and {@link Keyboard.up}.
@ -882,13 +856,10 @@ export class ElementHandle<
* @param key - Name of key to press, such as `ArrowLeft`.
* See {@link KeyInput} for a list of all key names.
*/
async press(
abstract press(
key: KeyInput,
options?: Readonly<KeyPressOptions>
): Promise<void>;
async press(): Promise<void> {
throw new Error('Not implemented');
}
/**
* This method returns the bounding box of the element (relative to the main frame),
@ -1205,9 +1176,7 @@ export class ElementHandle<
/**
* @internal
*/
assertElementHasWorld(): asserts this {
assert(this.executionContext()._world);
}
abstract assertElementHasWorld(): asserts this;
/**
* If the element is a form input, you can use {@link ElementHandle.autofill}
@ -1234,10 +1203,7 @@ export class ElementHandle<
* });
* ```
*/
autofill(data: AutofillData): Promise<void>;
autofill(): Promise<void> {
throw new Error('Not implemented');
}
abstract autofill(data: AutofillData): Promise<void>;
}
/**

View File

@ -16,8 +16,6 @@
import Protocol from 'devtools-protocol';
import {CDPSession} from '../common/Connection.js';
import {ExecutionContext} from '../common/ExecutionContext.js';
import {EvaluateFuncWith, HandleFor, HandleOr} from '../common/types.js';
import {ElementHandle} from './ElementHandle.js';
@ -43,7 +41,7 @@ import {ElementHandle} from './ElementHandle.js';
*
* @public
*/
export class JSHandle<T = unknown> {
export abstract class JSHandle<T = unknown> {
/**
* Used for nominally typing {@link JSHandle}.
*/
@ -61,62 +59,36 @@ export class JSHandle<T = unknown> {
throw new Error('Not implemented');
}
/**
* @internal
*/
executionContext(): ExecutionContext {
throw new Error('Not implemented');
}
/**
* @internal
*/
get client(): CDPSession {
throw new Error('Not implemented');
}
/**
* Evaluates the given function with the current handle as its first argument.
*/
async evaluate<
abstract evaluate<
Params extends unknown[],
Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
>(
pageFunction: Func | string,
...args: Params
): Promise<Awaited<ReturnType<Func>>>;
async evaluate(): Promise<unknown> {
throw new Error('Not implemented');
}
/**
* Evaluates the given function with the current handle as its first argument.
*
*/
async evaluateHandle<
abstract evaluateHandle<
Params extends unknown[],
Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
>(
pageFunction: Func | string,
...args: Params
): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
async evaluateHandle(): Promise<HandleFor<unknown>> {
throw new Error('Not implemented');
}
/**
* Fetches a single property from the referenced object.
*/
async getProperty<K extends keyof T>(
abstract getProperty<K extends keyof T>(
propertyName: HandleOr<K>
): Promise<HandleFor<T[K]>>;
async getProperty(propertyName: string): Promise<JSHandle<unknown>>;
async getProperty<K extends keyof T>(
propertyName: HandleOr<K>
): Promise<HandleFor<T[K]>>;
async getProperty<K extends keyof T>(): Promise<HandleFor<T[K]>> {
throw new Error('Not implemented');
}
abstract getProperty(propertyName: string): Promise<JSHandle<unknown>>;
/**
* Gets a map of handles representing the properties of the current handle.
@ -136,9 +108,7 @@ export class JSHandle<T = unknown> {
* children; // holds elementHandles to all children of document.body
* ```
*/
async getProperties(): Promise<Map<string, JSHandle>> {
throw new Error('Not implemented');
}
abstract getProperties(): Promise<Map<string, JSHandle<unknown>>>;
/**
* A vanilla object representing the serializable portions of the
@ -148,24 +118,18 @@ export class JSHandle<T = unknown> {
* @remarks
* If the object has a `toJSON` function, it **will not** be called.
*/
async jsonValue(): Promise<T> {
throw new Error('Not implemented');
}
abstract jsonValue(): Promise<T>;
/**
* Either `null` or the handle itself if the handle is an
* instance of {@link ElementHandle}.
*/
asElement(): ElementHandle<Node> | null {
throw new Error('Not implemented');
}
abstract asElement(): ElementHandle<Node> | null;
/**
* Releases the object referenced by the handle for garbage collection.
*/
async dispose(): Promise<void> {
throw new Error('Not implemented');
}
abstract dispose(): Promise<void>;
/**
* Returns a string representation of the JSHandle.
@ -173,23 +137,17 @@ export class JSHandle<T = unknown> {
* @remarks
* Useful during debugging.
*/
toString(): string {
throw new Error('Not implemented');
}
abstract toString(): string;
/**
* @internal
*/
get id(): string | undefined {
throw new Error('Not implemented');
}
abstract get id(): string | undefined;
/**
* Provides access to the
* {@link https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#type-RemoteObject | Protocol.Runtime.RemoteObject}
* backing this handle.
*/
remoteObject(): Protocol.Runtime.RemoteObject {
throw new Error('Not implemented');
}
abstract remoteObject(): Protocol.Runtime.RemoteObject;
}

View File

@ -21,6 +21,7 @@ import {assert} from '../util/assert.js';
import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js';
import {CDPSession} from './Connection.js';
import {CDPJSHandle} from './JSHandle.js';
import {QueryHandler, QuerySelector} from './QueryHandler.js';
import {AwaitableIterable} from './types.js';
@ -105,7 +106,9 @@ export class ARIAQueryHandler extends QueryHandler {
element: ElementHandle<Node>,
selector: string
): AwaitableIterable<ElementHandle<Node>> {
const context = element.executionContext();
const context = (
element as unknown as CDPJSHandle<Node>
).executionContext();
const {name, role} = parseARIASelector(selector);
const results = await queryAXTree(context._client, element, name, role);
const world = context._world!;

View File

@ -76,14 +76,14 @@ export class CDPElementHandle<
/**
* @internal
*/
override executionContext(): ExecutionContext {
executionContext(): ExecutionContext {
return this.handle.executionContext();
}
/**
* @internal
*/
override get client(): CDPSession {
get client(): CDPSession {
return this.handle.client;
}
@ -527,6 +527,10 @@ export class CDPElementHandle<
card: data.creditCard,
});
}
override assertElementHasWorld(): asserts this {
assert(this.executionContext()._world);
}
}
function computeQuadArea(quad: Point[]): number {

View File

@ -105,12 +105,14 @@ export class ExecutionContext {
selector: string
): Promise<JSHandle<Node[]>> => {
const results = ARIAQueryHandler.queryAll(element, selector);
return element.executionContext().evaluateHandle(
(...elements) => {
return elements;
},
...(await AsyncIterableUtil.collect(results))
);
return (element as unknown as CDPJSHandle<Node>)
.executionContext()
.evaluateHandle(
(...elements) => {
return elements;
},
...(await AsyncIterableUtil.collect(results))
);
}) as (...args: unknown[]) => unknown)
),
]);

View File

@ -29,6 +29,7 @@ import {ExecutionContext} from './ExecutionContext.js';
import {Frame} from './Frame.js';
import {FrameManager} from './FrameManager.js';
import {MAIN_WORLD, PUPPETEER_WORLD} from './IsolatedWorlds.js';
import {CDPJSHandle} from './JSHandle.js';
import {LifecycleWatcher, PuppeteerLifeCycleEvent} from './LifecycleWatcher.js';
import {TimeoutSettings} from './TimeoutSettings.js';
import {
@ -500,7 +501,7 @@ export class IsolatedWorld implements Realm {
async adoptHandle<T extends JSHandle<Node>>(handle: T): Promise<T> {
const context = await this.executionContext();
assert(
handle.executionContext() !== context,
(handle as unknown as CDPJSHandle<Node>).executionContext() !== context,
'Cannot adopt handle that already belongs to this execution context'
);
const nodeInfo = await this.#client.send('DOM.describeNode', {
@ -511,7 +512,9 @@ export class IsolatedWorld implements Realm {
async transferHandle<T extends JSHandle<Node>>(handle: T): Promise<T> {
const context = await this.executionContext();
if (handle.executionContext() === context) {
if (
(handle as unknown as CDPJSHandle<Node>).executionContext() === context
) {
return handle;
}
const info = await this.#client.send('DOM.describeNode', {

View File

@ -51,11 +51,11 @@ export class CDPJSHandle<T = unknown> extends JSHandle<T> {
this.#remoteObject = remoteObject;
}
override executionContext(): ExecutionContext {
executionContext(): ExecutionContext {
return this.#context;
}
override get client(): CDPSession {
get client(): CDPSession {
return this.#context._client;
}

View File

@ -67,7 +67,7 @@ export class ElementHandle<
/**
* @internal
*/
override assertElementHasWorld(): asserts this {
assertElementHasWorld(): asserts this {
// TODO: Should assert element has a Sandbox
return;
}

View File

@ -15,6 +15,7 @@
*/
import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
import Protocol from 'devtools-protocol';
import {ElementHandle} from '../../api/ElementHandle.js';
import {JSHandle as BaseJSHandle} from '../../api/JSHandle.js';
@ -167,4 +168,8 @@ export class JSHandle<T = unknown> extends BaseJSHandle<T> {
remoteValue(): Bidi.Script.RemoteValue {
return this.#remoteValue;
}
override remoteObject(): Protocol.Runtime.RemoteObject {
throw new Error('Not available in WebDriver BiDi');
}
}