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:
parent
495cc34d77
commit
42757a2a5a
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ type (
|
||||
InnerTextBySelector(selector String) String
|
||||
|
||||
InnerTextBySelectorAll(selector String) *Array
|
||||
|
||||
CountBySelector(selector String) Int
|
||||
}
|
||||
|
||||
HTMLDocument interface {
|
||||
|
24
pkg/stdlib/html/elements_count.go
Normal file
24
pkg/stdlib/html/elements_count.go
Normal 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
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user