Adding OuterHTML and InnerHTML actions

This commit is contained in:
Kenneth Shaw 2017-07-01 11:53:22 +07:00
parent df490a3025
commit 1a35cceeae
5 changed files with 78 additions and 45 deletions

View File

@ -15,6 +15,7 @@ gometalinter \
--exclude='/easyjson\.go.*(passes|copies) lock' \ --exclude='/easyjson\.go.*(passes|copies) lock' \
--exclude='/easyjson\.go.*ineffectual assignment' \ --exclude='/easyjson\.go.*ineffectual assignment' \
--exclude='/easyjson\.go.*unnecessary conversion' \ --exclude='/easyjson\.go.*unnecessary conversion' \
--exclude='/easyjson\.go.*this value of key is never used' \
--exclude='/easyjson\.go.*\((gocyclo|golint|goconst|staticcheck)\)$' \ --exclude='/easyjson\.go.*\((gocyclo|golint|goconst|staticcheck)\)$' \
--exclude='^cdp/.*Potential hardcoded credentials' \ --exclude='^cdp/.*Potential hardcoded credentials' \
--exclude='^cdp/cdp\.go.*UnmarshalEasyJSON.*\(gocyclo\)$' \ --exclude='^cdp/cdp\.go.*UnmarshalEasyJSON.*\(gocyclo\)$' \
@ -24,6 +25,7 @@ gometalinter \
--exclude='^cmd/chromedp-gen/fixup/fixup\.go.*\(goconst\)$' \ --exclude='^cmd/chromedp-gen/fixup/fixup\.go.*\(goconst\)$' \
--exclude='^cmd/chromedp-gen/internal/enum\.go.*unreachable' \ --exclude='^cmd/chromedp-gen/internal/enum\.go.*unreachable' \
--exclude='^cmd/chromedp-gen/(main|domain-gen)\.go.*\(gas\)$' \ --exclude='^cmd/chromedp-gen/(main|domain-gen)\.go.*\(gas\)$' \
--exclude='^examples/upload/main\.go.*\(errcheck\)$' \
--exclude='^kb/gen\.go.*\((gas|vet)\)$' \ --exclude='^kb/gen\.go.*\((gas|vet)\)$' \
--exclude='^runner/.*\(gas\)$' \ --exclude='^runner/.*\(gas\)$' \
--exclude='^handler\.go.*cmd can be easyjson\.Marshaler' \ --exclude='^handler\.go.*cmd can be easyjson\.Marshaler' \

View File

