2020-06-25 16:05:36 -07:00
|
|
|
/**
|
|
|
|
* 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 * as types from '../../types';
|
2020-06-26 12:28:27 -07:00
|
|
|
import { ElementHandleChannel, JSHandleInitializer } from '../channels';
|
2020-06-25 16:05:36 -07:00
|
|
|
import { Frame } from './frame';
|
2020-06-27 11:10:07 -07:00
|
|
|
import { FuncOn, JSHandle, serializeArgument, parseResult } from './jsHandle';
|
2020-07-10 15:11:47 -07:00
|
|
|
import { ChannelOwner } from './channelOwner';
|
2020-06-25 16:05:36 -07:00
|
|
|
|
|
|
|
export class ElementHandle<T extends Node = Node> extends JSHandle<T> {
|
2020-06-25 18:01:18 -07:00
|
|
|
readonly _elementChannel: ElementHandleChannel;
|
2020-06-25 16:05:36 -07:00
|
|
|
|
|
|
|
static from(handle: ElementHandleChannel): ElementHandle {
|
2020-07-01 18:36:09 -07:00
|
|
|
return (handle as any)._object;
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static fromNullable(handle: ElementHandleChannel | null): ElementHandle | null {
|
|
|
|
return handle ? ElementHandle.from(handle) : null;
|
|
|
|
}
|
|
|
|
|
2020-07-10 15:11:47 -07:00
|
|
|
constructor(parent: ChannelOwner, guid: string, initializer: JSHandleInitializer) {
|
|
|
|
super(parent, guid, initializer);
|
2020-07-01 13:55:29 -07:00
|
|
|
this._elementChannel = this._channel as ElementHandleChannel;
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
asElement(): ElementHandle<T> | null {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
async ownerFrame(): Promise<Frame | null> {
|
|
|
|
return Frame.fromNullable(await this._elementChannel.ownerFrame());
|
|
|
|
}
|
|
|
|
|
|
|
|
async contentFrame(): Promise<Frame | null> {
|
|
|
|
return Frame.fromNullable(await this._elementChannel.contentFrame());
|
|
|
|
}
|
|
|
|
|
|
|
|
async getAttribute(name: string): Promise<string | null> {
|
|
|
|
return await this._elementChannel.getAttribute({ name });
|
|
|
|
}
|
|
|
|
|
|
|
|
async textContent(): Promise<string | null> {
|
|
|
|
return await this._elementChannel.textContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
async innerText(): Promise<string> {
|
|
|
|
return await this._elementChannel.innerText();
|
|
|
|
}
|
|
|
|
|
|
|
|
async innerHTML(): Promise<string> {
|
|
|
|
return await this._elementChannel.innerHTML();
|
|
|
|
}
|
|
|
|
|
|
|
|
async dispatchEvent(type: string, eventInit: Object = {}) {
|
|
|
|
await this._elementChannel.dispatchEvent({ type, eventInit });
|
|
|
|
}
|
|
|
|
|
2020-07-06 10:04:09 -07:00
|
|
|
async scrollIntoViewIfNeeded(options: types.TimeoutOptions = {}) {
|
|
|
|
await this._elementChannel.scrollIntoViewIfNeeded(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async hover(options: types.PointerActionOptions & types.PointerActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
await this._elementChannel.hover(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async click(options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.click(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async dblclick(options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.dblclick(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async selectOption(values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[] | null, options: types.NavigatingActionWaitOptions = {}): Promise<string[]> {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.selectOption({ values: convertSelectOptionValues(values), ...options });
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async fill(value: string, options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.fill({ value, ...options });
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async selectText(options: types.TimeoutOptions): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
await this._elementChannel.selectText(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async setInputFiles(files: string | types.FilePayload | string[] | types.FilePayload[], options: types.NavigatingActionWaitOptions = {}) {
|
2020-07-06 10:04:09 -07:00
|
|
|
await this._elementChannel.setInputFiles({ files, ...options });
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async focus(): Promise<void> {
|
|
|
|
await this._elementChannel.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
async type(text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
await this._elementChannel.type({ text, ...options });
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async press(key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}): Promise<void> {
|
2020-07-06 10:04:09 -07:00
|
|
|
await this._elementChannel.press({ key, ...options });
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async check(options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.check(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async uncheck(options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
2020-07-06 10:04:09 -07:00
|
|
|
return await this._elementChannel.uncheck(options);
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async boundingBox(): Promise<types.Rect | null> {
|
|
|
|
return await this._elementChannel.boundingBox();
|
|
|
|
}
|
|
|
|
|
2020-07-06 10:04:09 -07:00
|
|
|
async screenshot(options: types.ElementScreenshotOptions = {}): Promise<Buffer> {
|
|
|
|
return Buffer.from(await this._elementChannel.screenshot(options), 'base64');
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async $(selector: string): Promise<ElementHandle<Element> | null> {
|
|
|
|
return ElementHandle.fromNullable(await this._elementChannel.querySelector({ selector })) as ElementHandle<Element> | null;
|
|
|
|
}
|
|
|
|
|
|
|
|
async $$(selector: string): Promise<ElementHandle<Element>[]> {
|
|
|
|
return (await this._elementChannel.querySelectorAll({ selector })).map(h => ElementHandle.from(h) as ElementHandle<Element>);
|
|
|
|
}
|
|
|
|
|
|
|
|
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
|
|
|
|
async $eval<R>(selector: string, pageFunction: FuncOn<Element, void, R>, arg?: any): Promise<R>;
|
|
|
|
async $eval<R, Arg>(selector: string, pageFunction: FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
|
2020-07-03 18:04:08 -07:00
|
|
|
return parseResult(await this._elementChannel.evalOnSelector({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }));
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R>;
|
|
|
|
async $$eval<R>(selector: string, pageFunction: FuncOn<Element[], void, R>, arg?: any): Promise<R>;
|
|
|
|
async $$eval<R, Arg>(selector: string, pageFunction: FuncOn<Element[], Arg, R>, arg: Arg): Promise<R> {
|
2020-07-03 18:04:08 -07:00
|
|
|
return parseResult(await this._elementChannel.evalOnSelectorAll({ selector, expression: String(pageFunction), isFunction: typeof pageFunction === 'function', arg: serializeArgument(arg) }));
|
2020-06-25 16:05:36 -07:00
|
|
|
}
|
|
|
|
}
|
2020-06-26 11:51:47 -07:00
|
|
|
|
|
|
|
export function convertSelectOptionValues(values: string | ElementHandle | types.SelectOption | string[] | ElementHandle[] | types.SelectOption[] | null): string | ElementHandleChannel | types.SelectOption | string[] | ElementHandleChannel[] | types.SelectOption[] | null {
|
|
|
|
if (values instanceof ElementHandle)
|
|
|
|
return values._elementChannel;
|
|
|
|
if (Array.isArray(values) && values.length && values[0] instanceof ElementHandle)
|
|
|
|
return (values as ElementHandle[]).map((v: ElementHandle) => v._elementChannel);
|
|
|
|
return values as any;
|
|
|
|
}
|