Skip to content

Commit

Permalink
Bugfix/http driver xpath (#725)
Browse files Browse the repository at this point in the history
* Fixed XPath eval in http driver for attrribute values

* Added unit test to cover http XPath func eval

* Added integration test for covering XPath by CDP driver
  • Loading branch information
ziflex committed Jan 28, 2022
1 parent 8d8afed commit 0c6d4e6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
8 changes: 8 additions & 0 deletions e2e/tests/dynamic/element/xpath/attrs.fql
@@ -0,0 +1,8 @@
LET url = @lab.cdn.dynamic
LET page = DOCUMENT(url, true)

LET actual = XPATH(page, "//body/@class")

T::NOT::EMPTY(actual)

RETURN T::EQ(actual[0], "text-center")
51 changes: 51 additions & 0 deletions pkg/drivers/http/element_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/MontFerret/ferret/pkg/drivers"
"github.com/MontFerret/ferret/pkg/drivers/http"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
"github.com/PuerkitoBio/goquery"
. "github.com/smartystreets/goconvey/convey"
"testing"
Expand Down Expand Up @@ -447,5 +448,55 @@ func TestElement(t *testing.T) {
So(err, ShouldBeNil)
So(nt.String(), ShouldEqual, "[\"Album example for Bootstrap\"]")
})

Convey("Func", func() {
buff := bytes.NewBuffer([]byte(doc))

buff.Write([]byte(doc))

doc, err := goquery.NewDocumentFromReader(buff)

So(err, ShouldBeNil)

el, err := http.NewHTMLElement(doc.Find("html"))

So(err, ShouldBeNil)

nt, err := el.XPath(context.Background(), values.NewString("count(//div)"))

So(err, ShouldBeNil)
So(nt.Type().String(), ShouldEqual, types.Float.String())
})

Convey("Attributes", func() {
buff := bytes.NewBuffer([]byte(`<!DOCTYPE html><body><div><a title="30"/></div></body></html>`))
godoc, err := goquery.NewDocumentFromReader(buff)
So(err, ShouldBeNil)

doc, err := http.NewRootHTMLDocument(godoc, "localhost:9090")
So(err, ShouldBeNil)

nt, err := doc.XPath(context.Background(), values.NewString("//a/@title"))

So(err, ShouldBeNil)
So(nt.Type().String(), ShouldEqual, types.Array.String())
So(nt.(*values.Array).First().Type().String(), ShouldEqual, types.String.String())
So(nt.(*values.Array).First().String(), ShouldEqual, "30")
})

Convey("Element node", func() {
buff := bytes.NewBuffer([]byte(`<!DOCTYPE html><body><div><a title="30"/></div></body></html>`))
godoc, err := goquery.NewDocumentFromReader(buff)
So(err, ShouldBeNil)

doc, err := http.NewRootHTMLDocument(godoc, "localhost:9090")
So(err, ShouldBeNil)

nt, err := doc.XPath(context.Background(), values.NewString("//div"))

So(err, ShouldBeNil)
So(nt.Type().String(), ShouldEqual, types.Array.String())
So(nt.(*values.Array).First().Type().String(), ShouldEqual, drivers.HTMLElementType.String())
})
})
}
15 changes: 9 additions & 6 deletions pkg/drivers/http/xpath.go
Expand Up @@ -84,12 +84,15 @@ func EvalXPathTo(selection *goquery.Selection, expression string) (core.Value, e
for res.MoveNext() {
var item core.Value

node := res.Current().(*htmlquery.NodeNavigator).Current()

if node.Type == html.TextNode {
item = values.NewString(node.Data)
} else {
i, err := parseXPathNode(node)
node := res.Current()

switch node.NodeType() {
case xpath.TextNode:
item = values.NewString(node.Value())
case xpath.AttributeNode:
item = values.NewString(node.Value())
default:
i, err := parseXPathNode(node.(*htmlquery.NodeNavigator).Current())

if err != nil {
return nil, err
Expand Down

0 comments on commit 0c6d4e6

Please sign in to comment.