...

Source file src/github.com/playwright-community/playwright-go/frame.go

Documentation: github.com/playwright-community/playwright-go

     1  package playwright
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  type frameImpl struct {
    11  	channelOwner
    12  	sync.RWMutex
    13  	detached    bool
    14  	page        *pageImpl
    15  	name        string
    16  	url         string
    17  	parentFrame Frame
    18  	childFrames []Frame
    19  	loadStates  *safeStringSet
    20  }
    21  
    22  func newFrame(parent *channelOwner, objectType string, guid string, initializer map[string]interface{}) *frameImpl {
    23  	var loadStates *safeStringSet
    24  	if ls, ok := initializer["loadStates"].([]string); ok {
    25  		loadStates = newSafeStringSet(ls)
    26  	} else {
    27  		loadStates = newSafeStringSet([]string{})
    28  	}
    29  	bt := &frameImpl{
    30  		name:        initializer["name"].(string),
    31  		url:         initializer["url"].(string),
    32  		loadStates:  loadStates,
    33  		childFrames: make([]Frame, 0),
    34  	}
    35  	bt.createChannelOwner(bt, parent, objectType, guid, initializer)
    36  
    37  	channelOwner := fromNullableChannel(initializer["parentFrame"])
    38  	if channelOwner != nil {
    39  		bt.parentFrame = channelOwner.(*frameImpl)
    40  		bt.parentFrame.(*frameImpl).childFrames = append(bt.parentFrame.(*frameImpl).childFrames, bt)
    41  	}
    42  
    43  	bt.channel.On("navigated", bt.onFrameNavigated)
    44  	bt.channel.On("loadstate", bt.onLoadState)
    45  	return bt
    46  }
    47  
    48  func (f *frameImpl) URL() string {
    49  	f.RLock()
    50  	defer f.RUnlock()
    51  	return f.url
    52  }
    53  
    54  func (f *frameImpl) Name() string {
    55  	f.RLock()
    56  	defer f.RUnlock()
    57  	return f.name
    58  }
    59  
    60  func (f *frameImpl) SetContent(content string, options ...PageSetContentOptions) error {
    61  	_, err := f.channel.Send("setContent", map[string]interface{}{
    62  		"html": content,
    63  	}, options)
    64  	return err
    65  }
    66  
    67  func (f *frameImpl) Content() (string, error) {
    68  	content, err := f.channel.Send("content")
    69  	return content.(string), err
    70  }
    71  
    72  func (f *frameImpl) Goto(url string, options ...PageGotoOptions) (Response, error) {
    73  	channel, err := f.channel.Send("goto", map[string]interface{}{
    74  		"url": url,
    75  	}, options)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  	channelOwner := fromNullableChannel(channel)
    80  	if channelOwner == nil {
    81  		return nil, nil
    82  	}
    83  	return channelOwner.(*responseImpl), nil
    84  }
    85  
    86  func (f *frameImpl) AddScriptTag(options PageAddScriptTagOptions) (ElementHandle, error) {
    87  	if options.Path != nil {
    88  		file, err := ioutil.ReadFile(*options.Path)
    89  		if err != nil {
    90  			return nil, err
    91  		}
    92  		options.Content = String(string(file))
    93  		options.Path = nil
    94  	}
    95  	channel, err := f.channel.Send("addScriptTag", options)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	return fromChannel(channel).(*elementHandleImpl), nil
   100  }
   101  
   102  func (f *frameImpl) AddStyleTag(options PageAddStyleTagOptions) (ElementHandle, error) {
   103  	if options.Path != nil {
   104  		file, err := ioutil.ReadFile(*options.Path)
   105  		if err != nil {
   106  			return nil, err
   107  		}
   108  		options.Content = String(string(file))
   109  		options.Path = nil
   110  	}
   111  	channel, err := f.channel.Send("addStyleTag", options)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	return fromChannel(channel).(*elementHandleImpl), nil
   116  }
   117  
   118  func (f *frameImpl) Page() Page {
   119  	return f.page
   120  }
   121  
   122  func (f *frameImpl) WaitForLoadState(given ...string) {
   123  	state := "load"
   124  	if len(given) == 1 {
   125  		state = given[0]
   126  	}
   127  	if f.loadStates.Has(state) {
   128  		return
   129  	}
   130  	succeed := make(chan bool, 1)
   131  	f.Once("loadstate", func(ev ...interface{}) {
   132  		gotState := ev[0].(string)
   133  		if gotState == state {
   134  			succeed <- true
   135  		}
   136  	})
   137  	<-succeed
   138  }
   139  
   140  func (f *frameImpl) WaitForURL(url string, options ...FrameWaitForURLOptions) error {
   141  	if len(options) > 0 {
   142  		if _, err := f.WaitForNavigation(PageWaitForNavigationOptions{
   143  			URL:       url,
   144  			Timeout:   options[0].Timeout,
   145  			WaitUntil: options[0].WaitUntil,
   146  		}); err != nil {
   147  			return err
   148  		}
   149  	}
   150  	return nil
   151  }
   152  
   153  func (f *frameImpl) WaitForEvent(event string, predicate ...interface{}) interface{} {
   154  	return <-waitForEvent(f, event, predicate...)
   155  }
   156  
   157  func (f *frameImpl) WaitForNavigation(options ...PageWaitForNavigationOptions) (Response, error) {
   158  	option := PageWaitForNavigationOptions{}
   159  	if len(options) == 1 {
   160  		option = options[0]
   161  	}
   162  	if option.WaitUntil == nil {
   163  		option.WaitUntil = WaitUntilStateLoad
   164  	}
   165  	if option.Timeout == nil {
   166  		option.Timeout = Float(f.page.timeoutSettings.NavigationTimeout())
   167  	}
   168  	deadline := time.After(time.Duration(*option.Timeout) * time.Millisecond)
   169  	var matcher *urlMatcher
   170  	if option.URL != nil {
   171  		matcher = newURLMatcher(option.URL)
   172  	}
   173  	predicate := func(events ...interface{}) bool {
   174  		ev := events[0].(map[string]interface{})
   175  		if ev["error"] != nil {
   176  			print("error")
   177  		}
   178  		return matcher == nil || matcher.Matches(ev["url"].(string))
   179  	}
   180  	select {
   181  	case <-deadline:
   182  		return nil, fmt.Errorf("Timeout %.2fms exceeded.", *option.Timeout)
   183  	case eventData := <-waitForEvent(f, "navigated", predicate):
   184  		event := eventData.(map[string]interface{})
   185  		if event["newDocument"] != nil && event["newDocument"].(map[string]interface{})["request"] != nil {
   186  			request := fromChannel(event["newDocument"].(map[string]interface{})["request"]).(*requestImpl)
   187  			return request.Response()
   188  		}
   189  	}
   190  	return nil, nil
   191  }
   192  
   193  func (f *frameImpl) onFrameNavigated(ev map[string]interface{}) {
   194  	f.Lock()
   195  	f.url = ev["url"].(string)
   196  	f.name = ev["name"].(string)
   197  	f.Unlock()
   198  	f.Emit("navigated", ev)
   199  	if f.page != nil {
   200  		f.page.Emit("framenavigated", f)
   201  	}
   202  }
   203  
   204  func (f *frameImpl) onLoadState(ev map[string]interface{}) {
   205  	if ev["add"] != nil {
   206  		add := ev["add"].(string)
   207  		f.loadStates.Add(add)
   208  		f.Emit("loadstate", add)
   209  	} else if ev["remove"] != nil {
   210  		remove := ev["remove"].(string)
   211  		f.loadStates.Remove(remove)
   212  	}
   213  }
   214  
   215  func (f *frameImpl) QuerySelector(selector string) (ElementHandle, error) {
   216  	channel, err := f.channel.Send("querySelector", map[string]interface{}{
   217  		"selector": selector,
   218  	})
   219  	if err != nil {
   220  		return nil, err
   221  	}
   222  	if channel == nil {
   223  		return nil, nil
   224  	}
   225  	return fromChannel(channel).(*elementHandleImpl), nil
   226  }
   227  
   228  func (f *frameImpl) QuerySelectorAll(selector string) ([]ElementHandle, error) {
   229  	channels, err := f.channel.Send("querySelectorAll", map[string]interface{}{
   230  		"selector": selector,
   231  	})
   232  	if err != nil {
   233  		return nil, err
   234  	}
   235  	elements := make([]ElementHandle, 0)
   236  	for _, channel := range channels.([]interface{}) {
   237  		elements = append(elements, fromChannel(channel).(*elementHandleImpl))
   238  	}
   239  	return elements, nil
   240  }
   241  
   242  func (f *frameImpl) Evaluate(expression string, options ...interface{}) (interface{}, error) {
   243  	var arg interface{}
   244  	forceExpression := false
   245  	if !isFunctionBody(expression) {
   246  		forceExpression = true
   247  	}
   248  	if len(options) == 1 {
   249  		arg = options[0]
   250  	} else if len(options) == 2 {
   251  		arg = options[0]
   252  		forceExpression = options[1].(bool)
   253  	}
   254  	result, err := f.channel.Send("evaluateExpression", map[string]interface{}{
   255  		"expression": expression,
   256  		"isFunction": !forceExpression,
   257  		"arg":        serializeArgument(arg),
   258  	})
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  	return parseResult(result), nil
   263  }
   264  
   265  func (f *frameImpl) EvalOnSelector(selector string, expression string, options ...interface{}) (interface{}, error) {
   266  	var arg interface{}
   267  	forceExpression := false
   268  	if !isFunctionBody(expression) {
   269  		forceExpression = true
   270  	}
   271  	if len(options) == 1 {
   272  		arg = options[0]
   273  	} else if len(options) == 2 {
   274  		arg = options[0]
   275  		forceExpression = options[1].(bool)
   276  	}
   277  	result, err := f.channel.Send("evalOnSelector", map[string]interface{}{
   278  		"selector":   selector,
   279  		"expression": expression,
   280  		"isFunction": !forceExpression,
   281  		"arg":        serializeArgument(arg),
   282  	})
   283  	if err != nil {
   284  		return nil, err
   285  	}
   286  	return parseResult(result), nil
   287  }
   288  
   289  func (f *frameImpl) EvalOnSelectorAll(selector string, expression string, options ...interface{}) (interface{}, error) {
   290  	var arg interface{}
   291  	forceExpression := false
   292  	if !isFunctionBody(expression) {
   293  		forceExpression = true
   294  	}
   295  	if len(options) == 1 {
   296  		arg = options[0]
   297  	} else if len(options) == 2 {
   298  		arg = options[0]
   299  		forceExpression = options[1].(bool)
   300  	}
   301  	result, err := f.channel.Send("evalOnSelectorAll", map[string]interface{}{
   302  		"selector":   selector,
   303  		"expression": expression,
   304  		"isFunction": !forceExpression,
   305  		"arg":        serializeArgument(arg),
   306  	})
   307  	if err != nil {
   308  		return nil, err
   309  	}
   310  	return parseResult(result), nil
   311  }
   312  
   313  func (f *frameImpl) EvaluateHandle(expression string, options ...interface{}) (JSHandle, error) {
   314  	var arg interface{}
   315  	forceExpression := false
   316  	if !isFunctionBody(expression) {
   317  		forceExpression = true
   318  	}
   319  	if len(options) == 1 {
   320  		arg = options[0]
   321  	} else if len(options) == 2 {
   322  		arg = options[0]
   323  		forceExpression = options[1].(bool)
   324  	}
   325  	result, err := f.channel.Send("evaluateExpressionHandle", map[string]interface{}{
   326  		"expression": expression,
   327  		"isFunction": !forceExpression,
   328  		"arg":        serializeArgument(arg),
   329  	})
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  	channelOwner := fromChannel(result)
   334  	if channelOwner == nil {
   335  		return nil, nil
   336  	}
   337  	return channelOwner.(JSHandle), nil
   338  }
   339  
   340  func (f *frameImpl) Click(selector string, options ...PageClickOptions) error {
   341  	_, err := f.channel.Send("click", map[string]interface{}{
   342  		"selector": selector,
   343  	}, options)
   344  	return err
   345  }
   346  
   347  func (f *frameImpl) WaitForSelector(selector string, options ...PageWaitForSelectorOptions) (ElementHandle, error) {
   348  	channel, err := f.channel.Send("waitForSelector", map[string]interface{}{
   349  		"selector": selector,
   350  	}, options)
   351  	if err != nil {
   352  		return nil, err
   353  	}
   354  	channelOwner := fromNullableChannel(channel)
   355  	if channelOwner == nil {
   356  		return nil, nil
   357  	}
   358  	return channelOwner.(*elementHandleImpl), nil
   359  }
   360  
   361  func (f *frameImpl) DispatchEvent(selector, typ string, eventInit interface{}, options ...PageDispatchEventOptions) error {
   362  	_, err := f.channel.Send("dispatchEvent", map[string]interface{}{
   363  		"selector":  selector,
   364  		"type":      typ,
   365  		"eventInit": serializeArgument(eventInit),
   366  	})
   367  	return err
   368  }
   369  
   370  func (f *frameImpl) InnerText(selector string, options ...PageInnerTextOptions) (string, error) {
   371  	innerText, err := f.channel.Send("innerText", map[string]interface{}{
   372  		"selector": selector,
   373  	}, options)
   374  	if err != nil {
   375  		return "", err
   376  	}
   377  	return innerText.(string), nil
   378  }
   379  
   380  func (f *frameImpl) InnerHTML(selector string, options ...PageInnerHTMLOptions) (string, error) {
   381  	innerHTML, err := f.channel.Send("innerHTML", map[string]interface{}{
   382  		"selector": selector,
   383  	}, options)
   384  	if err != nil {
   385  		return "", err
   386  	}
   387  	return innerHTML.(string), nil
   388  }
   389  
   390  func (f *frameImpl) GetAttribute(selector string, name string, options ...PageGetAttributeOptions) (string, error) {
   391  	attribute, err := f.channel.Send("getAttribute", map[string]interface{}{
   392  		"selector": selector,
   393  		"name":     name,
   394  	}, options)
   395  	if err != nil {
   396  		return "", err
   397  	}
   398  	if attribute == nil {
   399  		return "", nil
   400  	}
   401  	return attribute.(string), nil
   402  }
   403  
   404  func (f *frameImpl) Hover(selector string, options ...PageHoverOptions) error {
   405  	_, err := f.channel.Send("hover", map[string]interface{}{
   406  		"selector": selector,
   407  	}, options)
   408  	return err
   409  }
   410  
   411  func (f *frameImpl) SetInputFiles(selector string, files []InputFile, options ...FrameSetInputFilesOptions) error {
   412  	_, err := f.channel.Send("setInputFiles", map[string]interface{}{
   413  		"selector": selector,
   414  		"files":    normalizeFilePayloads(files),
   415  	}, options)
   416  	return err
   417  }
   418  
   419  func (f *frameImpl) Type(selector, text string, options ...PageTypeOptions) error {
   420  	_, err := f.channel.Send("type", map[string]interface{}{
   421  		"selector": selector,
   422  		"text":     text,
   423  	}, options)
   424  	return err
   425  }
   426  
   427  func (f *frameImpl) Press(selector, key string, options ...PagePressOptions) error {
   428  	_, err := f.channel.Send("press", map[string]interface{}{
   429  		"selector": selector,
   430  		"key":      key,
   431  	}, options)
   432  	return err
   433  }
   434  
   435  func (f *frameImpl) Check(selector string, options ...FrameCheckOptions) error {
   436  	_, err := f.channel.Send("check", map[string]interface{}{
   437  		"selector": selector,
   438  	}, options)
   439  	return err
   440  }
   441  
   442  func (f *frameImpl) Uncheck(selector string, options ...FrameUncheckOptions) error {
   443  	_, err := f.channel.Send("uncheck", map[string]interface{}{
   444  		"selector": selector,
   445  	}, options)
   446  	return err
   447  }
   448  
   449  func (f *frameImpl) WaitForTimeout(timeout float64) {
   450  	time.Sleep(time.Duration(timeout) * time.Millisecond)
   451  }
   452  
   453  func (f *frameImpl) WaitForFunction(expression string, arg interface{}, options ...FrameWaitForFunctionOptions) (JSHandle, error) {
   454  	var option FrameWaitForFunctionOptions
   455  	if len(options) == 1 {
   456  		option = options[0]
   457  	}
   458  	forceExpression := false
   459  	if !isFunctionBody(expression) {
   460  		forceExpression = true
   461  	}
   462  	result, err := f.channel.Send("waitForFunction", map[string]interface{}{
   463  		"expression": expression,
   464  		"isFunction": !forceExpression,
   465  		"arg":        serializeArgument(arg),
   466  		"timeout":    option.Timeout,
   467  		"polling":    option.Polling,
   468  	})
   469  	if err != nil {
   470  		return nil, err
   471  	}
   472  	handle := fromChannel(result)
   473  	if handle == nil {
   474  		return nil, nil
   475  	}
   476  	return handle.(*jsHandleImpl), nil
   477  }
   478  
   479  func (f *frameImpl) Title() (string, error) {
   480  	title, err := f.channel.Send("title")
   481  	if err != nil {
   482  		return "", err
   483  	}
   484  	return title.(string), err
   485  }
   486  
   487  func (f *frameImpl) ChildFrames() []Frame {
   488  	return f.childFrames
   489  }
   490  
   491  func (f *frameImpl) Dblclick(selector string, options ...FrameDblclickOptions) error {
   492  	_, err := f.channel.Send("dblclick", map[string]interface{}{
   493  		"selector": selector,
   494  	}, options)
   495  	return err
   496  }
   497  
   498  func (f *frameImpl) Fill(selector string, value string, options ...FrameFillOptions) error {
   499  	_, err := f.channel.Send("fill", map[string]interface{}{
   500  		"selector": selector,
   501  		"value":    value,
   502  	}, options)
   503  	return err
   504  }
   505  
   506  func (f *frameImpl) Focus(selector string, options ...FrameFocusOptions) error {
   507  	_, err := f.channel.Send("focus", map[string]interface{}{
   508  		"selector": selector,
   509  	}, options)
   510  	return err
   511  }
   512  
   513  func (f *frameImpl) FrameElement() (ElementHandle, error) {
   514  	elementHandle, err := f.channel.Send("frameElement")
   515  	if err != nil {
   516  		return nil, err
   517  	}
   518  	return elementHandle.(*elementHandleImpl), nil
   519  }
   520  
   521  func (f *frameImpl) IsDetached() bool {
   522  	return f.detached
   523  }
   524  
   525  func (f *frameImpl) ParentFrame() Frame {
   526  	return f.parentFrame
   527  }
   528  
   529  func (f *frameImpl) TextContent(selector string, options ...FrameTextContentOptions) (string, error) {
   530  	textContent, err := f.channel.Send("textContent", map[string]interface{}{
   531  		"selector": selector,
   532  	}, options)
   533  	if err != nil {
   534  		return "", err
   535  	}
   536  	return textContent.(string), nil
   537  }
   538  
   539  func (f *frameImpl) Tap(selector string, options ...FrameTapOptions) error {
   540  	_, err := f.channel.Send("tap", map[string]interface{}{
   541  		"selector": selector,
   542  	}, options)
   543  	return err
   544  }
   545  
   546  func (f *frameImpl) SelectOption(selector string, values SelectOptionValues, options ...FrameSelectOptionOptions) ([]string, error) {
   547  	opts := convertSelectOptionSet(values)
   548  
   549  	m := make(map[string]interface{})
   550  	m["selector"] = selector
   551  	for k, v := range opts {
   552  		m[k] = v
   553  	}
   554  	selected, err := f.channel.Send("selectOption", m, options)
   555  	if err != nil {
   556  		return nil, err
   557  	}
   558  
   559  	return transformToStringList(selected), nil
   560  }
   561  
   562  func (f *frameImpl) IsChecked(selector string, options ...FrameIsCheckedOptions) (bool, error) {
   563  	checked, err := f.channel.Send("isChecked", map[string]interface{}{
   564  		"selector": selector,
   565  	}, options)
   566  	if err != nil {
   567  		return false, err
   568  	}
   569  	return checked.(bool), nil
   570  }
   571  
   572  func (f *frameImpl) IsDisabled(selector string, options ...FrameIsDisabledOptions) (bool, error) {
   573  	disabled, err := f.channel.Send("isDisabled", map[string]interface{}{
   574  		"selector": selector,
   575  	}, options)
   576  	if err != nil {
   577  		return false, err
   578  	}
   579  	return disabled.(bool), nil
   580  }
   581  
   582  func (f *frameImpl) IsEditable(selector string, options ...FrameIsEditableOptions) (bool, error) {
   583  	editable, err := f.channel.Send("isEditable", map[string]interface{}{
   584  		"selector": selector,
   585  	}, options)
   586  	if err != nil {
   587  		return false, err
   588  	}
   589  	return editable.(bool), nil
   590  }
   591  
   592  func (f *frameImpl) IsEnabled(selector string, options ...FrameIsEnabledOptions) (bool, error) {
   593  	enabled, err := f.channel.Send("isEnabled", map[string]interface{}{
   594  		"selector": selector,
   595  	}, options)
   596  	if err != nil {
   597  		return false, err
   598  	}
   599  	return enabled.(bool), nil
   600  }
   601  
   602  func (f *frameImpl) IsHidden(selector string, options ...FrameIsHiddenOptions) (bool, error) {
   603  	hidden, err := f.channel.Send("isHidden", map[string]interface{}{
   604  		"selector": selector,
   605  	}, options)
   606  	if err != nil {
   607  		return false, err
   608  	}
   609  	return hidden.(bool), nil
   610  }
   611  
   612  func (f *frameImpl) IsVisible(selector string, options ...FrameIsVisibleOptions) (bool, error) {
   613  	visible, err := f.channel.Send("isVisible", map[string]interface{}{
   614  		"selector": selector,
   615  	}, options)
   616  	if err != nil {
   617  		return false, err
   618  	}
   619  	return visible.(bool), nil
   620  }
   621  
   622  func (f *frameImpl) InputValue(selector string, options ...FrameInputValueOptions) (string, error) {
   623  
   624  	value, err := f.channel.Send("inputValue", map[string]interface{}{
   625  		"selector": selector,
   626  	}, options)
   627  	return value.(string), err
   628  }
   629  
   630  func (f *frameImpl) DragAndDrop(source, target string, options ...FrameDragAndDropOptions) error {
   631  	_, err := f.channel.Send("dragAndDrop", map[string]interface{}{
   632  		"source": source,
   633  		"target": target,
   634  	}, options)
   635  	return err
   636  }
   637  
   638  func (f *frameImpl) SetChecked(selector string, checked bool, options ...FrameSetCheckedOptions) error {
   639  	if checked {
   640  		_, err := f.channel.Send("check", map[string]interface{}{
   641  			"selector": selector,
   642  		}, options)
   643  		return err
   644  	} else {
   645  		_, err := f.channel.Send("uncheck", map[string]interface{}{
   646  			"selector": selector,
   647  		}, options)
   648  		return err
   649  	}
   650  }
   651  
   652  func (f *frameImpl) Locator(selector string, options ...FrameLocatorOptions) (Locator, error) {
   653  	var option LocatorLocatorOptions
   654  	if len(options) == 1 {
   655  		option = LocatorLocatorOptions(options[0])
   656  	}
   657  	return newLocator(f, selector, option)
   658  }
   659  
   660  func (f *frameImpl) highlight(selector string) error {
   661  	_, err := f.channel.Send("highlight", map[string]interface{}{
   662  		"selector": selector,
   663  	})
   664  	return err
   665  }
   666  
   667  func (f *frameImpl) queryCount(selector string) (int, error) {
   668  	response, err := f.channel.Send("queryCount", map[string]interface{}{
   669  		"selector": selector,
   670  	})
   671  	if err != nil {
   672  		return 0, err
   673  	}
   674  	return int(response.(float64)), nil
   675  }
   676  

View as plain text