1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-02 09:21:54 +02:00

Added click count (#377)

* Added click count
This commit is contained in:
Tim Voronov 2019-09-07 01:59:32 -04:00 committed by GitHub
parent 24370d8178
commit fcd0a21e75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 143 additions and 63 deletions

View File

@ -0,0 +1,16 @@
LET url = @dynamic + "/#/forms"
LET page = DOCUMENT(url, true)
WAIT_ELEMENT(page, "form")
LET input = ELEMENT(page, "#text_input")
INPUT(input, "Foo")
CLICK(page, "#text_input", 2)
INPUT(input, "Bar")
WAIT(100)
RETURN EXPECT("Bar", input.value)

View File

@ -0,0 +1,16 @@
LET url = @dynamic + "/#/forms"
LET page = DOCUMENT(url, true)
WAIT_ELEMENT(page, "form")
LET input = ELEMENT(page, "#text_input")
INPUT(input, "Foo")
CLICK(input, 2)
INPUT(input, "Bar")
WAIT(100)
RETURN EXPECT("Bar", input.value)

8
go.sum
View File

@ -21,6 +21,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/derekparker/trie v0.0.0-20190812220523-e66023ee76eb h1:HGjKnH6D1WD8sc9SfCkWkeD4OteWPPXD+ayJY+P1Bgk=
github.com/derekparker/trie v0.0.0-20190812220523-e66023ee76eb/go.mod h1:D6ICZm05D9VN1n/8iOtBxLpXtoGp6HDFUJ1RNVieOSE=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
@ -29,12 +30,16 @@ github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvK
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/labstack/echo/v4 v4.1.10 h1:/yhIpO50CBInUbE/nHJtGIyhBv0dJe2cDAYxc3V3uMo=
github.com/labstack/echo/v4 v4.1.10/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/mafredri/cdp v0.24.2 h1:Rzhj/EQw9opbiwUpNML7P+4Hvf0/nSYPaDbiCEpILOM=
github.com/mafredri/cdp v0.24.2/go.mod h1:hgdiA0yp1uqhSaDOHJWPgXpMbh+LAfUdD9vbN2AM8gE=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
@ -55,10 +60,13 @@ github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:s
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@ -317,14 +317,6 @@ func (doc *HTMLDocument) GetURL() values.String {
return values.NewString(doc.frames.Frame.URL)
}
func (doc *HTMLDocument) ClickBySelector(ctx context.Context, selector values.String) error {
return doc.element.ClickBySelector(ctx, selector)
}
func (doc *HTMLDocument) ClickBySelectorAll(ctx context.Context, selector values.String) error {
return doc.element.ClickBySelectorAll(ctx, selector)
}
func (doc *HTMLDocument) MoveMouseByXY(ctx context.Context, x, y values.Float) error {
return doc.input.MoveMouseByXY(ctx, float64(x), float64(y))
}

View File

@ -1026,16 +1026,16 @@ func (el *HTMLElement) WaitForStyle(ctx context.Context, name values.String, val
return err
}
func (el *HTMLElement) Click(ctx context.Context) error {
return el.input.Click(ctx, el.id.objectID)
func (el *HTMLElement) Click(ctx context.Context, count values.Int) error {
return el.input.Click(ctx, el.id.objectID, int(count))
}
func (el *HTMLElement) ClickBySelector(ctx context.Context, selector values.String) error {
return el.input.ClickBySelector(ctx, el.id.nodeID, selector.String())
func (el *HTMLElement) ClickBySelector(ctx context.Context, selector values.String, count values.Int) error {
return el.input.ClickBySelector(ctx, el.id.nodeID, selector.String(), int(count))
}
func (el *HTMLElement) ClickBySelectorAll(ctx context.Context, selector values.String) error {
return el.input.ClickBySelectorAll(ctx, el.id.nodeID, selector.String())
func (el *HTMLElement) ClickBySelectorAll(ctx context.Context, selector values.String, count values.Int) error {
return el.input.ClickBySelectorAll(ctx, el.id.nodeID, selector.String(), int(count))
}
func (el *HTMLElement) Input(ctx context.Context, value core.Value, delay values.Int) error {

View File

@ -149,7 +149,7 @@ func (m *Manager) MoveMouseByXY(ctx context.Context, x, y float64) error {
return m.mouse.Move(ctx, x, y)
}
func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID) error {
func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID, count int) error {
if err := m.ScrollIntoView(ctx, objectID); err != nil {
return err
}
@ -160,14 +160,16 @@ func (m *Manager) Click(ctx context.Context, objectID runtime.RemoteObjectID) er
return err
}
if err := m.mouse.Click(ctx, points.X, points.Y, drivers.DefaultInputDelay); err != nil {
delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond
if err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, count); err != nil {
return nil
}
return nil
}
func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
if err := m.ScrollIntoViewBySelector(ctx, selector); err != nil {
return err
}
@ -184,14 +186,16 @@ func (m *Manager) ClickBySelector(ctx context.Context, parentNodeID dom.NodeID,
return err
}
if err := m.mouse.Click(ctx, points.X, points.Y, drivers.DefaultInputDelay); err != nil {
delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond
if err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, count); err != nil {
return nil
}
return nil
}
func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeID, selector string) error {
func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeID, selector string, count int) error {
if err := m.ScrollIntoViewBySelector(ctx, selector); err != nil {
return err
}
@ -203,8 +207,7 @@ func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeI
}
for _, nodeID := range found.NodeIDs {
_, min := core.NumberBoundaries(drivers.DefaultInputDelay * 2)
beforeTypeDelay := time.Duration(min) * time.Millisecond
beforeTypeDelay := time.Duration(core.NumberLowerBoundary(drivers.DefaultMouseDelay*10)) * time.Millisecond
time.Sleep(beforeTypeDelay)
@ -214,7 +217,9 @@ func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeI
return err
}
if err := m.mouse.Click(ctx, points.X, points.Y, drivers.DefaultInputDelay); err != nil {
delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond
if err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, count); err != nil {
return nil
}
}
@ -345,7 +350,8 @@ func (m *Manager) ClearBySelector(ctx context.Context, parentNodeID dom.NodeID,
}
func (m *Manager) ClearByXY(ctx context.Context, points Quad) error {
err := m.mouse.ClickWithCount(ctx, points.X, points.Y, 3, 5)
delay := time.Duration(drivers.DefaultMouseDelay) * time.Millisecond
err := m.mouse.ClickWithCount(ctx, points.X, points.Y, delay, 2)
if err != nil {
return err

View File

@ -18,11 +18,11 @@ func NewMouse(client *cdp.Client) *Mouse {
return &Mouse{client, 0, 0}
}
func (m *Mouse) Click(ctx context.Context, x, y float64, delay int) error {
return m.ClickWithCount(ctx, x, y, 1, delay)
func (m *Mouse) Click(ctx context.Context, x, y float64, delay time.Duration) error {
return m.ClickWithCount(ctx, x, y, delay, 1)
}
func (m *Mouse) ClickWithCount(ctx context.Context, x, y float64, count, delay int) error {
func (m *Mouse) ClickWithCount(ctx context.Context, x, y float64, delay time.Duration, count int) error {
if err := m.Move(ctx, x, y); err != nil {
return err
}
@ -31,9 +31,7 @@ func (m *Mouse) ClickWithCount(ctx context.Context, x, y float64, count, delay i
return err
}
releaseDelay := randomDuration(delay)
time.Sleep(releaseDelay * time.Millisecond)
time.Sleep(randomDuration(int(delay)))
return m.UpWithCount(ctx, "left", count)
}
@ -46,8 +44,8 @@ func (m *Mouse) DownWithCount(ctx context.Context, button string, count int) err
return m.client.Input.DispatchMouseEvent(
ctx,
input.NewDispatchMouseEventArgs("mousePressed", m.x, m.y).
SetClickCount(count).
SetButton(button),
SetButton(button).
SetClickCount(count),
)
}
@ -59,8 +57,8 @@ func (m *Mouse) UpWithCount(ctx context.Context, button string, count int) error
return m.client.Input.DispatchMouseEvent(
ctx,
input.NewDispatchMouseEventArgs("mouseReleased", m.x, m.y).
SetClickCount(count).
SetButton(button),
SetButton(button).
SetClickCount(count),
)
}

View File

@ -3,6 +3,7 @@ package drivers
const (
DefaultPageLoadTimeout = 60000
DefaultWaitTimeout = 5000
DefaultInputDelay = 25
DefaultKeyboardDelay = 25
DefaultMouseDelay = 10
DefaultTimeout = 30000
)

View File

@ -207,14 +207,6 @@ func (doc *HTMLDocument) GetParentDocument() drivers.HTMLDocument {
return doc.parent
}
func (doc *HTMLDocument) ClickBySelector(_ context.Context, _ values.String) error {
return core.ErrNotSupported
}
func (doc *HTMLDocument) ClickBySelectorAll(_ context.Context, _ values.String) error {
return core.ErrNotSupported
}
func (doc *HTMLDocument) ScrollTop(_ context.Context) error {
return core.ErrNotSupported
}

View File

@ -489,15 +489,15 @@ func (el *HTMLElement) Iterate(_ context.Context) (core.Iterator, error) {
return common.NewIterator(el)
}
func (el *HTMLElement) Click(_ context.Context) error {
func (el *HTMLElement) Click(_ context.Context, _ values.Int) error {
return core.ErrNotSupported
}
func (el *HTMLElement) ClickBySelector(_ context.Context, _ values.String) error {
func (el *HTMLElement) ClickBySelector(_ context.Context, _ values.String, _ values.Int) error {
return core.ErrNotSupported
}
func (el *HTMLElement) ClickBySelectorAll(_ context.Context, _ values.String) error {
func (el *HTMLElement) ClickBySelectorAll(_ context.Context, _ values.String, _ values.Int) error {
return core.ErrNotSupported
}

View File

@ -43,10 +43,6 @@ type (
ExistsBySelector(ctx context.Context, selector values.String) (values.Boolean, error)
XPath(ctx context.Context, expression values.String) (core.Value, error)
ClickBySelector(ctx context.Context, selector values.String) error
ClickBySelectorAll(ctx context.Context, selector values.String) error
}
// HTMLElement is the most general base interface which most objects in a GetMainFrame implement.
@ -97,7 +93,11 @@ type (
GetInnerTextBySelectorAll(ctx context.Context, selector values.String) (*values.Array, error)
Click(ctx context.Context) error
Click(ctx context.Context, count values.Int) error
ClickBySelector(ctx context.Context, selector values.String, count values.Int) error
ClickBySelectorAll(ctx context.Context, selector values.String, count values.Int) error
Clear(ctx context.Context) error

View File

@ -6,13 +6,15 @@ import (
"github.com/MontFerret/ferret/pkg/drivers"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
// Click dispatches click event on a given element
// @param source (Open | GetElement) - Event source.
// @param selector (String, optional) - Optional selector.
// @param selectorOrCount (String | Int, optional) - Optional selector or count of clicks.
// @param count (Int, optional) - Optional count of clicks.
func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 1, 2)
err := core.ValidateArgs(args, 1, 3)
if err != nil {
return values.False, err
@ -26,7 +28,44 @@ func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
// CLICK(elOrDoc)
if len(args) == 1 {
return values.True, el.Click(ctx)
return values.True, el.Click(ctx, 1)
}
if len(args) == 2 {
err := core.ValidateType(args[1], types.String, types.Int)
if err != nil {
return values.False, err
}
if args[1].Type() == types.String {
selector := values.ToString(args[1])
exists, err := el.ExistsBySelector(ctx, selector)
if err != nil {
return values.False, err
}
if !exists {
return exists, nil
}
return exists, el.ClickBySelector(ctx, selector, 1)
}
return values.True, el.Click(ctx, values.ToInt(args[1]))
}
err = core.ValidateType(args[1], types.String)
if err != nil {
return values.False, err
}
err = core.ValidateType(args[2], types.Int)
if err != nil {
return values.False, err
}
// CLICK(doc, selector)
@ -41,5 +80,7 @@ func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
return exists, nil
}
return exists, el.ClickBySelector(ctx, selector)
count := values.ToInt(args[2])
return exists, el.ClickBySelector(ctx, selector, count)
}

View File

@ -6,14 +6,16 @@ import (
"github.com/MontFerret/ferret/pkg/drivers"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
// ClickAll dispatches click event on all matched element
// @param source (Open) - Open.
// @param selector (String) - Selector.
// @param count (Int, optional) - Optional count of clicks.
// @returns (Boolean) - Returns true if matched at least one element.
func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
err := core.ValidateArgs(args, 2, 2)
err := core.ValidateArgs(args, 2, 3)
if err != nil {
return values.False, err
@ -22,7 +24,7 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
el, err := drivers.ToElement(args[0])
if err != nil {
return values.None, err
return values.False, err
}
selector := values.ToString(args[1])
@ -37,5 +39,17 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
return values.False, nil
}
return values.True, el.ClickBySelectorAll(ctx, selector)
count := values.NewInt(1)
if len(args) == 3 {
err := core.ValidateType(args[2], types.Int)
if err != nil {
return values.False, err
}
count = values.ToInt(args[2])
}
return values.True, el.ClickBySelectorAll(ctx, selector, count)
}

View File

@ -27,7 +27,7 @@ func Input(ctx context.Context, args ...core.Value) (core.Value, error) {
return values.False, err
}
delay := values.NewInt(drivers.DefaultInputDelay)
delay := values.NewInt(drivers.DefaultKeyboardDelay)
// INPUT(el, value)
if len(args) == 2 {

View File

@ -102,7 +102,7 @@ func (i *PagingIterator) Next(ctx context.Context) (core.Value, core.Value, erro
return values.None, values.None, core.ErrNoMoreData
}
err = i.document.ClickBySelector(ctx, i.selector)
err = i.document.GetElement().ClickBySelector(ctx, i.selector, 1)
if err != nil {
return values.None, values.None, err

View File

@ -4,10 +4,6 @@ confidence = 0.8
errorCode = 1
warningCode = 0
[rule.package-comments]
severity = "warning"
[rule.exported]
severity = "warning"
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]