mirror of
https://github.com/MontFerret/ferret.git
synced 2025-02-13 13:58:32 +02:00
Added INPUT_CLEAR function (#366)
* Added INPUT_CLEAR function * Fixed linting issue * Fixed formatting
This commit is contained in:
parent
2a8135657d
commit
af1125c8e9
12
e2e/tests/dynamic/element/clear/clear.fql
Normal file
12
e2e/tests/dynamic/element/clear/clear.fql
Normal file
@ -0,0 +1,12 @@
|
||||
LET url = @dynamic + "?redirect=/forms"
|
||||
LET doc = DOCUMENT(url, true)
|
||||
|
||||
WAIT_ELEMENT(doc, "form")
|
||||
|
||||
LET input = ELEMENT(doc, "#text_input")
|
||||
|
||||
INPUT(input, "Foo", 100)
|
||||
|
||||
INPUT_CLEAR(input)
|
||||
|
||||
RETURN EXPECT("", INNER_TEXT(doc, "#text_output"))
|
14
e2e/tests/dynamic/element/clear/clear_by_selector.fql
Normal file
14
e2e/tests/dynamic/element/clear/clear_by_selector.fql
Normal file
@ -0,0 +1,14 @@
|
||||
LET url = @dynamic + "?redirect=/forms"
|
||||
LET doc = DOCUMENT(url, true)
|
||||
|
||||
WAIT_ELEMENT(doc, "form")
|
||||
|
||||
LET form = ELEMENT(doc, "#page-form")
|
||||
|
||||
INPUT(form, "#text_input", "foo")
|
||||
INPUT_CLEAR(form, "#text_input")
|
||||
|
||||
LET input = ELEMENT(doc, "#text_input")
|
||||
LET output = ELEMENT(doc, "#text_output")
|
||||
|
||||
RETURN EXPECT("", output.innerText)
|
12
e2e/tests/dynamic/element/input/input_by_selector.fql
Normal file
12
e2e/tests/dynamic/element/input/input_by_selector.fql
Normal file
@ -0,0 +1,12 @@
|
||||
LET url = @dynamic + "?redirect=/forms"
|
||||
LET doc = DOCUMENT(url, true)
|
||||
|
||||
WAIT_ELEMENT(doc, "form")
|
||||
|
||||
LET form = ELEMENT(doc, "#page-form")
|
||||
|
||||
INPUT(form, "#text_input", "foo")
|
||||
|
||||
LET output = ELEMENT(doc, "#text_output")
|
||||
|
||||
RETURN EXPECT(output.innerText, "foo")
|
@ -325,10 +325,6 @@ func (doc *HTMLDocument) ClickBySelectorAll(ctx context.Context, selector values
|
||||
return doc.element.ClickBySelectorAll(ctx, selector)
|
||||
}
|
||||
|
||||
func (doc *HTMLDocument) InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error {
|
||||
return doc.input.TypeBySelector(ctx, doc.element.id.nodeID, selector, value, delay)
|
||||
}
|
||||
|
||||
func (doc *HTMLDocument) SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error) {
|
||||
return doc.input.SelectBySelector(ctx, doc.element.id.nodeID, selector, value)
|
||||
}
|
||||
|
@ -1068,7 +1068,27 @@ func (el *HTMLElement) Input(ctx context.Context, value core.Value, delay values
|
||||
return core.Error(core.ErrInvalidOperation, "element is not an <input> element.")
|
||||
}
|
||||
|
||||
return el.input.Type(ctx, el.id.objectID, value, delay)
|
||||
return el.input.Type(ctx, el.id.objectID, input.TypeParams{
|
||||
Text: value,
|
||||
Clear: false,
|
||||
Delay: delay,
|
||||
})
|
||||
}
|
||||
|
||||
func (el *HTMLElement) InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error {
|
||||
return el.input.TypeBySelector(ctx, el.id.nodeID, selector, input.TypeParams{
|
||||
Text: value,
|
||||
Clear: false,
|
||||
Delay: delay,
|
||||
})
|
||||
}
|
||||
|
||||
func (el *HTMLElement) Clear(ctx context.Context) error {
|
||||
return el.input.Clear(ctx, el.id.objectID)
|
||||
}
|
||||
|
||||
func (el *HTMLElement) ClearBySelector(ctx context.Context, selector values.String) error {
|
||||
return el.input.ClearBySelector(ctx, el.id.nodeID, selector)
|
||||
}
|
||||
|
||||
func (el *HTMLElement) Select(ctx context.Context, value *values.Array) (*values.Array, error) {
|
||||
@ -1215,6 +1235,10 @@ func (el *HTMLElement) handleAttrModified(ctx context.Context, message interface
|
||||
return
|
||||
}
|
||||
|
||||
if el.IsDetached() {
|
||||
return
|
||||
}
|
||||
|
||||
el.attributes.Mutate(ctx, func(v core.Value, err error) {
|
||||
if err != nil {
|
||||
el.logError(err).Msg("failed to update element")
|
||||
@ -1255,6 +1279,10 @@ func (el *HTMLElement) handleAttrRemoved(ctx context.Context, message interface{
|
||||
return
|
||||
}
|
||||
|
||||
if el.IsDetached() {
|
||||
return
|
||||
}
|
||||
|
||||
el.attributes.Mutate(ctx, func(v core.Value, err error) {
|
||||
if err != nil {
|
||||
el.logError(err).Msg("failed to update element")
|
||||
@ -1287,6 +1315,13 @@ func (el *HTMLElement) handleChildrenCountChanged(ctx context.Context, message i
|
||||
return
|
||||
}
|
||||
|
||||
if el.IsDetached() {
|
||||
return
|
||||
}
|
||||
|
||||
el.mu.Lock()
|
||||
defer el.mu.Unlock()
|
||||
|
||||
node, err := el.client.DOM.DescribeNode(
|
||||
ctx,
|
||||
dom.NewDescribeNodeArgs().SetObjectID(el.id.objectID),
|
||||
@ -1298,9 +1333,6 @@ func (el *HTMLElement) handleChildrenCountChanged(ctx context.Context, message i
|
||||
return
|
||||
}
|
||||
|
||||
el.mu.Lock()
|
||||
defer el.mu.Unlock()
|
||||
|
||||
el.children = createChildrenArray(node.Node.Children)
|
||||
}
|
||||
|
||||
@ -1319,6 +1351,10 @@ func (el *HTMLElement) handleChildInserted(ctx context.Context, message interfac
|
||||
prevID := reply.PreviousNodeID
|
||||
nextID := reply.Node.NodeID
|
||||
|
||||
if el.IsDetached() {
|
||||
return
|
||||
}
|
||||
|
||||
el.mu.Lock()
|
||||
defer el.mu.Unlock()
|
||||
|
||||
@ -1375,6 +1411,10 @@ func (el *HTMLElement) handleChildRemoved(ctx context.Context, message interface
|
||||
targetIDx := -1
|
||||
targetID := reply.NodeID
|
||||
|
||||
if el.IsDetached() {
|
||||
return
|
||||
}
|
||||
|
||||
el.mu.Lock()
|
||||
defer el.mu.Unlock()
|
||||
|
||||
|
@ -2,15 +2,45 @@ package input
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"time"
|
||||
|
||||
"github.com/mafredri/cdp"
|
||||
"github.com/mafredri/cdp/protocol/input"
|
||||
)
|
||||
|
||||
type Keyboard struct {
|
||||
client *cdp.Client
|
||||
}
|
||||
const DefaultDelay = 25
|
||||
|
||||
type (
|
||||
KeyboardModifier int
|
||||
|
||||
KeyboardLocation int
|
||||
|
||||
KeyboardKey struct {
|
||||
KeyCode int
|
||||
Key string
|
||||
Code string
|
||||
Modifier KeyboardModifier
|
||||
Location KeyboardLocation
|
||||
}
|
||||
|
||||
Keyboard struct {
|
||||
client *cdp.Client
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
KeyboardModifierNone KeyboardModifier = 0
|
||||
KeyboardModifierAlt KeyboardModifier = 1
|
||||
KeyboardModifierCtrl KeyboardModifier = 2
|
||||
KeyboardModifierCmd KeyboardModifier = 4
|
||||
KeyboardModifierShift KeyboardModifier = 8
|
||||
|
||||
// 1=Left, 2=Right
|
||||
KeyboardLocationNone KeyboardLocation = 0
|
||||
KeyboardLocationLeft KeyboardLocation = 1
|
||||
KeyboardLocationRight KeyboardLocation = 2
|
||||
)
|
||||
|
||||
func NewKeyboard(client *cdp.Client) *Keyboard {
|
||||
return &Keyboard{client}
|
||||
@ -40,7 +70,7 @@ func (k *Keyboard) Type(ctx context.Context, text string, delay int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
releaseDelay := randomDuration(delay)
|
||||
releaseDelay := randomDuration(delay) * time.Millisecond
|
||||
time.Sleep(releaseDelay)
|
||||
|
||||
if err := k.Up(ctx, ch); err != nil {
|
||||
@ -50,3 +80,34 @@ func (k *Keyboard) Type(ctx context.Context, text string, delay int) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *Keyboard) Press(ctx context.Context, name string) error {
|
||||
key, found := usKeyboardLayout[name]
|
||||
|
||||
if !found {
|
||||
return errors.New("invalid key")
|
||||
}
|
||||
|
||||
err := k.client.Input.DispatchKeyEvent(
|
||||
ctx,
|
||||
input.NewDispatchKeyEventArgs("keyDown").
|
||||
SetCode(key.Code).
|
||||
SetKey(key.Key).
|
||||
SetWindowsVirtualKeyCode(key.KeyCode),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
releaseDelay := randomDuration(DefaultDelay)
|
||||
time.Sleep(releaseDelay)
|
||||
|
||||
return k.client.Input.DispatchKeyEvent(
|
||||
ctx,
|
||||
input.NewDispatchKeyEventArgs("keyUp").
|
||||
SetCode(key.Code).
|
||||
SetKey(key.Key).
|
||||
SetWindowsVirtualKeyCode(key.KeyCode),
|
||||
)
|
||||
}
|
||||
|
1352
pkg/drivers/cdp/input/layout.go
Normal file
1352
pkg/drivers/cdp/input/layout.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,12 +14,20 @@ import (
|
||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
client *cdp.Client
|
||||
exec *eval.ExecutionContext
|
||||
keyboard *Keyboard
|
||||
mouse *Mouse
|
||||
}
|
||||
type (
|
||||
TypeParams struct {
|
||||
Text core.Value
|
||||
Clear values.Boolean
|
||||
Delay values.Int
|
||||
}
|
||||
|
||||
Manager struct {
|
||||
client *cdp.Client
|
||||
exec *eval.ExecutionContext
|
||||
keyboard *Keyboard
|
||||
mouse *Mouse
|
||||
}
|
||||
)
|
||||
|
||||
func NewManager(
|
||||
client *cdp.Client,
|
||||
@ -213,7 +221,7 @@ func (m *Manager) ClickBySelectorAll(ctx context.Context, parentNodeID dom.NodeI
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, text core.Value, delay values.Int) error {
|
||||
func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, params TypeParams) error {
|
||||
err := m.ScrollIntoView(ctx, objectID)
|
||||
|
||||
if err != nil {
|
||||
@ -226,15 +234,27 @@ func (m *Manager) Type(ctx context.Context, objectID runtime.RemoteObjectID, tex
|
||||
return err
|
||||
}
|
||||
|
||||
_, min := core.NumberBoundaries(float64(delay))
|
||||
if params.Clear {
|
||||
points, err := GetClickablePointByObjectID(ctx, m.client, objectID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.ClearByXY(ctx, points); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, min := core.NumberBoundaries(float64(params.Delay))
|
||||
beforeTypeDelay := time.Duration(min)
|
||||
|
||||
time.Sleep(beforeTypeDelay * time.Millisecond)
|
||||
|
||||
return m.keyboard.Type(ctx, text.String(), int(delay))
|
||||
return m.keyboard.Type(ctx, params.Text.String(), int(params.Delay))
|
||||
}
|
||||
|
||||
func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, selector values.String, text core.Value, delay values.Int) error {
|
||||
func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, selector values.String, params TypeParams) error {
|
||||
err := m.ScrollIntoViewBySelector(ctx, selector)
|
||||
|
||||
if err != nil {
|
||||
@ -253,12 +273,84 @@ func (m *Manager) TypeBySelector(ctx context.Context, parentNodeID dom.NodeID, s
|
||||
return err
|
||||
}
|
||||
|
||||
_, min := core.NumberBoundaries(float64(delay))
|
||||
if params.Clear {
|
||||
points, err := GetClickablePointByNodeID(ctx, m.client, found.NodeID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.ClearByXY(ctx, points); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, min := core.NumberBoundaries(float64(params.Delay))
|
||||
beforeTypeDelay := time.Duration(min)
|
||||
|
||||
time.Sleep(beforeTypeDelay * time.Millisecond)
|
||||
|
||||
return m.keyboard.Type(ctx, text.String(), int(delay))
|
||||
return m.keyboard.Type(ctx, params.Text.String(), int(params.Delay))
|
||||
}
|
||||
|
||||
func (m *Manager) Clear(ctx context.Context, objectID runtime.RemoteObjectID) error {
|
||||
err := m.ScrollIntoView(ctx, objectID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
points, err := GetClickablePointByObjectID(ctx, m.client, objectID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetObjectID(objectID))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.ClearByXY(ctx, points)
|
||||
}
|
||||
|
||||
func (m *Manager) ClearBySelector(ctx context.Context, parentNodeID dom.NodeID, selector values.String) error {
|
||||
err := m.ScrollIntoViewBySelector(ctx, selector)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
found, err := m.client.DOM.QuerySelector(ctx, dom.NewQuerySelectorArgs(parentNodeID, selector.String()))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
points, err := GetClickablePointByNodeID(ctx, m.client, found.NodeID)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = m.client.DOM.Focus(ctx, dom.NewFocusArgs().SetNodeID(found.NodeID))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.ClearByXY(ctx, points)
|
||||
}
|
||||
|
||||
func (m *Manager) ClearByXY(ctx context.Context, points Quad) error {
|
||||
err := m.mouse.ClickWithCount(ctx, points.X, points.Y, 3, 5)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.keyboard.Press(ctx, "Backspace")
|
||||
}
|
||||
|
||||
func (m *Manager) Select(ctx context.Context, objectID runtime.RemoteObjectID, value *values.Array) (*values.Array, error) {
|
||||
|
@ -19,11 +19,15 @@ func NewMouse(client *cdp.Client) *Mouse {
|
||||
}
|
||||
|
||||
func (m *Mouse) Click(ctx context.Context, x, y float64, delay int) error {
|
||||
return m.ClickWithCount(ctx, x, y, 1, delay)
|
||||
}
|
||||
|
||||
func (m *Mouse) ClickWithCount(ctx context.Context, x, y float64, count, delay int) error {
|
||||
if err := m.Move(ctx, x, y); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.Down(ctx, "left"); err != nil {
|
||||
if err := m.DownWithCount(ctx, "left", count); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -31,23 +35,31 @@ func (m *Mouse) Click(ctx context.Context, x, y float64, delay int) error {
|
||||
|
||||
time.Sleep(releaseDelay * time.Millisecond)
|
||||
|
||||
return m.Up(ctx, "left")
|
||||
return m.UpWithCount(ctx, "left", count)
|
||||
}
|
||||
|
||||
func (m *Mouse) Down(ctx context.Context, button string) error {
|
||||
return m.DownWithCount(ctx, button, 1)
|
||||
}
|
||||
|
||||
func (m *Mouse) DownWithCount(ctx context.Context, button string, count int) error {
|
||||
return m.client.Input.DispatchMouseEvent(
|
||||
ctx,
|
||||
input.NewDispatchMouseEventArgs("mousePressed", m.x, m.y).
|
||||
SetClickCount(1).
|
||||
SetClickCount(count).
|
||||
SetButton(button),
|
||||
)
|
||||
}
|
||||
|
||||
func (m *Mouse) Up(ctx context.Context, button string) error {
|
||||
return m.UpWithCount(ctx, button, 1)
|
||||
}
|
||||
|
||||
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(1).
|
||||
SetClickCount(count).
|
||||
SetButton(button),
|
||||
)
|
||||
}
|
||||
|
@ -215,10 +215,6 @@ func (doc *HTMLDocument) ClickBySelectorAll(_ context.Context, _ values.String)
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (doc *HTMLDocument) InputBySelector(_ context.Context, _ values.String, _ core.Value, _ values.Int) error {
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (doc *HTMLDocument) SelectBySelector(_ context.Context, _ values.String, _ *values.Array) (*values.Array, error) {
|
||||
return nil, core.ErrNotSupported
|
||||
}
|
||||
|
@ -501,10 +501,22 @@ func (el *HTMLElement) ClickBySelectorAll(_ context.Context, _ values.String) er
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (el *HTMLElement) Clear(_ context.Context) error {
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (el *HTMLElement) ClearBySelector(_ context.Context, _ values.String) error {
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (el *HTMLElement) Input(_ context.Context, _ core.Value, _ values.Int) error {
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (el *HTMLElement) InputBySelector(_ context.Context, _ values.String, _ core.Value, _ values.Int) error {
|
||||
return core.ErrNotSupported
|
||||
}
|
||||
|
||||
func (el *HTMLElement) Select(_ context.Context, _ *values.Array) (*values.Array, error) {
|
||||
return nil, core.ErrNotSupported
|
||||
}
|
||||
|
@ -99,8 +99,14 @@ type (
|
||||
|
||||
Click(ctx context.Context) error
|
||||
|
||||
Clear(ctx context.Context) error
|
||||
|
||||
ClearBySelector(ctx context.Context, selector values.String) error
|
||||
|
||||
Input(ctx context.Context, value core.Value, delay values.Int) error
|
||||
|
||||
InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error
|
||||
|
||||
Select(ctx context.Context, value *values.Array) (*values.Array, error)
|
||||
|
||||
ScrollIntoView(ctx context.Context) error
|
||||
@ -131,8 +137,6 @@ type (
|
||||
|
||||
GetChildDocuments(ctx context.Context) (*values.Array, error)
|
||||
|
||||
InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error
|
||||
|
||||
SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error)
|
||||
|
||||
ScrollTop(ctx context.Context) error
|
||||
|
33
pkg/stdlib/html/clear.go
Normal file
33
pkg/stdlib/html/clear.go
Normal file
@ -0,0 +1,33 @@
|
||||
package html
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/MontFerret/ferret/pkg/drivers"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||
)
|
||||
|
||||
// InputClear clears a value from an underlying input element.
|
||||
// @param source (HTMLPage | HTMLDocument | HTMLElement) - Event target.
|
||||
// @param selector (String, options) - Selector.
|
||||
func InputClear(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||
err := core.ValidateArgs(args, 1, 2)
|
||||
|
||||
if err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
el, err := drivers.ToElement(args[0])
|
||||
|
||||
if err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
// CLEAR(el)
|
||||
if len(args) == 1 {
|
||||
return values.None, el.Clear(ctx)
|
||||
}
|
||||
|
||||
return values.None, el.ClearBySelector(ctx, values.ToString(args[1]))
|
||||
}
|
@ -2,7 +2,6 @@ package html
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/MontFerret/ferret/pkg/drivers"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/core"
|
||||
"github.com/MontFerret/ferret/pkg/runtime/values"
|
||||
@ -10,93 +9,74 @@ import (
|
||||
)
|
||||
|
||||
// Input types a value to an underlying input element.
|
||||
// @param source (Open | GetElement) - Event target.
|
||||
// @param source (HTMLPage | HTMLDocument | HTMLElement) - Event target.
|
||||
// @param valueOrSelector (String) - Selector or a value.
|
||||
// @param value (String) - Target value.
|
||||
// @param delay (Int, optional) - Waits delay milliseconds between keystrokes
|
||||
// @param delay (Int, optional) - Target value.
|
||||
// @returns (Boolean) - Returns true if an element was found.
|
||||
func Input(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||
err := core.ValidateArgs(args, 2, 4)
|
||||
|
||||
if err != nil {
|
||||
return values.None, err
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
arg1 := args[0]
|
||||
err = core.ValidateType(arg1, drivers.HTMLPageType, drivers.HTMLDocumentType, drivers.HTMLElementType)
|
||||
el, err := drivers.ToElement(args[0])
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
if arg1.Type() == drivers.HTMLPageType || arg1.Type() == drivers.HTMLDocumentType {
|
||||
doc, err := drivers.ToDocument(arg1)
|
||||
delay := values.NewInt(25)
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
// INPUT(el, value)
|
||||
if len(args) == 2 {
|
||||
return values.True, el.Input(ctx, args[1], delay)
|
||||
}
|
||||
|
||||
// selector
|
||||
arg2 := args[1]
|
||||
err = core.ValidateType(arg2, types.String)
|
||||
var selector values.String
|
||||
var value core.Value
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
// INPUT(el, valueOrSelector, valueOrOpts)
|
||||
if len(args) == 3 {
|
||||
switch v := args[2].(type) {
|
||||
// INPUT(el, value, delay)
|
||||
case values.Int, values.Float:
|
||||
value = args[1]
|
||||
delay = values.ToInt(v)
|
||||
|
||||
selector := values.ToString(arg2)
|
||||
delay := values.Int(0)
|
||||
|
||||
if len(args) == 4 {
|
||||
arg4 := args[3]
|
||||
|
||||
err = core.ValidateType(arg4, types.Int)
|
||||
return values.True, el.Input(ctx, value, delay)
|
||||
default:
|
||||
// INPUT(el, selector, value)
|
||||
err := core.ValidateType(args[1], types.String)
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
delay = values.ToInt(arg4)
|
||||
selector = values.ToString(args[1])
|
||||
value = args[2]
|
||||
}
|
||||
|
||||
exists, err := doc.ExistsBySelector(ctx, selector)
|
||||
} else {
|
||||
// INPUT(el, selector, value, delay)
|
||||
err := core.ValidateType(args[3], types.Int)
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return values.False, nil
|
||||
}
|
||||
|
||||
return values.True, doc.InputBySelector(ctx, selector, args[2], delay)
|
||||
delay = values.ToInt(args[3])
|
||||
}
|
||||
|
||||
el, err := drivers.ToElement(arg1)
|
||||
|
||||
if err != nil {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
delay := values.Int(0)
|
||||
|
||||
if len(args) == 3 {
|
||||
arg3 := args[2]
|
||||
|
||||
err = core.ValidateType(arg3, types.Int)
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
delay = arg3.(values.Int)
|
||||
}
|
||||
|
||||
err = el.Input(ctx, args[1], delay)
|
||||
exists, err := el.ExistsBySelector(ctx, selector)
|
||||
|
||||
if err != nil {
|
||||
return values.False, err
|
||||
}
|
||||
|
||||
return values.True, nil
|
||||
if !exists {
|
||||
return values.False, nil
|
||||
}
|
||||
|
||||
return values.True, el.InputBySelector(ctx, selector, value, delay)
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ func RegisterLib(ns core.Namespace) error {
|
||||
"INNER_TEXT_SET": SetInnerText,
|
||||
"INNER_TEXT_ALL": GetInnerTextAll,
|
||||
"INPUT": Input,
|
||||
"INPUT_CLEAR": InputClear,
|
||||
"MOUSE": MouseMoveXY,
|
||||
"NAVIGATE": Navigate,
|
||||
"NAVIGATE_BACK": NavigateBack,
|
||||
|
Loading…
x
Reference in New Issue
Block a user