1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-01-18 03:22:02 +02:00

Feature/#105 elements count (#109)

* #105 Added ELEMENTS_COUNT function

* Some minor updates

* Invalid return type
This commit is contained in:
Tim Voronov 2018-10-12 21:52:27 -04:00 committed by GitHub
parent 495cc34d77
commit 42757a2a5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 96 additions and 3 deletions

View File

@ -366,6 +366,13 @@ func (doc *HTMLDocument) InnerTextBySelectorAll(selector values.String) *values.
return doc.element.InnerTextBySelectorAll(selector)
}
func (doc *HTMLDocument) CountBySelector(selector values.String) values.Int {
doc.Lock()
defer doc.Unlock()
return doc.element.CountBySelector(selector)
}
func (doc *HTMLDocument) ClickBySelector(selector values.String) (values.Boolean, error) {
res, err := eval.Eval(
doc.client,
@ -567,6 +574,11 @@ func (doc *HTMLDocument) WaitForClassAll(selector, class values.String, timeout
}
func (doc *HTMLDocument) WaitForNavigation(timeout values.Int) error {
// do not wait
if timeout == 0 {
return nil
}
onEvent := make(chan struct{})
listener := func(_ interface{}) {
close(onEvent)

View File

@ -681,6 +681,29 @@ func (el *HTMLElement) InnerHTMLBySelectorAll(selector values.String) *values.Ar
return arr
}
func (el *HTMLElement) CountBySelector(selector values.String) values.Int {
if !el.IsConnected() {
return values.ZeroInt
}
ctx, cancel := contextWithTimeout()
defer cancel()
// TODO: Can we use RemoteObjectID or BackendID instead of NodeId?
selectorArgs := dom.NewQuerySelectorAllArgs(el.id.nodeID, selector.String())
res, err := el.client.DOM.QuerySelectorAll(ctx, selectorArgs)
if err != nil {
el.logError(err).
Str("selector", selector.String()).
Msg("failed to retrieve nodes by selector")
return values.ZeroInt
}
return values.NewInt(len(res.NodeIDs))
}
func (el *HTMLElement) Click() (values.Boolean, error) {
ctx, cancel := contextWithTimeout()

View File

@ -238,6 +238,16 @@ func (el *HTMLElement) InnerTextBySelectorAll(selector values.String) *values.Ar
return arr
}
func (el *HTMLElement) CountBySelector(selector values.String) values.Int {
selection := el.selection.Find(selector.String())
if selection == nil {
return values.ZeroInt
}
return values.NewInt(selection.Size())
}
func (el *HTMLElement) parseAttrs() *values.Object {
obj := values.NewObject()

View File

@ -3,6 +3,7 @@ package static_test
import (
"bytes"
"github.com/MontFerret/ferret/pkg/html/static"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/PuerkitoBio/goquery"
. "github.com/smartystreets/goconvey/convey"
"testing"
@ -297,7 +298,7 @@ func TestElement(t *testing.T) {
So(el.Length(), ShouldEqual, 4)
})
Convey(".Read", t, func() {
Convey(".Value", t, func() {
buff := bytes.NewBuffer([]byte(`
<html>
<head></head>
@ -385,14 +386,34 @@ func TestElement(t *testing.T) {
So(err, ShouldBeNil)
el, err := static.NewHTMLElement(doc.Find("body .card-img-top:nth-child(1)"))
el, err := static.NewHTMLElement(doc.Selection)
So(err, ShouldBeNil)
v := el.NodeName()
found := el.QuerySelector(values.NewString("body .card-img-top:nth-child(1)"))
So(found, ShouldNotEqual, values.None)
v := found.(values.HTMLNode).NodeName()
So(err, ShouldBeNil)
So(v, ShouldEqual, "img")
})
Convey(".CountBySelector", t, func() {
buff := bytes.NewBuffer([]byte(doc))
doc, err := goquery.NewDocumentFromReader(buff)
So(err, ShouldBeNil)
el, err := static.NewHTMLElement(doc.Selection)
So(err, ShouldBeNil)
v := el.CountBySelector(values.NewString("head meta"))
So(v, ShouldEqual, 4)
})
}

View File

@ -37,6 +37,8 @@ type (
InnerTextBySelector(selector String) String
InnerTextBySelectorAll(selector String) *Array
CountBySelector(selector String) Int
}
HTMLDocument interface {

View File

@ -0,0 +1,24 @@
package html
import (
"context"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
)
/*
* Returns a number of found HTML elements by a given CSS selector.
* Returns an empty array if element not found.
* @param docOrEl (HTMLDocument|HTMLElement) - Parent document or element.
* @param selector (String) - CSS selector.
* @returns (Int) - A number of found HTML elements by a given CSS selector.
*/
func ElementsCount(_ context.Context, args ...core.Value) (core.Value, error) {
el, selector, err := queryArgs(args)
if err != nil {
return values.None, err
}
return el.CountBySelector(selector), nil
}

View File

@ -17,6 +17,7 @@ func NewLib() map[string]core.Function {
"DOCUMENT_PARSE": DocumentParse,
"ELEMENT": Element,
"ELEMENTS": Elements,
"ELEMENTS_COUNT": ElementsCount,
"WAIT_ELEMENT": WaitElement,
"WAIT_NAVIGATION": WaitNavigation,
"WAIT_CLASS": WaitClass,