899 lines
21 KiB
Go
899 lines
21 KiB
Go
package playwright
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
var (
|
|
testIdAttributeName = "data-testid"
|
|
ErrLocatorNotSameFrame = errors.New("inner 'has' or 'hasNot' locator must belong to the same frame")
|
|
)
|
|
|
|
type locatorImpl struct {
|
|
frame *frameImpl
|
|
selector string
|
|
options *LocatorLocatorOptions
|
|
err error
|
|
}
|
|
|
|
func newLocator(frame *frameImpl, selector string, options ...LocatorLocatorOptions) *locatorImpl {
|
|
option := &LocatorLocatorOptions{}
|
|
if len(options) == 1 {
|
|
option = &options[0]
|
|
}
|
|
locator := &locatorImpl{frame: frame, selector: selector, options: option, err: nil}
|
|
if option.HasText != nil {
|
|
selector += fmt.Sprintf(` >> internal:has-text=%s`, escapeForTextSelector(option.HasText, false))
|
|
}
|
|
if option.HasNotText != nil {
|
|
selector += fmt.Sprintf(` >> internal:has-not-text=%s`, escapeForTextSelector(option.HasNotText, false))
|
|
}
|
|
if option.Has != nil {
|
|
has := option.Has.(*locatorImpl)
|
|
if frame != has.frame {
|
|
locator.err = errors.Join(locator.err, ErrLocatorNotSameFrame)
|
|
} else {
|
|
selector += fmt.Sprintf(` >> internal:has=%s`, escapeText(has.selector))
|
|
}
|
|
}
|
|
if option.HasNot != nil {
|
|
hasNot := option.HasNot.(*locatorImpl)
|
|
if frame != hasNot.frame {
|
|
locator.err = errors.Join(locator.err, ErrLocatorNotSameFrame)
|
|
} else {
|
|
selector += fmt.Sprintf(` >> internal:has-not=%s`, escapeText(hasNot.selector))
|
|
}
|
|
}
|
|
locator.selector = selector
|
|
|
|
return locator
|
|
}
|
|
|
|
func (l *locatorImpl) equals(locator Locator) bool {
|
|
return l.frame == locator.(*locatorImpl).frame && l.err == locator.(*locatorImpl).err && l.selector == locator.(*locatorImpl).selector
|
|
}
|
|
|
|
func (l *locatorImpl) Err() error {
|
|
return l.err
|
|
}
|
|
|
|
func (l *locatorImpl) All() ([]Locator, error) {
|
|
result := make([]Locator, 0)
|
|
count, err := l.Count()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for i := 0; i < count; i++ {
|
|
result = append(result, l.Nth(i))
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (l *locatorImpl) AllInnerTexts() ([]string, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
innerTexts, err := l.frame.EvalOnSelectorAll(l.selector, "ee => ee.map(e => e.innerText)")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
texts := innerTexts.([]interface{})
|
|
result := make([]string, len(texts))
|
|
for i := range texts {
|
|
result[i] = texts[i].(string)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (l *locatorImpl) AllTextContents() ([]string, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
textContents, err := l.frame.EvalOnSelectorAll(l.selector, "ee => ee.map(e => e.textContent || '')")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
texts := textContents.([]interface{})
|
|
result := make([]string, len(texts))
|
|
for i := range texts {
|
|
result[i] = texts[i].(string)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (l *locatorImpl) And(locator Locator) Locator {
|
|
return newLocator(l.frame, l.selector+` >> internal:and=`+escapeText(locator.(*locatorImpl).selector))
|
|
}
|
|
|
|
func (l *locatorImpl) Or(locator Locator) Locator {
|
|
return newLocator(l.frame, l.selector+` >> internal:or=`+escapeText(locator.(*locatorImpl).selector))
|
|
}
|
|
|
|
func (l *locatorImpl) Blur(options ...LocatorBlurOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
params := map[string]interface{}{
|
|
"selector": l.selector,
|
|
"strict": true,
|
|
}
|
|
if len(options) == 1 {
|
|
if options[0].Timeout != nil {
|
|
params["timeout"] = options[0].Timeout
|
|
}
|
|
}
|
|
_, err := l.frame.channel.Send("blur", params)
|
|
return err
|
|
}
|
|
|
|
func (l *locatorImpl) AriaSnapshot(options ...LocatorAriaSnapshotOptions) (string, error) {
|
|
var option LocatorAriaSnapshotOptions
|
|
if len(options) == 1 {
|
|
option = options[0]
|
|
}
|
|
ret, err := l.frame.channel.Send("ariaSnapshot", option,
|
|
map[string]interface{}{"selector": l.selector})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return ret.(string), nil
|
|
}
|
|
|
|
func (l *locatorImpl) BoundingBox(options ...LocatorBoundingBoxOptions) (*Rect, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
result, err := l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
return handle.BoundingBox()
|
|
}, option)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result.(*Rect), nil
|
|
}
|
|
|
|
func (l *locatorImpl) Check(options ...LocatorCheckOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameCheckOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Check(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Clear(options ...LocatorClearOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
if len(options) == 1 {
|
|
return l.Fill("", LocatorFillOptions{
|
|
Force: options[0].Force,
|
|
Timeout: options[0].Timeout,
|
|
})
|
|
} else {
|
|
return l.Fill("")
|
|
}
|
|
}
|
|
|
|
func (l *locatorImpl) Click(options ...LocatorClickOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameClickOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Click(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) ContentFrame() FrameLocator {
|
|
return newFrameLocator(l.frame, l.selector)
|
|
}
|
|
|
|
func (l *locatorImpl) Count() (int, error) {
|
|
if l.err != nil {
|
|
return 0, l.err
|
|
}
|
|
return l.frame.queryCount(l.selector)
|
|
}
|
|
|
|
func (l *locatorImpl) Dblclick(options ...LocatorDblclickOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameDblclickOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Dblclick(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) DispatchEvent(typ string, eventInit interface{}, options ...LocatorDispatchEventOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameDispatchEventOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.DispatchEvent(l.selector, typ, eventInit, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) DragTo(target Locator, options ...LocatorDragToOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameDragAndDropOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.DragAndDrop(l.selector, target.(*locatorImpl).selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) ElementHandle(options ...LocatorElementHandleOptions) (ElementHandle, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
option := FrameWaitForSelectorOptions{
|
|
State: WaitForSelectorStateAttached,
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&option, options[0], false); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return l.frame.WaitForSelector(l.selector, option)
|
|
}
|
|
|
|
func (l *locatorImpl) ElementHandles() ([]ElementHandle, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
return l.frame.QuerySelectorAll(l.selector)
|
|
}
|
|
|
|
func (l *locatorImpl) Evaluate(expression string, arg interface{}, options ...LocatorEvaluateOptions) (interface{}, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
return l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
return handle.Evaluate(expression, arg)
|
|
}, option)
|
|
}
|
|
|
|
func (l *locatorImpl) EvaluateAll(expression string, options ...interface{}) (interface{}, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
return l.frame.EvalOnSelectorAll(l.selector, expression, options...)
|
|
}
|
|
|
|
func (l *locatorImpl) EvaluateHandle(expression string, arg interface{}, options ...LocatorEvaluateHandleOptions) (JSHandle, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
h, err := l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
return handle.EvaluateHandle(expression, arg)
|
|
}, option)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return h.(JSHandle), nil
|
|
}
|
|
|
|
func (l *locatorImpl) Fill(value string, options ...LocatorFillOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameFillOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Fill(l.selector, value, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Filter(options ...LocatorFilterOptions) Locator {
|
|
if len(options) == 1 {
|
|
return newLocator(l.frame, l.selector, LocatorLocatorOptions(options[0]))
|
|
}
|
|
return newLocator(l.frame, l.selector)
|
|
}
|
|
|
|
func (l *locatorImpl) First() Locator {
|
|
return newLocator(l.frame, l.selector+" >> nth=0")
|
|
}
|
|
|
|
func (l *locatorImpl) Focus(options ...LocatorFocusOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameFocusOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Focus(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) FrameLocator(selector string) FrameLocator {
|
|
return newFrameLocator(l.frame, l.selector+" >> "+selector)
|
|
}
|
|
|
|
func (l *locatorImpl) GetAttribute(name string, options ...LocatorGetAttributeOptions) (string, error) {
|
|
if l.err != nil {
|
|
return "", l.err
|
|
}
|
|
opt := FrameGetAttributeOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return l.frame.GetAttribute(l.selector, name, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) GetByAltText(text interface{}, options ...LocatorGetByAltTextOptions) Locator {
|
|
exact := false
|
|
if len(options) == 1 {
|
|
if *options[0].Exact {
|
|
exact = true
|
|
}
|
|
}
|
|
return l.Locator(getByAltTextSelector(text, exact))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByLabel(text interface{}, options ...LocatorGetByLabelOptions) Locator {
|
|
exact := false
|
|
if len(options) == 1 {
|
|
if *options[0].Exact {
|
|
exact = true
|
|
}
|
|
}
|
|
return l.Locator(getByLabelSelector(text, exact))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByPlaceholder(text interface{}, options ...LocatorGetByPlaceholderOptions) Locator {
|
|
exact := false
|
|
if len(options) == 1 {
|
|
if *options[0].Exact {
|
|
exact = true
|
|
}
|
|
}
|
|
return l.Locator(getByPlaceholderSelector(text, exact))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByRole(role AriaRole, options ...LocatorGetByRoleOptions) Locator {
|
|
return l.Locator(getByRoleSelector(role, options...))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByTestId(testId interface{}) Locator {
|
|
return l.Locator(getByTestIdSelector(getTestIdAttributeName(), testId))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByText(text interface{}, options ...LocatorGetByTextOptions) Locator {
|
|
exact := false
|
|
if len(options) == 1 {
|
|
if *options[0].Exact {
|
|
exact = true
|
|
}
|
|
}
|
|
return l.Locator(getByTextSelector(text, exact))
|
|
}
|
|
|
|
func (l *locatorImpl) GetByTitle(text interface{}, options ...LocatorGetByTitleOptions) Locator {
|
|
exact := false
|
|
if len(options) == 1 {
|
|
if *options[0].Exact {
|
|
exact = true
|
|
}
|
|
}
|
|
return l.Locator(getByTitleSelector(text, exact))
|
|
}
|
|
|
|
func (l *locatorImpl) Highlight() error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
return l.frame.highlight(l.selector)
|
|
}
|
|
|
|
func (l *locatorImpl) Hover(options ...LocatorHoverOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameHoverOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Hover(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) InnerHTML(options ...LocatorInnerHTMLOptions) (string, error) {
|
|
if l.err != nil {
|
|
return "", l.err
|
|
}
|
|
opt := FrameInnerHTMLOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return l.frame.InnerHTML(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) InnerText(options ...LocatorInnerTextOptions) (string, error) {
|
|
if l.err != nil {
|
|
return "", l.err
|
|
}
|
|
opt := FrameInnerTextOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return l.frame.InnerText(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) InputValue(options ...LocatorInputValueOptions) (string, error) {
|
|
if l.err != nil {
|
|
return "", l.err
|
|
}
|
|
opt := FrameInputValueOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return l.frame.InputValue(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsChecked(options ...LocatorIsCheckedOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsCheckedOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsChecked(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsDisabled(options ...LocatorIsDisabledOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsDisabledOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsDisabled(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsEditable(options ...LocatorIsEditableOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsEditableOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsEditable(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsEnabled(options ...LocatorIsEnabledOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsEnabledOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsEnabled(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsHidden(options ...LocatorIsHiddenOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsHiddenOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsHidden(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) IsVisible(options ...LocatorIsVisibleOptions) (bool, error) {
|
|
if l.err != nil {
|
|
return false, l.err
|
|
}
|
|
opt := FrameIsVisibleOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return false, err
|
|
}
|
|
}
|
|
return l.frame.IsVisible(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Last() Locator {
|
|
return newLocator(l.frame, l.selector+" >> nth=-1")
|
|
}
|
|
|
|
func (l *locatorImpl) Locator(selectorOrLocator interface{}, options ...LocatorLocatorOptions) Locator {
|
|
selector, ok := selectorOrLocator.(string)
|
|
if ok {
|
|
return newLocator(l.frame, l.selector+" >> "+selector, options...)
|
|
}
|
|
locator, ok := selectorOrLocator.(*locatorImpl)
|
|
if ok {
|
|
if l.frame != locator.frame {
|
|
l.err = errors.Join(l.err, ErrLocatorNotSameFrame)
|
|
return l
|
|
}
|
|
return newLocator(l.frame,
|
|
l.selector+" >> internal:chain="+escapeText(locator.selector),
|
|
options...,
|
|
)
|
|
}
|
|
l.err = errors.Join(l.err, fmt.Errorf("invalid locator parameter: %v", selectorOrLocator))
|
|
return l
|
|
}
|
|
|
|
func (l *locatorImpl) Nth(index int) Locator {
|
|
return newLocator(l.frame, l.selector+" >> nth="+strconv.Itoa(index))
|
|
}
|
|
|
|
func (l *locatorImpl) Page() (Page, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
return l.frame.Page(), nil
|
|
}
|
|
|
|
func (l *locatorImpl) Press(key string, options ...LocatorPressOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FramePressOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Press(l.selector, key, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) PressSequentially(text string, options ...LocatorPressSequentiallyOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
var option LocatorTypeOptions
|
|
if len(options) == 1 {
|
|
option = LocatorTypeOptions(options[0])
|
|
}
|
|
return l.Type(text, option)
|
|
}
|
|
|
|
func (l *locatorImpl) Screenshot(options ...LocatorScreenshotOptions) ([]byte, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
result, err := l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
var screenshotOption ElementHandleScreenshotOptions
|
|
if len(options) == 1 {
|
|
screenshotOption = ElementHandleScreenshotOptions(options[0])
|
|
}
|
|
return handle.Screenshot(screenshotOption)
|
|
}, option)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result.([]byte), nil
|
|
}
|
|
|
|
func (l *locatorImpl) ScrollIntoViewIfNeeded(options ...LocatorScrollIntoViewIfNeededOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
_, err := l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
var opt ElementHandleScrollIntoViewIfNeededOptions
|
|
if len(options) == 1 {
|
|
opt.Timeout = options[0].Timeout
|
|
}
|
|
return nil, handle.ScrollIntoViewIfNeeded(opt)
|
|
}, option)
|
|
|
|
return err
|
|
}
|
|
|
|
func (l *locatorImpl) SelectOption(values SelectOptionValues, options ...LocatorSelectOptionOptions) ([]string, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
opt := FrameSelectOptionOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return l.frame.SelectOption(l.selector, values, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) SelectText(options ...LocatorSelectTextOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
var option FrameWaitForSelectorOptions
|
|
if len(options) == 1 {
|
|
option.Timeout = options[0].Timeout
|
|
}
|
|
|
|
_, err := l.withElement(func(handle ElementHandle) (interface{}, error) {
|
|
var opt ElementHandleSelectTextOptions
|
|
if len(options) == 1 {
|
|
opt = ElementHandleSelectTextOptions(options[0])
|
|
}
|
|
return nil, handle.SelectText(opt)
|
|
}, option)
|
|
|
|
return err
|
|
}
|
|
|
|
func (l *locatorImpl) SetChecked(checked bool, options ...LocatorSetCheckedOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameSetCheckedOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.SetChecked(l.selector, checked, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) SetInputFiles(files interface{}, options ...LocatorSetInputFilesOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameSetInputFilesOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.SetInputFiles(l.selector, files, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Tap(options ...LocatorTapOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameTapOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Tap(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) TextContent(options ...LocatorTextContentOptions) (string, error) {
|
|
if l.err != nil {
|
|
return "", l.err
|
|
}
|
|
opt := FrameTextContentOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
return l.frame.TextContent(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Type(text string, options ...LocatorTypeOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameTypeOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Type(l.selector, text, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) Uncheck(options ...LocatorUncheckOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameUncheckOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return l.frame.Uncheck(l.selector, opt)
|
|
}
|
|
|
|
func (l *locatorImpl) WaitFor(options ...LocatorWaitForOptions) error {
|
|
if l.err != nil {
|
|
return l.err
|
|
}
|
|
opt := FrameWaitForSelectorOptions{
|
|
Strict: Bool(true),
|
|
}
|
|
if len(options) == 1 {
|
|
if err := assignStructFields(&opt, options[0], false); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
_, err := l.frame.WaitForSelector(l.selector, opt)
|
|
return err
|
|
}
|
|
|
|
func (l *locatorImpl) withElement(
|
|
callback func(handle ElementHandle) (interface{}, error),
|
|
options ...FrameWaitForSelectorOptions,
|
|
) (interface{}, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
handle, err := l.frame.WaitForSelector(l.selector, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
result, err := callback(handle)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (l *locatorImpl) expect(expression string, options frameExpectOptions) (*frameExpectResult, error) {
|
|
if l.err != nil {
|
|
return nil, l.err
|
|
}
|
|
overrides := map[string]interface{}{
|
|
"selector": l.selector,
|
|
"expression": expression,
|
|
}
|
|
if options.ExpectedValue != nil {
|
|
overrides["expectedValue"] = serializeArgument(options.ExpectedValue)
|
|
options.ExpectedValue = nil
|
|
}
|
|
result, err := l.frame.channel.SendReturnAsDict("expect", options, overrides)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var (
|
|
received interface{}
|
|
matches bool
|
|
log []string
|
|
)
|
|
|
|
if v, ok := result["received"]; ok {
|
|
received = parseResult(v)
|
|
}
|
|
if v, ok := result["matches"]; ok {
|
|
matches = v.(bool)
|
|
}
|
|
if v, ok := result["log"]; ok {
|
|
for _, l := range v.([]interface{}) {
|
|
log = append(log, l.(string))
|
|
}
|
|
}
|
|
return &frameExpectResult{Received: received, Matches: matches, Log: log}, nil
|
|
}
|