mirror of
https://github.com/MontFerret/ferret.git
synced 2025-07-15 01:25:00 +02:00
Bugfix/click (#355)
* Added ability to use ClickBySelector with an element * Fixes * Increased timeout time
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### 0.8.3
|
||||||
|
#### Fixed
|
||||||
|
- Unable to click by selector using an element.
|
||||||
|
|
||||||
### 0.8.2
|
### 0.8.2
|
||||||
#### Fixed
|
#### Fixed
|
||||||
- Scrolling position is not centered. [#343](https://github.com/MontFerret/ferret/pull/343)
|
- Scrolling position is not centered. [#343](https://github.com/MontFerret/ferret/pull/343)
|
||||||
|
@ -55,7 +55,7 @@ export default class AppearableComponent extends React.PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const btnId = `${this.props.id}-btn`;
|
const btnId = `${this.props.id}-btn`;
|
||||||
|
|
||||||
return e("div", {className: "card"}, [
|
return e("div", { id: this.props.id, className: "card"}, [
|
||||||
e("div", { className: "card-header"}, [
|
e("div", { className: "card-header"}, [
|
||||||
e("button", {
|
e("button", {
|
||||||
id: btnId,
|
id: btnId,
|
||||||
|
@ -34,7 +34,7 @@ export default class ClickableComponent extends React.PureComponent {
|
|||||||
classNames.push("alert-success");
|
classNames.push("alert-success");
|
||||||
}
|
}
|
||||||
|
|
||||||
return e("div", {className: "card clickable"}, [
|
return e("div", { id: this.props.id, className: "card clickable"}, [
|
||||||
e("div", { className: "card-header"}, [
|
e("div", { className: "card-header"}, [
|
||||||
e("button", {
|
e("button", {
|
||||||
id: btnId,
|
id: btnId,
|
||||||
|
@ -42,7 +42,7 @@ export default class FocusableComponent extends React.PureComponent {
|
|||||||
classNames.push("alert-success");
|
classNames.push("alert-success");
|
||||||
}
|
}
|
||||||
|
|
||||||
return e("div", {className: "card focusable"}, [
|
return e("div", {id: this.props.id, className: "card focusable"}, [
|
||||||
e("div", { className: "card-header"}, [
|
e("div", { className: "card-header"}, [
|
||||||
e("div", { classNames: "form-group" }, [
|
e("div", { classNames: "form-group" }, [
|
||||||
e("input", {
|
e("input", {
|
||||||
|
@ -30,7 +30,7 @@ export default class HoverableComponent extends React.PureComponent {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return e("div", { className: "card"}, [
|
return e("div", { id: this.props.id, className: "card"}, [
|
||||||
e("div", {className: "card-header"}, [
|
e("div", {className: "card-header"}, [
|
||||||
e("button", {
|
e("button", {
|
||||||
id: "hoverable-btn",
|
id: "hoverable-btn",
|
||||||
|
@ -9,16 +9,16 @@ export default class EventsPage extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return e("div", { id: "page-events" }, [
|
return e("div", { id: "page-events" }, [
|
||||||
e("div", { className: "row" }, [
|
e("div", { className: "row" }, [
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Hoverable),
|
e(Hoverable),
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Clickable, {
|
e(Clickable, {
|
||||||
id: "wait-class",
|
id: "wait-class",
|
||||||
title: "Add class"
|
title: "Add class"
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Clickable, {
|
e(Clickable, {
|
||||||
id: "wait-class-random",
|
id: "wait-class-random",
|
||||||
title: "Add class 2",
|
title: "Add class 2",
|
||||||
@ -27,14 +27,14 @@ export default class EventsPage extends React.Component {
|
|||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
e("div", { className: "row" }, [
|
e("div", { className: "row" }, [
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Clickable, {
|
e(Clickable, {
|
||||||
id: "wait-no-class",
|
id: "wait-no-class",
|
||||||
title: "Remove class",
|
title: "Remove class",
|
||||||
show: true
|
show: true
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Clickable, {
|
e(Clickable, {
|
||||||
id: "wait-no-class-random",
|
id: "wait-no-class-random",
|
||||||
title: "Remove class 2",
|
title: "Remove class 2",
|
||||||
@ -42,7 +42,7 @@ export default class EventsPage extends React.Component {
|
|||||||
randomTimeout: true
|
randomTimeout: true
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Appearable, {
|
e(Appearable, {
|
||||||
id: "wait-element",
|
id: "wait-element",
|
||||||
appear: true,
|
appear: true,
|
||||||
@ -51,14 +51,14 @@ export default class EventsPage extends React.Component {
|
|||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
e("div", { className: "row" }, [
|
e("div", { className: "row" }, [
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Appearable, {
|
e(Appearable, {
|
||||||
id: "wait-no-element",
|
id: "wait-no-element",
|
||||||
appear: false,
|
appear: false,
|
||||||
title: "Disappearable"
|
title: "Disappearable"
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Appearable, {
|
e(Appearable, {
|
||||||
id: "wait-style",
|
id: "wait-style",
|
||||||
appear: true,
|
appear: true,
|
||||||
@ -66,7 +66,7 @@ export default class EventsPage extends React.Component {
|
|||||||
useStyle: true,
|
useStyle: true,
|
||||||
})
|
})
|
||||||
]),
|
]),
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Appearable, {
|
e(Appearable, {
|
||||||
id: "wait-no-style",
|
id: "wait-no-style",
|
||||||
appear: false,
|
appear: false,
|
||||||
@ -76,7 +76,7 @@ export default class EventsPage extends React.Component {
|
|||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
e("div", { className: "row" }, [
|
e("div", { className: "row" }, [
|
||||||
e("div", { className: "col-lg-4"}, [
|
e("div", { className: "col-lg-4" }, [
|
||||||
e(Focusable, {
|
e(Focusable, {
|
||||||
id: "focus",
|
id: "focus",
|
||||||
appear: false,
|
appear: false,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export default function random(min = 1000, max = 5000) {
|
export default function random(min = 1000, max = 4000) {
|
||||||
const val = Math.random() * 1000 * 10;
|
const val = Math.random() * 1000 * 10;
|
||||||
|
|
||||||
if (val < min) {
|
if (val < min) {
|
||||||
|
10
e2e/tests/dynamic/element/click/click.fql
Normal file
10
e2e/tests/dynamic/element/click/click.fql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
LET url = @dynamic + "/#/events"
|
||||||
|
LET page = DOCUMENT(url, true)
|
||||||
|
|
||||||
|
LET btn = ELEMENT(page, "#wait-class-random-btn")
|
||||||
|
|
||||||
|
CLICK(btn)
|
||||||
|
|
||||||
|
WAIT_CLASS(page, "#wait-class-random-content", "alert-success")
|
||||||
|
|
||||||
|
RETURN ""
|
10
e2e/tests/dynamic/element/click/click_by_selector.fql
Normal file
10
e2e/tests/dynamic/element/click/click_by_selector.fql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
LET url = "http://192.168.1.170:8080/#/events"
|
||||||
|
LET page = DOCUMENT(url, true)
|
||||||
|
|
||||||
|
LET div = ELEMENT(page, "#wait-class-random")
|
||||||
|
|
||||||
|
CLICK(div, "button")
|
||||||
|
|
||||||
|
WAIT_CLASS(page, "#wait-class-random-content", "alert-success", 10000)
|
||||||
|
|
||||||
|
RETURN ""
|
@ -318,11 +318,11 @@ func (doc *HTMLDocument) GetURL() values.String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ClickBySelector(ctx context.Context, selector values.String) error {
|
func (doc *HTMLDocument) ClickBySelector(ctx context.Context, selector values.String) error {
|
||||||
return doc.input.ClickBySelector(ctx, doc.element.id.nodeID, selector)
|
return doc.element.ClickBySelector(ctx, selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) ClickBySelectorAll(ctx context.Context, selector values.String) error {
|
func (doc *HTMLDocument) ClickBySelectorAll(ctx context.Context, selector values.String) error {
|
||||||
return doc.input.ClickBySelectorAll(ctx, doc.element.id.nodeID, selector)
|
return doc.element.ClickBySelectorAll(ctx, selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (doc *HTMLDocument) InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error {
|
func (doc *HTMLDocument) InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) error {
|
||||||
|
@ -1055,6 +1055,14 @@ func (el *HTMLElement) Click(ctx context.Context) error {
|
|||||||
return el.input.Click(ctx, el.id.objectID)
|
return el.input.Click(ctx, el.id.objectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (el *HTMLElement) ClickBySelector(ctx context.Context, selector values.String) error {
|
||||||
|
return el.input.ClickBySelector(ctx, el.id.nodeID, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *HTMLElement) ClickBySelectorAll(ctx context.Context, selector values.String) error {
|
||||||
|
return el.input.ClickBySelectorAll(ctx, el.id.nodeID, selector)
|
||||||
|
}
|
||||||
|
|
||||||
func (el *HTMLElement) Input(ctx context.Context, value core.Value, delay values.Int) error {
|
func (el *HTMLElement) Input(ctx context.Context, value core.Value, delay values.Int) error {
|
||||||
if el.GetNodeName() != "INPUT" {
|
if el.GetNodeName() != "INPUT" {
|
||||||
return core.Error(core.ErrInvalidOperation, "element is not an <input> element.")
|
return core.Error(core.ErrInvalidOperation, "element is not an <input> element.")
|
||||||
|
@ -493,6 +493,14 @@ func (el *HTMLElement) Click(_ context.Context) error {
|
|||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (el *HTMLElement) ClickBySelector(_ context.Context, _ values.String) error {
|
||||||
|
return core.ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *HTMLElement) ClickBySelectorAll(_ context.Context, _ values.String) error {
|
||||||
|
return core.ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (el *HTMLElement) Input(_ context.Context, _ core.Value, _ values.Int) error {
|
func (el *HTMLElement) Input(_ context.Context, _ core.Value, _ values.Int) error {
|
||||||
return core.ErrNotSupported
|
return core.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,10 @@ type (
|
|||||||
ExistsBySelector(ctx context.Context, selector values.String) (values.Boolean, error)
|
ExistsBySelector(ctx context.Context, selector values.String) (values.Boolean, error)
|
||||||
|
|
||||||
XPath(ctx context.Context, expression values.String) (core.Value, 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.
|
// HTMLElement is the most general base interface which most objects in a GetMainFrame implement.
|
||||||
@ -127,10 +131,6 @@ type (
|
|||||||
|
|
||||||
GetChildDocuments(ctx context.Context) (*values.Array, error)
|
GetChildDocuments(ctx context.Context) (*values.Array, error)
|
||||||
|
|
||||||
ClickBySelector(ctx context.Context, selector values.String) error
|
|
||||||
|
|
||||||
ClickBySelectorAll(ctx context.Context, selector values.String) error
|
|
||||||
|
|
||||||
InputBySelector(ctx context.Context, selector values.String, value core.Value, delay values.Int) 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)
|
SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// Click dispatches click event on a given element
|
// Click dispatches click event on a given element
|
||||||
// @param source (Open | GetElement) - Event source.
|
// @param source (Open | GetElement) - Event source.
|
||||||
// @param selector (String, optional) - Optional selector. Only used when a document instance is passed.
|
// @param selector (String, optional) - Optional selector.
|
||||||
func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
|
func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||||
err := core.ValidateArgs(args, 1, 2)
|
err := core.ValidateArgs(args, 1, 2)
|
||||||
|
|
||||||
@ -18,26 +18,20 @@ func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return values.False, err
|
return values.False, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLICK(el)
|
el, err := drivers.ToElement(args[0])
|
||||||
if len(args) == 1 {
|
|
||||||
el, err := drivers.ToElement(args[0])
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return values.False, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return values.True, el.Click(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CLICK(doc, selector)
|
|
||||||
doc, err := drivers.ToDocument(args[0])
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.False, err
|
return values.False, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CLICK(elOrDoc)
|
||||||
|
if len(args) == 1 {
|
||||||
|
return values.True, el.Click(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CLICK(doc, selector)
|
||||||
selector := values.ToString(args[1])
|
selector := values.ToString(args[1])
|
||||||
exists, err := doc.ExistsBySelector(ctx, selector)
|
exists, err := el.ExistsBySelector(ctx, selector)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.False, err
|
return values.False, err
|
||||||
@ -47,5 +41,5 @@ func Click(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return exists, nil
|
return exists, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return exists, doc.ClickBySelector(ctx, selector)
|
return exists, el.ClickBySelector(ctx, selector)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return values.False, err
|
return values.False, err
|
||||||
}
|
}
|
||||||
|
|
||||||
doc, err := drivers.ToDocument(args[0])
|
el, err := drivers.ToElement(args[0])
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.None, err
|
return values.None, err
|
||||||
@ -27,7 +27,7 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
|
|
||||||
selector := values.ToString(args[1])
|
selector := values.ToString(args[1])
|
||||||
|
|
||||||
exists, err := doc.ExistsBySelector(ctx, selector)
|
exists, err := el.ExistsBySelector(ctx, selector)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return values.False, err
|
return values.False, err
|
||||||
@ -37,5 +37,5 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) {
|
|||||||
return values.False, nil
|
return values.False, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return values.True, doc.ClickBySelectorAll(ctx, selector)
|
return values.True, el.ClickBySelectorAll(ctx, selector)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user