Changes to ElementVisible/ElementNotVisible

Changed implementation of ElementVisible/ElementNotVisible to use a
javascript evaluation instead of the previous, cumbersome
implementation. As this may not work correctly in all scenarios, the old
versions will remain as ElementVisibleOld and ElementNotVisibleOld until
the new implementations can be vetted for correctness/performance.
This commit is contained in:
Kenneth Shaw 2017-02-08 15:40:22 +07:00
parent b57afce7e7
commit 5bef7dce13
2 changed files with 46 additions and 19 deletions

18
nav.go
View File

@ -3,11 +3,9 @@ package chromedp
import (
"context"
"errors"
"fmt"
"github.com/knq/chromedp/cdp"
"github.com/knq/chromedp/cdp/page"
rundom "github.com/knq/chromedp/cdp/runtime"
)
// Navigate navigates the current frame.
@ -125,20 +123,6 @@ func Location(urlstr *string) Action {
if urlstr == nil {
panic("urlstr cannot be nil")
}
return ActionFunc(func(ctxt context.Context, h cdp.FrameHandler) error {
res, exp, err := rundom.Evaluate(`location.toString()`).Do(ctxt, h)
if err != nil {
return err
}
if exp != nil {
return exp
}
if res.Type != rundom.TypeString || len(res.Value) < 2 {
return fmt.Errorf("expected string of at least length 2, got %s length %d", res.Subtype, len(res.Value))
}
*urlstr = string(res.Value[1 : len(res.Value)-1])
return nil
})
return EvaluateAsDevTools(`location.toString()`, urlstr)
}

47
sel.go
View File

@ -300,6 +300,38 @@ func ElementReady(s *Selector) {
// ElementVisible is a query option to wait until the element is visible.
func ElementVisible(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h cdp.FrameHandler, n *cdp.Node) error {
var res bool
err := EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctxt, h)
if err != nil {
return err
}
if !res {
return ErrNotVisible
}
return nil
}))(s)
}
// ElementNotVisible is a query option to wait until the element is not visible.
func ElementNotVisible(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h cdp.FrameHandler, n *cdp.Node) error {
var res bool
err := EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctxt, h)
if err != nil {
return err
}
if res {
return ErrVisible
}
return nil
}))(s)
}
// ElementVisibleOld is a query option to wait until the element is visible.
//
// This is the old, complicated, implementation (deprecated).
func ElementVisibleOld(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h cdp.FrameHandler, n *cdp.Node) error {
var err error
@ -344,8 +376,11 @@ func ElementVisible(s *Selector) {
}))(s)
}
// ElementNotVisible is a query option to wait until the element is visible.
func ElementNotVisible(s *Selector) {
// ElementNotVisibleOld is a query option to wait until the element is not
// visible.
//
// This is the old, complicated, implementation (deprecated).
func ElementNotVisibleOld(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h cdp.FrameHandler, n *cdp.Node) error {
var err error
@ -463,3 +498,11 @@ func WaitEnabled(sel interface{}, opts ...QueryOption) Action {
func WaitSelected(sel interface{}, opts ...QueryOption) Action {
return Query(sel, append(opts, ElementSelected)...)
}
const (
// visibleJS is a javascript snippet that returns true or false depending
// on if the specified node's offsetParent is not null.
visibleJS = `(function(a) {
return a[0].offsetParent !== null
})($x('%s'))`
)