From 07208b1cc387967a6883ca7d83306bd4a30e4064 Mon Sep 17 00:00:00 2001 From: kotamat Date: Mon, 18 Sep 2017 15:20:25 +0900 Subject: [PATCH] Add Atributes All feature --- query.go | 29 +++++++++++++++++++++++++++++ query_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/query.go b/query.go index 3d909dc..0f43939 100644 --- a/query.go +++ b/query.go @@ -209,6 +209,35 @@ func Attributes(sel interface{}, attributes *map[string]string, opts ...QueryOpt }, opts...) } +// AttributesAll retrieves the element attributes for every nodes matching the +// selector. +// selector should be ByQueryAll +func AttributesAll(sel interface{}, attributes *[]map[string]string, opts ...QueryOption) Action { + if attributes == nil { + panic("attributes cannot be nil") + } + + return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { + if len(nodes) < 1 { + return fmt.Errorf("selector `%s` did not return any nodes", sel) + } + + for _, node := range nodes { + node.RLock() + defer node.RUnlock() + + m := make(map[string]string) + attrs := node.Attributes + for i := 0; i < len(attrs); i += 2 { + m[attrs[i]] = attrs[i+1] + } + + *attributes = append(*attributes, m) + } + return nil + }, opts...) +} + // SetAttributes sets the element attributes for the first node matching the // selector. func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryOption) Action { diff --git a/query_test.go b/query_test.go index c16c1d5..aa0b7c1 100644 --- a/query_test.go +++ b/query_test.go @@ -399,6 +399,47 @@ func TestAttributes(t *testing.T) { } } +func TestAttributesAll(t *testing.T) { + t.Parallel() + + c := testAllocate(t, "image.html") + defer c.Release() + + tests := []struct { + sel string + by QueryOption + exp []map[string]string + }{ + {"img", ByQueryAll, + []map[string]string{ + { + "alt": "Brankas - Easy Money Management", + "id": "icon-brankas", + "src": "images/brankas.png", + }, + { + "alt": "How people build software", + "id": "icon-github", + "src": "images/github.png", + }, + }, + }, + } + + var err error + for i, test := range tests { + var attrs []map[string]string + err = c.Run(defaultContext, AttributesAll(test.sel, &attrs, test.by)) + if err != nil { + t.Fatalf("test %d got error: %v", i, err) + } + + if !reflect.DeepEqual(test.exp, attrs) { + t.Errorf("test %d expected %v, got: %v", i, test.exp, attrs) + } + } +} + func TestSetAttributes(t *testing.T) { tests := []struct { sel string @@ -407,14 +448,14 @@ func TestSetAttributes(t *testing.T) { exp map[string]string }{ {`//*[@id="icon-brankas"]`, BySearch, - map[string]string{"data-url": "brankas"}, + map[string]string{"data-url": "brankas"}, map[string]string{ "alt": "Brankas - Easy Money Management", "id": "icon-brankas", "src": "images/brankas.png", "data-url": "brankas"}}, {"body > img:first-child", ByQuery, - map[string]string{"data-url": "brankas"}, + map[string]string{"data-url": "brankas"}, map[string]string{ "alt": "Brankas - Easy Money Management", "id": "icon-brankas", @@ -422,7 +463,7 @@ func TestSetAttributes(t *testing.T) { "data-url": "brankas", }}, {"body > img:nth-child(2)", ByQueryAll, - map[string]string{"width": "100", "height": "200"}, + map[string]string{"width": "100", "height": "200"}, map[string]string{ "alt": `How people build software`, "id": "icon-github", @@ -431,7 +472,7 @@ func TestSetAttributes(t *testing.T) { "height": "200", }}, {"#icon-github", ByID, - map[string]string{"width": "100", "height": "200"}, + map[string]string{"width": "100", "height": "200"}, map[string]string{ "alt": "How people build software", "id": "icon-github",