@ -174,36 +174,16 @@ func Value(sel interface{}, value *string, opts ...QueryOption) Action {
panic("value cannot be nil") panic("value cannot be nil")
} }
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return JavascriptAttribute(sel, "value", value, opts...)
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return EvaluateAsDevTools(fmt.Sprintf(valueJS, nodes[0].FullXPath()), value).Do(ctxt, h)
}, opts...)
} }
// SetValue sets the value of an element. // SetValue sets the value of an element.
func SetValue(sel interface{}, value string, opts ...QueryOption) Action { func SetValue(sel interface{}, value string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return SetJavascriptAttribute(sel, "value", value, opts...)
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var res string
err := EvaluateAsDevTools(fmt.Sprintf(setValueJS, nodes[0].FullXPath(), value), &res).Do(ctxt, h)
if err != nil {
return err
}
if res != value {
return fmt.Errorf("could not set value on node %d", nodes[0].NodeID)
}
return nil
}, opts...)
} }
// Attributes retrieves the attributes for the first node matching the selector. // Attributes retrieves the element attributes for the first node matching the
// selector.
func Attributes(sel interface{}, attributes *map[string]string, opts ...QueryOption) Action { func Attributes(sel interface{}, attributes *map[string]string, opts ...QueryOption) Action {
if attributes == nil { if attributes == nil {
panic("attributes cannot be nil") panic("attributes cannot be nil")
@ -229,7 +209,8 @@ func Attributes(sel interface{}, attributes *map[string]string, opts ...QueryOpt
}, opts...) }, opts...)
} }
// SetAttributes sets the attributes for the first node matching the selector. // SetAttributes sets the element attributes for the first node matching the
// selector.
func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryOption) Action { func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error {
if len(nodes) < 1 { if len(nodes) < 1 {
@ -246,8 +227,8 @@ func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryO
}, opts...) }, opts...)
} }
// AttributeValue retrieves the attribute value for the first node matching the // AttributeValue retrieves the element attribute value for the first node
// selector. // matching the selector.
func AttributeValue(sel interface{}, name string, value *string, ok *bool, opts ...QueryOption) Action { func AttributeValue(sel interface{}, name string, value *string, ok *bool, opts ...QueryOption) Action {
if value == nil { if value == nil {
panic("value cannot be nil") panic("value cannot be nil")
@ -280,8 +261,8 @@ func AttributeValue(sel interface{}, name string, value *string, ok *bool, opts
}, opts...) }, opts...)
} }
// SetAttributeValue sets the attribute with name to value on the first node // SetAttributeValue sets the element attribute with name to value for the
// matching the selector. // first node matching the selector.
func SetAttributeValue(sel interface{}, name, value string, opts ...QueryOption) Action { func SetAttributeValue(sel interface{}, name, value string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error {
if len(nodes) < 1 { if len(nodes) < 1 {
@ -292,8 +273,8 @@ func SetAttributeValue(sel interface{}, name, value string, opts ...QueryOption)
}, opts...) }, opts...)
} }
// RemoveAttribute removes the attribute with name from the first node matching // RemoveAttribute removes the element attribute with name from the first node
// the selector. // matching the selector.
func RemoveAttribute(sel interface{}, name string, opts ...QueryOption) Action { func RemoveAttribute(sel interface{}, name string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error {
if len(nodes) < 1 { if len(nodes) < 1 {
@ -304,6 +285,58 @@ func RemoveAttribute(sel interface{}, name string, opts ...QueryOption) Action {
}, opts...) }, opts...)
} }
// JavascriptAttribute retrieves the Javascript attribute for the first node
// matching the selector.
func JavascriptAttribute(sel interface{}, name string, res interface{}, opts ...QueryOption) Action {
if res == nil {
panic("res 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)
}
return EvaluateAsDevTools(fmt.Sprintf(attributeJS, nodes[0].FullXPath(), name), res).Do(ctxt, h)
}, opts...)
}
// SetJavascriptAttribute sets the javascript attribute for the first node
// matching the selector.
func SetJavascriptAttribute(sel interface{}, name, value string, opts ...QueryOption) Action {
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)
}
var res string
err := EvaluateAsDevTools(fmt.Sprintf(setAttributeJS, nodes[0].FullXPath(), name, value), &res).Do(ctxt, h)
if err != nil {
return err
}
if res != value {
return fmt.Errorf("could not set value on node %d", nodes[0].NodeID)
}
return nil
}, opts...)
}
// OuterHTML retrieves the outer html of the first node matching the selector.
func OuterHTML(sel interface{}, html *string, opts ...QueryOption) Action {
if html == nil {
panic("html cannot be nil")
}
return JavascriptAttribute(sel, "outerHTML", html, opts...)
}
// InnerHTML retrieves the inner html of the first node matching the selector.
func InnerHTML(sel interface{}, html *string, opts ...QueryOption) Action {
if html == nil {
panic("html cannot be nil")
}
return JavascriptAttribute(sel, "innerHTML", html, opts...)
}
// Click sends a mouse click event to the first node matching the selector. // Click sends a mouse click event to the first node matching the selector.
func Click(sel interface{}, opts ...QueryOption) Action { func Click(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error { return QueryAfter(sel, func(ctxt context.Context, h cdp.Handler, nodes ...*cdp.Node) error {

View File

@ -910,8 +910,6 @@ func TestFileUpload(t *testing.T) {
for i, test := range tests { for i, test := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) { t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
test = test
c := testAllocate(t, "") c := testAllocate(t, "")
defer c.Release() defer c.Release()

4
sel.go
View File

@ -129,14 +129,14 @@ func (s *Selector) selAsString() string {
} }
// selAsInt forces sel into a int. // selAsInt forces sel into a int.
func (s *Selector) selAsInt() int { /*func (s *Selector) selAsInt() int {
sel, ok := s.sel.(int) sel, ok := s.sel.(int)
if !ok { if !ok {
panic("selector must be int") panic("selector must be int")
} }
return sel return sel
} }*/
// QueryAfter is an action that will match the specified sel using the supplied // QueryAfter is an action that will match the specified sel using the supplied
// query options, and after the visibility conditions of the query have been // query options, and after the visibility conditions of the query have been

20
util.go
View File

@ -80,22 +80,22 @@ const (
return false; return false;
})($x('%s'))` })($x('%s'))`
// valueJS is a javascript snippet that returns the value of a specified // attributeJS is a javascript snippet that returns the attribute of a specified
// node. // node.
valueJS = `(function(a) { attributeJS = `(function(a, n) {
return a[0].value; return a[0][n];
})($x('%s'))`
// setValueJS is a javascript snippet that sets the value of the specified
// node, and returns the value.
setValueJS = `(function(a, val) {
return a[0].value = val;
})($x('%s'), '%s')` })($x('%s'), '%s')`
// setAttributeJS is a javascript snippet that sets the value of the specified
// node, and returns the value.
setAttributeJS = `(function(a, n, v) {
return a[0][n] = v;
})($x('%s'), '%s', '%s')`
// visibleJS is a javascript snippet that returns true or false depending // visibleJS is a javascript snippet that returns true or false depending
// on if the specified node's offsetParent is not null. // on if the specified node's offsetParent is not null.
visibleJS = `(function(a) { visibleJS = `(function(a) {
return a[0].offsetParent !== null return a[0].offsetParent !== null;
})($x('%s'))` })($x('%s'))`
) )