404 lines
9.9 KiB
Go
404 lines
9.9 KiB
Go
package playwright
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
type elementHandleImpl struct {
|
|
jsHandleImpl
|
|
}
|
|
|
|
func (e *elementHandleImpl) AsElement() ElementHandle {
|
|
return e
|
|
}
|
|
|
|
func (e *elementHandleImpl) OwnerFrame() (Frame, error) {
|
|
channel, err := e.channel.Send("ownerFrame")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
channelOwner := fromNullableChannel(channel)
|
|
if channelOwner == nil {
|
|
return nil, nil
|
|
}
|
|
return channelOwner.(*frameImpl), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) ContentFrame() (Frame, error) {
|
|
channel, err := e.channel.Send("contentFrame")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
channelOwner := fromNullableChannel(channel)
|
|
if channelOwner == nil {
|
|
return nil, nil
|
|
}
|
|
return channelOwner.(*frameImpl), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) GetAttribute(name string) (string, error) {
|
|
attribute, err := e.channel.Send("getAttribute", map[string]interface{}{
|
|
"name": name,
|
|
})
|
|
if attribute == nil {
|
|
return "", err
|
|
}
|
|
return attribute.(string), err
|
|
}
|
|
|
|
func (e *elementHandleImpl) TextContent() (string, error) {
|
|
textContent, err := e.channel.Send("textContent")
|
|
if textContent == nil {
|
|
return "", err
|
|
}
|
|
return textContent.(string), err
|
|
}
|
|
|
|
func (e *elementHandleImpl) InnerText() (string, error) {
|
|
innerText, err := e.channel.Send("innerText")
|
|
if innerText == nil {
|
|
return "", err
|
|
}
|
|
return innerText.(string), err
|
|
}
|
|
|
|
func (e *elementHandleImpl) InnerHTML() (string, error) {
|
|
innerHTML, err := e.channel.Send("innerHTML")
|
|
if innerHTML == nil {
|
|
return "", err
|
|
}
|
|
return innerHTML.(string), err
|
|
}
|
|
|
|
func (e *elementHandleImpl) DispatchEvent(typ string, initObjects ...interface{}) error {
|
|
var initObject interface{}
|
|
if len(initObjects) == 1 {
|
|
initObject = initObjects[0]
|
|
}
|
|
_, err := e.channel.Send("dispatchEvent", map[string]interface{}{
|
|
"type": typ,
|
|
"eventInit": serializeArgument(initObject),
|
|
})
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Hover(options ...ElementHandleHoverOptions) error {
|
|
_, err := e.channel.Send("hover", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Click(options ...ElementHandleClickOptions) error {
|
|
_, err := e.channel.Send("click", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Dblclick(options ...ElementHandleDblclickOptions) error {
|
|
_, err := e.channel.Send("dblclick", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) QuerySelector(selector string) (ElementHandle, error) {
|
|
channel, err := e.channel.Send("querySelector", map[string]interface{}{
|
|
"selector": selector,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if channel == nil {
|
|
return nil, nil
|
|
}
|
|
return fromChannel(channel).(*elementHandleImpl), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) QuerySelectorAll(selector string) ([]ElementHandle, error) {
|
|
channels, err := e.channel.Send("querySelectorAll", map[string]interface{}{
|
|
"selector": selector,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
elements := make([]ElementHandle, 0)
|
|
for _, channel := range channels.([]interface{}) {
|
|
elements = append(elements, fromChannel(channel).(*elementHandleImpl))
|
|
}
|
|
return elements, nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) EvalOnSelector(selector string, expression string, options ...interface{}) (interface{}, error) {
|
|
var arg interface{}
|
|
if len(options) == 1 {
|
|
arg = options[0]
|
|
}
|
|
result, err := e.channel.Send("evalOnSelector", map[string]interface{}{
|
|
"selector": selector,
|
|
"expression": expression,
|
|
"arg": serializeArgument(arg),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return parseResult(result), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) EvalOnSelectorAll(selector string, expression string, options ...interface{}) (interface{}, error) {
|
|
var arg interface{}
|
|
if len(options) == 1 {
|
|
arg = options[0]
|
|
}
|
|
result, err := e.channel.Send("evalOnSelectorAll", map[string]interface{}{
|
|
"selector": selector,
|
|
"expression": expression,
|
|
"arg": serializeArgument(arg),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return parseResult(result), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) ScrollIntoViewIfNeeded(options ...ElementHandleScrollIntoViewIfNeededOptions) error {
|
|
_, err := e.channel.Send("scrollIntoViewIfNeeded", options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) SetInputFiles(files interface{}, options ...ElementHandleSetInputFilesOptions) error {
|
|
frame, err := e.OwnerFrame()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if frame == nil {
|
|
return errors.New("Cannot set input files to detached element")
|
|
}
|
|
|
|
params, err := convertInputFiles(files, frame.(*frameImpl).page.browserContext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = e.channel.Send("setInputFiles", params, options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) BoundingBox() (*Rect, error) {
|
|
boundingBox, err := e.channel.Send("boundingBox")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if boundingBox == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
out := &Rect{}
|
|
remapMapToStruct(boundingBox, out)
|
|
return out, nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) Check(options ...ElementHandleCheckOptions) error {
|
|
_, err := e.channel.Send("check", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Uncheck(options ...ElementHandleUncheckOptions) error {
|
|
_, err := e.channel.Send("uncheck", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Press(key string, options ...ElementHandlePressOptions) error {
|
|
_, err := e.channel.Send("press", map[string]interface{}{
|
|
"key": key,
|
|
}, options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Fill(value string, options ...ElementHandleFillOptions) error {
|
|
_, err := e.channel.Send("fill", map[string]interface{}{
|
|
"value": value,
|
|
}, options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Type(value string, options ...ElementHandleTypeOptions) error {
|
|
_, err := e.channel.Send("type", map[string]interface{}{
|
|
"text": value,
|
|
}, options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Focus() error {
|
|
_, err := e.channel.Send("focus")
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) SelectText(options ...ElementHandleSelectTextOptions) error {
|
|
_, err := e.channel.Send("selectText", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) Screenshot(options ...ElementHandleScreenshotOptions) ([]byte, error) {
|
|
var path *string
|
|
overrides := map[string]interface{}{}
|
|
if len(options) == 1 {
|
|
path = options[0].Path
|
|
options[0].Path = nil
|
|
if options[0].Mask != nil {
|
|
masks := make([]map[string]interface{}, 0)
|
|
for _, m := range options[0].Mask {
|
|
if m.Err() != nil { // ErrLocatorNotSameFrame
|
|
return nil, m.Err()
|
|
}
|
|
l, ok := m.(*locatorImpl)
|
|
if ok {
|
|
masks = append(masks, map[string]interface{}{
|
|
"selector": l.selector,
|
|
"frame": l.frame.channel,
|
|
})
|
|
}
|
|
}
|
|
overrides["mask"] = masks
|
|
options[0].Mask = nil
|
|
}
|
|
}
|
|
data, err := e.channel.Send("screenshot", options, overrides)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
image, err := base64.StdEncoding.DecodeString(data.(string))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not decode base64 :%w", err)
|
|
}
|
|
if path != nil {
|
|
if err := os.WriteFile(*path, image, 0o644); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return image, nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) Tap(options ...ElementHandleTapOptions) error {
|
|
_, err := e.channel.Send("tap", options)
|
|
return err
|
|
}
|
|
|
|
func (e *elementHandleImpl) SelectOption(values SelectOptionValues, options ...ElementHandleSelectOptionOptions) ([]string, error) {
|
|
opts := convertSelectOptionSet(values)
|
|
selected, err := e.channel.Send("selectOption", opts, options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return transformToStringList(selected), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsChecked() (bool, error) {
|
|
checked, err := e.channel.Send("isChecked")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return checked.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsDisabled() (bool, error) {
|
|
disabled, err := e.channel.Send("isDisabled")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return disabled.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsEditable() (bool, error) {
|
|
editable, err := e.channel.Send("isEditable")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return editable.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsEnabled() (bool, error) {
|
|
enabled, err := e.channel.Send("isEnabled")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return enabled.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsHidden() (bool, error) {
|
|
hidden, err := e.channel.Send("isHidden")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return hidden.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) IsVisible() (bool, error) {
|
|
visible, err := e.channel.Send("isVisible")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return visible.(bool), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) WaitForElementState(state ElementState, options ...ElementHandleWaitForElementStateOptions) error {
|
|
_, err := e.channel.Send("waitForElementState", map[string]interface{}{
|
|
"state": state,
|
|
}, options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) WaitForSelector(selector string, options ...ElementHandleWaitForSelectorOptions) (ElementHandle, error) {
|
|
ch, err := e.channel.Send("waitForSelector", map[string]interface{}{
|
|
"selector": selector,
|
|
}, options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
channelOwner := fromNullableChannel(ch)
|
|
if channelOwner == nil {
|
|
return nil, nil
|
|
}
|
|
return channelOwner.(*elementHandleImpl), nil
|
|
}
|
|
|
|
func (e *elementHandleImpl) InputValue(options ...ElementHandleInputValueOptions) (string, error) {
|
|
result, err := e.channel.Send("inputValue", options)
|
|
if result == nil {
|
|
return "", err
|
|
}
|
|
return result.(string), err
|
|
}
|
|
|
|
func (e *elementHandleImpl) SetChecked(checked bool, options ...ElementHandleSetCheckedOptions) error {
|
|
if checked {
|
|
_, err := e.channel.Send("check", options)
|
|
return err
|
|
} else {
|
|
_, err := e.channel.Send("uncheck", options)
|
|
return err
|
|
}
|
|
}
|
|
|
|
func newElementHandle(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *elementHandleImpl {
|
|
bt := &elementHandleImpl{}
|
|
bt.createChannelOwner(bt, parent, objectType, guid, initializer)
|
|
return bt
|
|
}
|
|
|
|
func transformToStringList(in interface{}) []string {
|
|
s := in.([]interface{})
|
|
|
|
var out []string
|
|
for _, v := range s {
|
|
out = append(out, v.(string))
|
|
}
|
|
return out
|
|
}
|