diff --git a/e2e/tests/dynamic/element/xpath/attrs.fql b/e2e/tests/dynamic/element/xpath/attrs.fql new file mode 100644 index 00000000..fd7e8069 --- /dev/null +++ b/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") \ No newline at end of file diff --git a/pkg/drivers/http/element_test.go b/pkg/drivers/http/element_test.go index 4911cc3a..dd0cdcf0 100644 --- a/pkg/drivers/http/element_test.go +++ b/pkg/drivers/http/element_test.go @@ -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" @@ -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(`
`)) + 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(`
`)) + 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()) + }) }) } diff --git a/pkg/drivers/http/xpath.go b/pkg/drivers/http/xpath.go index 73258b92..540affd0 100644 --- a/pkg/drivers/http/xpath.go +++ b/pkg/drivers/http/xpath.go @@ -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() + node := res.Current() - if node.Type == html.TextNode { - item = values.NewString(node.Data) - } else { - i, err := parseXPathNode(node) + 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