Skip to content

Commit

Permalink
add Element.Hover
Browse files Browse the repository at this point in the history
resolve #151
  • Loading branch information
ysmood committed Jul 28, 2020
1 parent e15678c commit b7625ec
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 20 deletions.
36 changes: 17 additions & 19 deletions element.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func (el *Element) ScrollIntoViewE() error {
return proto.DOMScrollIntoViewIfNeeded{ObjectID: el.ObjectID}.Call(el)
}

// ClickE will press then release the button just like a human.
func (el *Element) ClickE(button proto.InputMouseButton) error {
// HoverE the mouse over the center of the element.
func (el *Element) HoverE() error {
err := el.WaitVisibleE()
if err != nil {
return err
Expand All @@ -57,12 +57,22 @@ func (el *Element) ClickE(button proto.InputMouseButton) error {
return err
}

box, err := el.boxCenter()
box, err := el.BoxE()
if err != nil {
return err
}

err = el.page.Mouse.MoveE(box.X, box.Y, 1)
err = el.page.Mouse.MoveE(box.CenterX(), box.CenterY(), 1)
if err != nil {
return err
}

return nil
}

// ClickE will press then release the button just like a human.
func (el *Element) ClickE(button proto.InputMouseButton) error {
err := el.HoverE()
if err != nil {
return err
}
Expand All @@ -82,7 +92,7 @@ func (el *Element) ClickE(button proto.InputMouseButton) error {

// ClickableE checks if the element is behind another element, such as when invisible or covered by a modal.
func (el *Element) ClickableE() (bool, error) {
box, err := el.boxCenter()
box, err := el.BoxE()
if err != nil {
return false, err
}
Expand All @@ -93,8 +103,8 @@ func (el *Element) ClickableE() (bool, error) {
}

elAtPoint, err := el.page.ElementFromPointE(
int64(box.X)+scroll.Value.Get("x").Int(),
int64(box.Y)+scroll.Value.Get("y").Int(),
int64(box.CenterX())+scroll.Value.Get("x").Int(),
int64(box.CenterY())+scroll.Value.Get("y").Int(),
)
if err != nil {
return false, err
Expand All @@ -112,18 +122,6 @@ func (el *Element) ClickableE() (bool, error) {
return false, nil
}

func (el *Element) boxCenter() (*proto.DOMRect, error) {
box, err := el.BoxE()
if err != nil {
return nil, err
}

x := box.X + box.Width/2
y := box.Y + box.Height/2

return &proto.DOMRect{X: x, Y: y}, nil
}

// BoxE returns the size of an element and its position relative to the main frame.
func (el *Element) BoxE() (*proto.DOMRect, error) {
res, err := proto.DOMGetBoxModel{ObjectID: el.ObjectID}.Call(el)
Expand Down
8 changes: 8 additions & 0 deletions element_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ func (s *S) TestNotClickable() {
})
}

func (s *S) TestHover() {
p := s.page.Navigate(srcFile("fixtures/click.html"))
el := p.Element("button")
el.Eval(`this.onmouseenter = () => this.dataset['a'] = 1`)
el.Hover()
s.Equal("1", el.Eval(`this.dataset['a']`).String())
}

func (s *S) TestElementContext() {
p := s.page.Navigate(srcFile("fixtures/click.html"))
el := p.Element("button").Timeout(time.Minute).CancelTimeout()
Expand Down
10 changes: 10 additions & 0 deletions lib/proto/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,13 @@ func (box *DOMBoxModel) Rect() *DOMRect {
Height: box.Content[7] - box.Content[1],
}
}

// CenterX of the rectangle
func (rect *DOMRect) CenterX() float64 {
return rect.X + rect.Width/2
}

// CenterY of the rectangle
func (rect *DOMRect) CenterY() float64 {
return rect.Y + rect.Height/2
}
5 changes: 4 additions & 1 deletion lib/proto/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ func TestRect(t *testing.T) {
b := &proto.DOMBoxModel{Content: proto.DOMQuad{
336, 382, 361, 382, 361, 421, 336, 412,
}}
rect := b.Rect()
assert.Equal(t, proto.DOMRect{X: 336, Y: 382, Width: 25, Height: 30}, *rect)

assert.Equal(t, proto.DOMRect{X: 336, Y: 382, Width: 25, Height: 30}, *b.Rect())
assert.Equal(t, 348.5, rect.CenterX())
assert.Equal(t, 397.0, rect.CenterY())
}
1 change: 1 addition & 0 deletions page.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ func (p *Page) initJS(force bool) error {
return nil
}

// We use this function to make sure every frame(page, iframe) will only have one IsolatedWorld.
func (p *Page) getExecutionID(force bool) (proto.RuntimeExecutionContextID, error) {
if !p.IsIframe() {
return 0, nil
Expand Down
6 changes: 6 additions & 0 deletions sugar.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,12 @@ func (el *Element) ScrollIntoView() *Element {
return el
}

// Hover the mouse over the center of the element.
func (el *Element) Hover() *Element {
kit.E(el.HoverE())
return el
}

// Click the element
func (el *Element) Click() *Element {
kit.E(el.ClickE(proto.InputMouseButtonLeft))
Expand Down

0 comments on commit b7625ec

Please sign in to comment.