Skip to content

Commit

Permalink
Added support of Element.nextElementSibling and Element.previousEleme… (
Browse files Browse the repository at this point in the history
#569)

* Added support of Element.nextElementSibling and Element.previousElementSibling

* Fixed linting issues

* Removed reedundant logger use
  • Loading branch information
ziflex authored Nov 14, 2020
1 parent 8a40d7b commit 0108824
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 7 deletions.
4 changes: 2 additions & 2 deletions e2e/pages/dynamic/components/pages/lists/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const ITEMS = [{"artist":"Lil Tecca","track":"Ransom"},{"artist":"NLE Choppa","t

export default class ListsPage extends React.Component {
render() {
const items = ITEMS.map((i) => {
return e("li", { className: "list-group-item track"}, [
const items = ITEMS.map((i, idx) => {
return e("li", { className: "list-group-item track", 'data-index': idx }, [
e("div", { className: "track-details"}, [
e("h5", { className: "track-artist"}, i.artist),
e("small", { className: "track-name"}, i.track)
Expand Down
11 changes: 11 additions & 0 deletions e2e/pages/static/list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Ferret E2E SPA</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="./assets/bootstrap.min.css" crossorigin="anonymous">
</head>
<body class="text-center">
<div id="root"><div id="layout"><nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4" id="navbar"><a class="navbar-brand active" aria-current="page" href="http://localhost:8080/#/">Ferret</a><button class="navbar-toggler" type="button"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse"><ul class="navbar-nav mr-auto"><li class="nav-item"><a class="nav-link" href="http://localhost:8080/#/forms">Forms</a></li><li class="nav-item"><a class="nav-link" href="http://localhost:8080/#/navigation">Navigation</a></li><li class="nav-item"><a class="nav-link" href="http://localhost:8080/#/events">Events</a></li><li class="nav-item"><a class="nav-link" href="http://localhost:8080/#/iframe">iFrame</a></li></ul></div></nav><main class="container"><div id="tracks"><ul class="list-group track-list"><li class="list-group-item track" data-index="0"><div class="track-details"><h5 class="track-artist">Lil Tecca</h5><small class="track-name">Ransom</small></div></li><li class="list-group-item track" data-index="1"><div class="track-details"><h5 class="track-artist">NLE Choppa</h5><small class="track-name">Shotta Flow (Feat. Blueface) [Remix]</small></div></li><li class="list-group-item track" data-index="2"><div class="track-details"><h5 class="track-artist">Baby Jesus (DaBaby)</h5><small class="track-name">Suge</small></div></li><li class="list-group-item track" data-index="3"><div class="track-details"><h5 class="track-artist">NLE Choppa</h5><small class="track-name">Shotta Flow 3</small></div></li><li class="list-group-item track" data-index="4"><div class="track-details"><h5 class="track-artist">Lil Tecca </h5><small class="track-name">Lil Tecca - Did It Again</small></div></li><li class="list-group-item track" data-index="5"><div class="track-details"><h5 class="track-artist">NLE Choppa</h5><small class="track-name">Shotta Flow</small></div></li><li class="list-group-item track" data-index="6"><div class="track-details"><h5 class="track-artist">Ynw Melly</h5><small class="track-name">Dangerously In Love (772 Love Pt. 2)</small></div></li><li class="list-group-item track" data-index="7"><div class="track-details"><h5 class="track-artist">POLO G</h5><small class="track-name">Polo G feat. Lil TJay - Pop Out</small></div></li><li class="list-group-item track" data-index="8"><div class="track-details"><h5 class="track-artist">MUSTARD</h5><small class="track-name">Ballin' (feat. Roddy Ricch)</small></div></li><li class="list-group-item track" data-index="9"><div class="track-details"><h5 class="track-artist">Lil Nas X</h5><small class="track-name">Panini</small></div></li><li class="list-group-item track" data-index="10"><div class="track-details"><h5 class="track-artist">Juice WRLD</h5><small class="track-name">Juice Wrld - RUN</small></div></li><li class="list-group-item track" data-index="11"><div class="track-details"><h5 class="track-artist">Shordie Shordie</h5><small class="track-name">Betchua (Bitchuary)</small></div></li><li class="list-group-item track" data-index="12"><div class="track-details"><h5 class="track-artist">Post Malone</h5><small class="track-name">Goodbyes (feat. Young Thug)</small></div></li><li class="list-group-item track" data-index="13"><div class="track-details"><h5 class="track-artist">LIL UZI VERT</h5><small class="track-name">Sanguine Paradise</small></div></li><li class="list-group-item track" data-index="14"><div class="track-details"><h5 class="track-artist">Calboy</h5><small class="track-name">Envy Me</small></div></li><li class="list-group-item track" data-index="15"><div class="track-details"><h5 class="track-artist">Ambjaay</h5><small class="track-name">Uno</small></div></li><li class="list-group-item track" data-index="16"><div class="track-details"><h5 class="track-artist">Lil Tecca</h5><small class="track-name">Lil Tecca - Bossanova</small></div></li><li class="list-group-item track" data-index="17"><div class="track-details"><h5 class="track-artist">Lil Baby</h5><small class="track-name">Baby</small></div></li><li class="list-group-item track" data-index="18"><div class="track-details"><h5 class="track-artist">Lil Tjay</h5><small class="track-name">Lil Tjay - Brothers (Prod by JDONTHATRACK &amp; Protegebeatz)</small></div></li><li class="list-group-item track" data-index="19"><div class="track-details"><h5 class="track-artist">YK Osiris</h5><small class="track-name">Worth It</small></div></li></ul></div></main></div></div>
</body></html>
12 changes: 12 additions & 0 deletions e2e/tests/dynamic/element/siblings/next.fql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
LET doc = DOCUMENT(@lab.cdn.dynamic + "/#/lists", { driver:"cdp" })

LET current = ELEMENT(doc, ".track")
T::NOT::NONE(current)
LET next = current.nextElementSibling
T::NOT::NONE(next)

LET currentIdx = TO_INT(current.attributes['data-index'])
LET nextIdx = TO_INT(next.attributes['data-index'])
T::GT(nextIdx, currentIdx)

RETURN NONE
12 changes: 12 additions & 0 deletions e2e/tests/dynamic/element/siblings/prev.fql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
LET doc = DOCUMENT(@lab.cdn.dynamic + "/#/lists", { driver:"cdp" })

LET current = ELEMENT(doc, '[data-index="1"]')
T::NOT::NONE(current)
LET prev = current.previousElementSibling
T::NOT::NONE(prev)

LET currentIdx = TO_INT(current.attributes['data-index'])
LET prevIdx = TO_INT(prev.attributes['data-index'])
T::LT(prevIdx, currentIdx)

RETURN NONE
13 changes: 13 additions & 0 deletions e2e/tests/static/element/siblings/next.fql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
LET url = @lab.cdn.static + '/list.html'
LET doc = DOCUMENT(url)

LET current = ELEMENT(doc, ".track")
T::NOT::NONE(current)
LET next = current.nextElementSibling.nextElementSibling
T::NOT::NONE(next)

LET currentIdx = TO_INT(current.attributes['data-index'])
LET nextIdx = TO_INT(next.attributes['data-index'])
T::GT(nextIdx, currentIdx)

RETURN NONE
13 changes: 13 additions & 0 deletions e2e/tests/static/element/siblings/prev.fql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
LET url = @lab.cdn.static + '/list.html'
LET doc = DOCUMENT(url)

LET current = ELEMENT(doc, '[data-index="1"]')
T::NOT::NONE(current)
LET prev = current.previousElementSibling
T::NOT::NONE(prev)

LET currentIdx = TO_INT(current.attributes['data-index'])
LET prevIdx = TO_INT(prev.attributes['data-index'])
T::LT(prevIdx, currentIdx)

RETURN NONE
20 changes: 20 additions & 0 deletions pkg/compiler/compiler_member_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,26 @@ func TestMember(t *testing.T) {

So(string(out), ShouldEqual, `"Bob"`)
})

Convey("Computed property with quotes", func() {
c := compiler.New()

p := c.MustCompile(`
LET obj = {
attributes: {
'data-index': 1
}
}
RETURN obj.attributes['data-index']
`)

out, err := p.Run(context.Background())

So(err, ShouldBeNil)

So(string(out), ShouldEqual, "1")
})
})
}

Expand Down
45 changes: 45 additions & 0 deletions pkg/drivers/cdp/dom/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,51 @@ func (el *HTMLElement) GetChildNode(ctx context.Context, idx values.Int) (core.V
)
}

func (el *HTMLElement) GetPreviousElementSibling(ctx context.Context) (core.Value, error) {
return el.getSibling(ctx, templates.GetPreviousElementSibling())
}

func (el *HTMLElement) GetNextElementSibling(ctx context.Context) (core.Value, error) {
return el.getSibling(ctx, templates.GetNextElementSibling())
}

func (el *HTMLElement) getSibling(ctx context.Context, expr string) (core.Value, error) {
if el.IsDetached() {
return values.None, drivers.ErrDetached
}

obj, err := el.exec.EvalWithArgumentsAndReturnReference(ctx, expr, runtime.CallArgument{
ObjectID: &el.id.ObjectID,
})

if err != nil {
return values.None, err
}

if obj.Type != "object" || obj.ObjectID == nil {
return values.None, nil
}

repl, err := el.client.DOM.RequestNode(ctx, dom.NewRequestNodeArgs(*obj.ObjectID))

if err != nil {
return values.None, err
}

return LoadHTMLElementWithID(
ctx,
el.logger,
el.client,
el.dom,
el.input,
el.exec,
HTMLElementIdentity{
NodeID: repl.NodeID,
ObjectID: *obj.ObjectID,
},
)
}

func (el *HTMLElement) QuerySelector(ctx context.Context, selector values.String) (core.Value, error) {
if el.IsDetached() {
return values.None, drivers.ErrDetached
Expand Down
12 changes: 12 additions & 0 deletions pkg/drivers/cdp/templates/siblings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package templates

const getPreviousElementSibling = "(el) => el.previousElementSibling"
const getNextElementSibling = "(el) => el.nextElementSibling"

func GetPreviousElementSibling() string {
return getPreviousElementSibling
}

func GetNextElementSibling() string {
return getNextElementSibling
}
4 changes: 4 additions & 0 deletions pkg/drivers/common/getter.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ func GetInElement(ctx context.Context, el drivers.HTMLElement, path []core.Value
}

return values.GetIn(ctx, styles, path[1:])
case "previousElementSibling":
return el.GetPreviousElementSibling(ctx)
case "nextElementSibling":
return el.GetNextElementSibling(ctx)
default:
return GetInNode(ctx, el, path)
}
Expand Down
32 changes: 27 additions & 5 deletions pkg/drivers/http/element.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,26 @@ func (el *HTMLElement) Iterate(_ context.Context) (core.Iterator, error) {
return common.NewIterator(el)
}

func (el *HTMLElement) GetPreviousElementSibling(_ context.Context) (core.Value, error) {
sibling := el.selection.Prev()

if sibling == nil {
return values.None, nil
}

return NewHTMLElement(sibling)
}

func (el *HTMLElement) GetNextElementSibling(_ context.Context) (core.Value, error) {
sibling := el.selection.Next()

if sibling == nil {
return values.None, nil
}

return NewHTMLElement(sibling)
}

func (el *HTMLElement) Click(_ context.Context, _ values.Int) error {
return core.ErrNotSupported
}
Expand Down Expand Up @@ -608,12 +628,14 @@ func (el *HTMLElement) ensureAttrs() {
func (el *HTMLElement) parseAttrs() *values.Object {
obj := values.NewObject()

for _, name := range common.Attributes {
val, ok := el.selection.Attr(name)
if len(el.selection.Nodes) == 0 {
return obj
}

if ok {
obj.Set(values.NewString(name), values.NewString(val))
}
node := el.selection.Nodes[0]

for _, attr := range node.Attr {
obj.Set(values.NewString(attr.Key), values.NewString(attr.Val))
}

return obj
Expand Down
4 changes: 4 additions & 0 deletions pkg/drivers/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ type (

GetInnerTextBySelectorAll(ctx context.Context, selector values.String) (*values.Array, error)

GetPreviousElementSibling(ctx context.Context) (core.Value, error)

GetNextElementSibling(ctx context.Context) (core.Value, error)

Click(ctx context.Context, count values.Int) error

ClickBySelector(ctx context.Context, selector values.String, count values.Int) error
Expand Down

0 comments on commit 0108824

Please sign in to comment.