diff --git a/CHANGELOG.md b/CHANGELOG.md index 21043acb..ea21ef4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Changelog +### 0.8.3 +#### Fixed +- Unable to click by selector using an element. + ### 0.8.2 #### Fixed - Scrolling position is not centered. [#343](https://github.com/MontFerret/ferret/pull/343) diff --git a/e2e/pages/dynamic/components/pages/events/appearable.js b/e2e/pages/dynamic/components/pages/events/appearable.js index 160fd0ed..c6c40d07 100644 --- a/e2e/pages/dynamic/components/pages/events/appearable.js +++ b/e2e/pages/dynamic/components/pages/events/appearable.js @@ -55,7 +55,7 @@ export default class AppearableComponent extends React.PureComponent { render() { 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("button", { id: btnId, diff --git a/e2e/pages/dynamic/components/pages/events/clickable.js b/e2e/pages/dynamic/components/pages/events/clickable.js index f0d3b48c..7e63bd1b 100644 --- a/e2e/pages/dynamic/components/pages/events/clickable.js +++ b/e2e/pages/dynamic/components/pages/events/clickable.js @@ -34,7 +34,7 @@ export default class ClickableComponent extends React.PureComponent { 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("button", { id: btnId, diff --git a/e2e/pages/dynamic/components/pages/events/focusable.js b/e2e/pages/dynamic/components/pages/events/focusable.js index 473c626c..c7400007 100644 --- a/e2e/pages/dynamic/components/pages/events/focusable.js +++ b/e2e/pages/dynamic/components/pages/events/focusable.js @@ -42,7 +42,7 @@ export default class FocusableComponent extends React.PureComponent { 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", { classNames: "form-group" }, [ e("input", { diff --git a/e2e/pages/dynamic/components/pages/events/hoverable.js b/e2e/pages/dynamic/components/pages/events/hoverable.js index ded13f5e..54fac586 100644 --- a/e2e/pages/dynamic/components/pages/events/hoverable.js +++ b/e2e/pages/dynamic/components/pages/events/hoverable.js @@ -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("button", { id: "hoverable-btn", diff --git a/e2e/pages/dynamic/components/pages/events/index.js b/e2e/pages/dynamic/components/pages/events/index.js index 4ee556af..65d44f09 100644 --- a/e2e/pages/dynamic/components/pages/events/index.js +++ b/e2e/pages/dynamic/components/pages/events/index.js @@ -9,16 +9,16 @@ export default class EventsPage extends React.Component { render() { return e("div", { id: "page-events" }, [ e("div", { className: "row" }, [ - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Hoverable), ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Clickable, { id: "wait-class", title: "Add class" }) ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Clickable, { id: "wait-class-random", title: "Add class 2", @@ -27,14 +27,14 @@ export default class EventsPage extends React.Component { ]) ]), e("div", { className: "row" }, [ - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Clickable, { id: "wait-no-class", title: "Remove class", show: true }) ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Clickable, { id: "wait-no-class-random", title: "Remove class 2", @@ -42,7 +42,7 @@ export default class EventsPage extends React.Component { randomTimeout: true }) ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Appearable, { id: "wait-element", appear: true, @@ -51,14 +51,14 @@ export default class EventsPage extends React.Component { ]), ]), e("div", { className: "row" }, [ - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Appearable, { id: "wait-no-element", appear: false, title: "Disappearable" }) ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Appearable, { id: "wait-style", appear: true, @@ -66,7 +66,7 @@ export default class EventsPage extends React.Component { useStyle: true, }) ]), - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Appearable, { id: "wait-no-style", appear: false, @@ -76,7 +76,7 @@ export default class EventsPage extends React.Component { ]), ]), e("div", { className: "row" }, [ - e("div", { className: "col-lg-4"}, [ + e("div", { className: "col-lg-4" }, [ e(Focusable, { id: "focus", appear: false, diff --git a/e2e/pages/dynamic/utils/random.js b/e2e/pages/dynamic/utils/random.js index 2f401403..e0bb7a23 100644 --- a/e2e/pages/dynamic/utils/random.js +++ b/e2e/pages/dynamic/utils/random.js @@ -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; if (val < min) { diff --git a/e2e/tests/dynamic/element/click/click.fql b/e2e/tests/dynamic/element/click/click.fql new file mode 100644 index 00000000..b45a0f20 --- /dev/null +++ b/e2e/tests/dynamic/element/click/click.fql @@ -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 "" \ No newline at end of file diff --git a/e2e/tests/dynamic/element/click/click_by_selector.fql b/e2e/tests/dynamic/element/click/click_by_selector.fql new file mode 100644 index 00000000..982df473 --- /dev/null +++ b/e2e/tests/dynamic/element/click/click_by_selector.fql @@ -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 "" \ No newline at end of file diff --git a/pkg/drivers/cdp/document.go b/pkg/drivers/cdp/document.go index 16d64929..82d59f5c 100644 --- a/pkg/drivers/cdp/document.go +++ b/pkg/drivers/cdp/document.go @@ -318,11 +318,11 @@ func (doc *HTMLDocument) GetURL() values.String { } 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 { - 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 { diff --git a/pkg/drivers/cdp/element.go b/pkg/drivers/cdp/element.go index 98c9aea5..997bbbbc 100644 --- a/pkg/drivers/cdp/element.go +++ b/pkg/drivers/cdp/element.go @@ -1055,6 +1055,14 @@ func (el *HTMLElement) Click(ctx context.Context) error { 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 { if el.GetNodeName() != "INPUT" { return core.Error(core.ErrInvalidOperation, "element is not an element.") diff --git a/pkg/drivers/http/element.go b/pkg/drivers/http/element.go index a6462390..f9b04f8d 100644 --- a/pkg/drivers/http/element.go +++ b/pkg/drivers/http/element.go @@ -493,6 +493,14 @@ func (el *HTMLElement) Click(_ context.Context) error { 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 { return core.ErrNotSupported } diff --git a/pkg/drivers/value.go b/pkg/drivers/value.go index 416e9f4e..d29eb417 100644 --- a/pkg/drivers/value.go +++ b/pkg/drivers/value.go @@ -43,6 +43,10 @@ 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. @@ -127,10 +131,6 @@ type ( 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 SelectBySelector(ctx context.Context, selector values.String, value *values.Array) (*values.Array, error) diff --git a/pkg/stdlib/html/click.go b/pkg/stdlib/html/click.go index 86332f38..d6bd85d3 100644 --- a/pkg/stdlib/html/click.go +++ b/pkg/stdlib/html/click.go @@ -10,7 +10,7 @@ import ( // Click dispatches click event on a given element // @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) { 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 } - // CLICK(el) - 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]) + el, err := drivers.ToElement(args[0]) if err != nil { return values.False, err } + // CLICK(elOrDoc) + if len(args) == 1 { + return values.True, el.Click(ctx) + } + + // CLICK(doc, selector) selector := values.ToString(args[1]) - exists, err := doc.ExistsBySelector(ctx, selector) + exists, err := el.ExistsBySelector(ctx, selector) if err != nil { return values.False, err @@ -47,5 +41,5 @@ func Click(ctx context.Context, args ...core.Value) (core.Value, error) { return exists, nil } - return exists, doc.ClickBySelector(ctx, selector) + return exists, el.ClickBySelector(ctx, selector) } diff --git a/pkg/stdlib/html/click_all.go b/pkg/stdlib/html/click_all.go index dda4a62f..7c6cf75f 100644 --- a/pkg/stdlib/html/click_all.go +++ b/pkg/stdlib/html/click_all.go @@ -19,7 +19,7 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) { return values.False, err } - doc, err := drivers.ToDocument(args[0]) + el, err := drivers.ToElement(args[0]) if err != nil { return values.None, err @@ -27,7 +27,7 @@ func ClickAll(ctx context.Context, args ...core.Value) (core.Value, error) { selector := values.ToString(args[1]) - exists, err := doc.ExistsBySelector(ctx, selector) + exists, err := el.ExistsBySelector(ctx, selector) if err != nil { 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.True, doc.ClickBySelectorAll(ctx, selector) + return values.True, el.ClickBySelectorAll(ctx, selector) }