use consistent context.Context var names

This commit is contained in:
Daniel Martí 2019-03-20 12:08:50 +00:00
parent 61f0a8da68
commit c109f6ebfd
7 changed files with 116 additions and 116 deletions

View File

@ -18,8 +18,8 @@ type Action interface {
type ActionFunc func(context.Context, cdp.Executor) error
// Do executes the func f using the provided context and frame handler.
func (f ActionFunc) Do(ctxt context.Context, h cdp.Executor) error {
return f(ctxt, h)
func (f ActionFunc) Do(ctx context.Context, h cdp.Executor) error {
return f(ctx, h)
}
// Tasks is a sequential list of Actions that can be used as a single Action.
@ -27,12 +27,12 @@ type Tasks []Action
// Do executes the list of Actions sequentially, using the provided context and
// frame handler.
func (t Tasks) Do(ctxt context.Context, h cdp.Executor) error {
func (t Tasks) Do(ctx context.Context, h cdp.Executor) error {
// TODO: put individual task timeouts from context here
for _, a := range t {
// ctxt, cancel = context.WithTimeout(ctxt, timeout)
// ctx, cancel = context.WithTimeout(ctx, timeout)
// defer cancel()
if err := a.Do(ctxt, h); err != nil {
if err := a.Do(ctx, h); err != nil {
return err
}
}
@ -46,11 +46,11 @@ func (t Tasks) Do(ctxt context.Context, h cdp.Executor) error {
// be marked for deprecation in the future, after the remaining Actions have
// been able to be written/tested.
func Sleep(d time.Duration) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
select {
case <-time.After(d):
case <-ctxt.Done():
return ctxt.Err()
case <-ctx.Done():
return ctx.Err()
}
return nil
})

View File

@ -27,7 +27,7 @@ func Evaluate(expression string, res interface{}, opts ...EvaluateOption) Action
panic("res cannot be nil")
}
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
// set up parameters
p := runtime.Evaluate(expression)
switch res.(type) {
@ -42,7 +42,7 @@ func Evaluate(expression string, res interface{}, opts ...EvaluateOption) Action
}
// evaluate
v, exp, err := p.Do(ctxt, h)
v, exp, err := p.Do(ctx, h)
if err != nil {
return err
}

View File

@ -127,7 +127,7 @@ func (t *Target) Execute(ctx context.Context, method string, params json.Marshal
// below are the old TargetHandler methods.
// processEvent processes an incoming event.
func (t *Target) processEvent(ctxt context.Context, msg *cdproto.Message) error {
func (t *Target) processEvent(ctx context.Context, msg *cdproto.Message) error {
if msg == nil {
return ErrChannelClosed
}
@ -151,7 +151,7 @@ func (t *Target) processEvent(ctxt context.Context, msg *cdproto.Message) error
case *inspector.EventDetached:
return nil
case *dom.EventDocumentUpdated:
t.documentUpdated(ctxt)
t.documentUpdated(ctx)
return nil
}
@ -166,7 +166,7 @@ func (t *Target) processEvent(ctxt context.Context, msg *cdproto.Message) error
// documentUpdated handles the document updated event, retrieving the document
// root for the root frame.
func (t *Target) documentUpdated(ctxt context.Context) {
func (t *Target) documentUpdated(ctx context.Context) {
f := t.cur
f.Lock()
defer f.Unlock()
@ -178,7 +178,7 @@ func (t *Target) documentUpdated(ctxt context.Context) {
f.Nodes = make(map[cdp.NodeID]*cdp.Node)
var err error
f.Root, err = dom.GetDocument().WithPierce(true).Do(ctxt, t)
f.Root, err = dom.GetDocument().WithPierce(true).Do(ctx, t)
if err == context.Canceled {
return // TODO: perhaps not necessary, but useful to keep the tests less noisy
}

View File

@ -27,7 +27,7 @@ func MouseAction(typ input.MouseType, x, y int64, opts ...MouseOption) Action {
// MouseClickXY sends a left mouse button click (ie, mousePressed and
// mouseReleased event) at the X, Y location.
func MouseClickXY(x, y int64, opts ...MouseOption) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
me := &input.DispatchMouseEventParams{
Type: input.MousePressed,
X: float64(x),
@ -41,13 +41,13 @@ func MouseClickXY(x, y int64, opts ...MouseOption) Action {
me = o(me)
}
err := me.Do(ctxt, h)
err := me.Do(ctx, h)
if err != nil {
return err
}
me.Type = input.MouseReleased
return me.Do(ctxt, h)
return me.Do(ctx, h)
})
}
@ -57,14 +57,14 @@ func MouseClickXY(x, y int64, opts ...MouseOption) Action {
// Note that the window will be scrolled if the node is not within the window's
// viewport.
func MouseClickNode(n *cdp.Node, opts ...MouseOption) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
var pos []int
err := EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, n.FullXPath()), &pos).Do(ctxt, h)
err := EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, n.FullXPath()), &pos).Do(ctx, h)
if err != nil {
return err
}
box, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctxt, h)
box, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctx, h)
if err != nil {
return err
}
@ -82,7 +82,7 @@ func MouseClickNode(n *cdp.Node, opts ...MouseOption) Action {
x /= int64(c / 2)
y /= int64(c / 2)
return MouseClickXY(x, y, opts...).Do(ctxt, h)
return MouseClickXY(x, y, opts...).Do(ctx, h)
})
}
@ -151,10 +151,10 @@ func ClickCount(n int) MouseOption {
// Please see the chromedp/kb package for implementation details and the list
// of well-known keys.
func KeyAction(keys string, opts ...KeyOption) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
for _, r := range keys {
for _, k := range kb.Encode(r) {
if err := k.Do(ctxt, h); err != nil {
if err := k.Do(ctx, h); err != nil {
return err
}
}
@ -169,13 +169,13 @@ func KeyAction(keys string, opts ...KeyOption) Action {
// KeyActionNode dispatches a key event on a node.
func KeyActionNode(n *cdp.Node, keys string, opts ...KeyOption) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
err := dom.Focus().WithNodeID(n.NodeID).Do(ctxt, h)
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
err := dom.Focus().WithNodeID(n.NodeID).Do(ctx, h)
if err != nil {
return err
}
return KeyAction(keys, opts...).Do(ctxt, h)
return KeyAction(keys, opts...).Do(ctx, h)
})
}

28
nav.go
View File

@ -10,8 +10,8 @@ import (
// Navigate navigates the current frame.
func Navigate(urlstr string) Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
_, _, _, err := page.Navigate(urlstr).Do(ctxt, h)
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
_, _, _, err := page.Navigate(urlstr).Do(ctx, h)
return err
})
}
@ -23,9 +23,9 @@ func NavigationEntries(currentIndex *int64, entries *[]*page.NavigationEntry) Ac
panic("currentIndex and entries cannot be nil")
}
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
var err error
*currentIndex, *entries, err = page.GetNavigationHistory().Do(ctxt, h)
*currentIndex, *entries, err = page.GetNavigationHistory().Do(ctx, h)
return err
})
}
@ -38,8 +38,8 @@ func NavigateToHistoryEntry(entryID int64) Action {
// NavigateBack navigates the current frame backwards in its history.
func NavigateBack() Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
cur, entries, err := page.GetNavigationHistory().Do(ctxt, h)
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
cur, entries, err := page.GetNavigationHistory().Do(ctx, h)
if err != nil {
return err
}
@ -48,14 +48,14 @@ func NavigateBack() Action {
return errors.New("invalid navigation entry")
}
return page.NavigateToHistoryEntry(entries[cur-1].ID).Do(ctxt, h)
return page.NavigateToHistoryEntry(entries[cur-1].ID).Do(ctx, h)
})
}
// NavigateForward navigates the current frame forwards in its history.
func NavigateForward() Action {
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
cur, entries, err := page.GetNavigationHistory().Do(ctxt, h)
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
cur, entries, err := page.GetNavigationHistory().Do(ctx, h)
if err != nil {
return err
}
@ -64,7 +64,7 @@ func NavigateForward() Action {
return errors.New("invalid navigation entry")
}
return page.NavigateToHistoryEntry(entries[cur+1].ID).Do(ctxt, h)
return page.NavigateToHistoryEntry(entries[cur+1].ID).Do(ctx, h)
})
}
@ -86,9 +86,9 @@ func CaptureScreenshot(res *[]byte) Action {
panic("res cannot be nil")
}
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
var err error
*res, err = page.CaptureScreenshot().Do(ctxt, h)
*res, err = page.CaptureScreenshot().Do(ctx, h)
return err
})
}
@ -99,9 +99,9 @@ func CaptureScreenshot(res *[]byte) Action {
panic("id cannot be nil")
}
return ActionFunc(func(ctxt context.Context, h cdp.Executor) error {
return ActionFunc(func(ctx context.Context, h cdp.Executor) error {
var err error
*id, err = page.AddScriptToEvaluateOnLoad(source).Do(ctxt, h)
*id, err = page.AddScriptToEvaluateOnLoad(source).Do(ctx, h)
return err
})
}

View File

@ -25,7 +25,7 @@ func Nodes(sel interface{}, nodes *[]*cdp.Node, opts ...QueryOption) Action {
panic("nodes cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, n ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, n ...*cdp.Node) error {
*nodes = n
return nil
}, opts...)
@ -37,7 +37,7 @@ func NodeIDs(sel interface{}, ids *[]cdp.NodeID, opts ...QueryOption) Action {
panic("nodes cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
nodeIDs := make([]cdp.NodeID, len(nodes))
for i, n := range nodes {
nodeIDs[i] = n.NodeID
@ -51,24 +51,24 @@ func NodeIDs(sel interface{}, ids *[]cdp.NodeID, opts ...QueryOption) Action {
// Focus focuses the first node matching the selector.
func Focus(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return dom.Focus().WithNodeID(nodes[0].NodeID).Do(ctxt, h)
return dom.Focus().WithNodeID(nodes[0].NodeID).Do(ctx, h)
}, opts...)
}
// Blur unfocuses (blurs) the first node matching the selector.
func Blur(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var res bool
err := EvaluateAsDevTools(fmt.Sprintf(blurJS, nodes[0].FullXPath()), &res).Do(ctxt, h)
err := EvaluateAsDevTools(fmt.Sprintf(blurJS, nodes[0].FullXPath()), &res).Do(ctx, h)
if err != nil {
return err
}
@ -87,12 +87,12 @@ func Dimensions(sel interface{}, model **dom.BoxModel, opts ...QueryOption) Acti
if model == nil {
panic("model cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var err error
*model, err = dom.GetBoxModel().WithNodeID(nodes[0].NodeID).Do(ctxt, h)
*model, err = dom.GetBoxModel().WithNodeID(nodes[0].NodeID).Do(ctx, h)
return err
}, opts...)
}
@ -103,18 +103,18 @@ func Text(sel interface{}, text *string, opts ...QueryOption) Action {
panic("text cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return EvaluateAsDevTools(fmt.Sprintf(textJS, nodes[0].FullXPath()), text).Do(ctxt, h)
return EvaluateAsDevTools(fmt.Sprintf(textJS, nodes[0].FullXPath()), text).Do(ctx, h)
}, opts...)
}
// Clear clears the values of any input/textarea nodes matching the selector.
func Clear(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
@ -154,7 +154,7 @@ func Clear(sel interface{}, opts ...QueryOption) Action {
a = dom.SetNodeValue(textID, "")
}
errs[i] = a.Do(ctxt, h)
errs[i] = a.Do(ctx, h)
}(i, n)
}
wg.Wait()
@ -190,7 +190,7 @@ func Attributes(sel interface{}, attributes *map[string]string, opts ...QueryOpt
panic("attributes cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
@ -219,7 +219,7 @@ func AttributesAll(sel interface{}, attributes *[]map[string]string, opts ...Que
panic("attributes cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
@ -243,7 +243,7 @@ func AttributesAll(sel interface{}, attributes *[]map[string]string, opts ...Que
// SetAttributes sets the element attributes for the first node matching the
// selector.
func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return errors.New("expected at least one element")
}
@ -254,7 +254,7 @@ func SetAttributes(sel interface{}, attributes map[string]string, opts ...QueryO
i++
}
return dom.SetAttributesAsText(nodes[0].NodeID, strings.Join(attrs, " ")).Do(ctxt, h)
return dom.SetAttributesAsText(nodes[0].NodeID, strings.Join(attrs, " ")).Do(ctx, h)
}, opts...)
}
@ -265,7 +265,7 @@ func AttributeValue(sel interface{}, name string, value *string, ok *bool, opts
panic("value cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return errors.New("expected at least one element")
}
@ -295,24 +295,24 @@ func AttributeValue(sel interface{}, name string, value *string, ok *bool, opts
// SetAttributeValue sets the element attribute with name to value for the
// first node matching the selector.
func SetAttributeValue(sel interface{}, name, value string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return dom.SetAttributeValue(nodes[0].NodeID, name, value).Do(ctxt, h)
return dom.SetAttributeValue(nodes[0].NodeID, name, value).Do(ctx, h)
}, opts...)
}
// RemoveAttribute removes the element attribute with name from the first node
// matching the selector.
func RemoveAttribute(sel interface{}, name string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return dom.RemoveAttribute(nodes[0].NodeID, name).Do(ctxt, h)
return dom.RemoveAttribute(nodes[0].NodeID, name).Do(ctx, h)
}, opts...)
}
@ -322,25 +322,25 @@ func JavascriptAttribute(sel interface{}, name string, res interface{}, opts ...
if res == nil {
panic("res cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, 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)
return EvaluateAsDevTools(fmt.Sprintf(attributeJS, nodes[0].FullXPath(), name), res).Do(ctx, 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 *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, 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)
err := EvaluateAsDevTools(fmt.Sprintf(setAttributeJS, nodes[0].FullXPath(), name, value), &res).Do(ctx, h)
if err != nil {
return err
}
@ -370,24 +370,24 @@ func InnerHTML(sel interface{}, html *string, opts ...QueryOption) Action {
// Click sends a mouse click event to the first node matching the selector.
func Click(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return MouseClickNode(nodes[0]).Do(ctxt, h)
return MouseClickNode(nodes[0]).Do(ctx, h)
}, append(opts, NodeVisible)...)
}
// DoubleClick sends a mouse double click event to the first node matching the
// selector.
func DoubleClick(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return MouseClickNode(nodes[0], ClickCount(2)).Do(ctxt, h)
return MouseClickNode(nodes[0], ClickCount(2)).Do(ctx, h)
}, append(opts, NodeVisible)...)
}
@ -397,7 +397,7 @@ func DoubleClick(sel interface{}, opts ...QueryOption) Action {
// Note: when selector matches a input[type="file"] node, then dom.SetFileInputFiles
// is used to set the upload path of the input node to v.
func SendKeys(sel interface{}, v string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
@ -416,22 +416,22 @@ func SendKeys(sel interface{}, v string, opts ...QueryOption) Action {
// when working with input[type="file"], call dom.SetFileInputFiles
if n.NodeName == "INPUT" && typ == "file" {
return dom.SetFileInputFiles([]string{v}).WithNodeID(n.NodeID).Do(ctxt, h)
return dom.SetFileInputFiles([]string{v}).WithNodeID(n.NodeID).Do(ctx, h)
}
return KeyActionNode(n, v).Do(ctxt, h)
return KeyActionNode(n, v).Do(ctx, h)
}, append(opts, NodeVisible)...)
}
// SetUploadFiles sets the files to upload (ie, for a input[type="file"] node)
// for the first node matching the selector.
func SetUploadFiles(sel interface{}, files []string, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
return dom.SetFileInputFiles(files).WithNodeID(nodes[0].NodeID).Do(ctxt, h)
return dom.SetFileInputFiles(files).WithNodeID(nodes[0].NodeID).Do(ctx, h)
}, opts...)
}
@ -441,13 +441,13 @@ func Screenshot(sel interface{}, picbuf *[]byte, opts ...QueryOption) Action {
panic("picbuf cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
// get box model
box, err := dom.GetBoxModel().WithNodeID(nodes[0].NodeID).Do(ctxt, h)
box, err := dom.GetBoxModel().WithNodeID(nodes[0].NodeID).Do(ctx, h)
if err != nil {
return err
}
@ -459,13 +459,13 @@ func Screenshot(sel interface{}, picbuf *[]byte, opts ...QueryOption) Action {
// scroll to node position
var pos []int
err = EvaluateAsDevTools(fmt.Sprintf(scrollJS, int64(box.Margin[0]), int64(box.Margin[1])), &pos).Do(ctxt, h)
err = EvaluateAsDevTools(fmt.Sprintf(scrollJS, int64(box.Margin[0]), int64(box.Margin[1])), &pos).Do(ctx, h)
if err != nil {
return err
}
// take page screenshot
buf, err := page.CaptureScreenshot().Do(ctxt, h)
buf, err := page.CaptureScreenshot().Do(ctx, h)
if err != nil {
return err
}
@ -497,13 +497,13 @@ func Screenshot(sel interface{}, picbuf *[]byte, opts ...QueryOption) Action {
// Submit is an action that submits the form of the first node matching the
// selector belongs to.
func Submit(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var res bool
err := EvaluateAsDevTools(fmt.Sprintf(submitJS, nodes[0].FullXPath()), &res).Do(ctxt, h)
err := EvaluateAsDevTools(fmt.Sprintf(submitJS, nodes[0].FullXPath()), &res).Do(ctx, h)
if err != nil {
return err
}
@ -519,13 +519,13 @@ func Submit(sel interface{}, opts ...QueryOption) Action {
// Reset is an action that resets the form of the first node matching the
// selector belongs to.
func Reset(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var res bool
err := EvaluateAsDevTools(fmt.Sprintf(resetJS, nodes[0].FullXPath()), &res).Do(ctxt, h)
err := EvaluateAsDevTools(fmt.Sprintf(resetJS, nodes[0].FullXPath()), &res).Do(ctx, h)
if err != nil {
return err
}
@ -544,12 +544,12 @@ func ComputedStyle(sel interface{}, style *[]*css.ComputedProperty, opts ...Quer
panic("style cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
computed, err := css.GetComputedStyleForNode(nodes[0].NodeID).Do(ctxt, h)
computed, err := css.GetComputedStyleForNode(nodes[0].NodeID).Do(ctx, h)
if err != nil {
return err
}
@ -567,7 +567,7 @@ func MatchedStyle(sel interface{}, style **css.GetMatchedStylesForNodeReturns, o
panic("style cannot be nil")
}
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
@ -576,7 +576,7 @@ func MatchedStyle(sel interface{}, style **css.GetMatchedStylesForNodeReturns, o
ret := &css.GetMatchedStylesForNodeReturns{}
ret.InlineStyle, ret.AttributesStyle, ret.MatchedCSSRules,
ret.PseudoElements, ret.Inherited, ret.CSSKeyframesRules,
err = css.GetMatchedStylesForNode(nodes[0].NodeID).Do(ctxt, h)
err = css.GetMatchedStylesForNode(nodes[0].NodeID).Do(ctx, h)
if err != nil {
return err
}
@ -589,13 +589,13 @@ func MatchedStyle(sel interface{}, style **css.GetMatchedStylesForNodeReturns, o
// ScrollIntoView scrolls the window to the first node matching the selector.
func ScrollIntoView(sel interface{}, opts ...QueryOption) Action {
return QueryAfter(sel, func(ctxt context.Context, h *Target, nodes ...*cdp.Node) error {
return QueryAfter(sel, func(ctx context.Context, h *Target, nodes ...*cdp.Node) error {
if len(nodes) < 1 {
return fmt.Errorf("selector `%s` did not return any nodes", sel)
}
var pos []int
err := EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, nodes[0].FullXPath()), &pos).Do(ctxt, h)
err := EvaluateAsDevTools(fmt.Sprintf(scrollIntoViewJS, nodes[0].FullXPath()), &pos).Do(ctx, h)
if err != nil {
return err
}

56
sel.go
View File

@ -55,7 +55,7 @@ func Query(sel interface{}, opts ...QueryOption) Action {
}
// Do satisfies the Action interface.
func (s *Selector) Do(ctxt context.Context, h cdp.Executor) error {
func (s *Selector) Do(ctx context.Context, h cdp.Executor) error {
th, ok := h.(*Target)
if !ok {
return ErrInvalidHandler
@ -63,9 +63,9 @@ func (s *Selector) Do(ctxt context.Context, h cdp.Executor) error {
var err error
select {
case err = <-s.run(ctxt, th):
case <-ctxt.Done():
err = ctxt.Err()
case err = <-s.run(ctx, th):
case <-ctx.Done():
err = ctx.Err()
}
return err
@ -74,7 +74,7 @@ func (s *Selector) Do(ctxt context.Context, h cdp.Executor) error {
// run runs the selector action, starting over if the original returned nodes
// are invalidated prior to finishing the selector's by, wait, check, and after
// funcs.
func (s *Selector) run(ctxt context.Context, h *Target) chan error {
func (s *Selector) run(ctx context.Context, h *Target) chan error {
ch := make(chan error, 1)
h.waitQueue <- func(cur *cdp.Frame) bool {
cur.RLock()
@ -86,17 +86,17 @@ func (s *Selector) run(ctxt context.Context, h *Target) chan error {
return false
}
ids, err := s.by(ctxt, h, root)
ids, err := s.by(ctx, h, root)
if err != nil || len(ids) < s.exp {
return false
}
nodes, err := s.wait(ctxt, h, cur, ids...)
nodes, err := s.wait(ctx, h, cur, ids...)
// if nodes==nil, we're not yet ready
if nodes == nil || err != nil {
return false
}
if s.after != nil {
if err := s.after(ctxt, h, nodes...); err != nil {
if err := s.after(ctx, h, nodes...); err != nil {
ch <- err
}
}
@ -135,8 +135,8 @@ func ByFunc(f func(context.Context, *Target, *cdp.Node) ([]cdp.NodeID, error)) Q
// ByQuery is a query option to select a single element using
// DOM.querySelector.
func ByQuery(s *Selector) {
ByFunc(func(ctxt context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
nodeID, err := dom.QuerySelector(n.NodeID, s.selAsString()).Do(ctxt, h)
ByFunc(func(ctx context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
nodeID, err := dom.QuerySelector(n.NodeID, s.selAsString()).Do(ctx, h)
if err != nil {
return nil, err
}
@ -151,8 +151,8 @@ func ByQuery(s *Selector) {
// ByQueryAll is a query option to select elements by DOM.querySelectorAll.
func ByQueryAll(s *Selector) {
ByFunc(func(ctxt context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
return dom.QuerySelectorAll(n.NodeID, s.selAsString()).Do(ctxt, h)
ByFunc(func(ctx context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
return dom.QuerySelectorAll(n.NodeID, s.selAsString()).Do(ctx, h)
})(s)
}
@ -165,8 +165,8 @@ func ByID(s *Selector) {
// BySearch is a query option via DOM.performSearch (works with both CSS and
// XPath queries).
func BySearch(s *Selector) {
ByFunc(func(ctxt context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
id, count, err := dom.PerformSearch(s.selAsString()).Do(ctxt, h)
ByFunc(func(ctx context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
id, count, err := dom.PerformSearch(s.selAsString()).Do(ctx, h)
if err != nil {
return nil, err
}
@ -175,7 +175,7 @@ func BySearch(s *Selector) {
return []cdp.NodeID{}, nil
}
nodes, err := dom.GetSearchResults(id, 0, count).Do(ctxt, h)
nodes, err := dom.GetSearchResults(id, 0, count).Do(ctx, h)
if err != nil {
return nil, err
}
@ -191,9 +191,9 @@ func ByNodeID(s *Selector) {
panic("ByNodeID can only work on []cdp.NodeID")
}
ByFunc(func(ctxt context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
ByFunc(func(ctx context.Context, h *Target, n *cdp.Node) ([]cdp.NodeID, error) {
for _, id := range ids {
err := dom.RequestChildNodes(id).WithPierce(true).Do(ctxt, h)
err := dom.RequestChildNodes(id).WithPierce(true).Do(ctx, h)
if err != nil {
return nil, err
}
@ -205,7 +205,7 @@ func ByNodeID(s *Selector) {
// waitReady waits for the specified nodes to be ready.
func (s *Selector) waitReady(check func(context.Context, *Target, *cdp.Node) error) func(context.Context, *Target, *cdp.Frame, ...cdp.NodeID) ([]*cdp.Node, error) {
return func(ctxt context.Context, h *Target, cur *cdp.Frame, ids ...cdp.NodeID) ([]*cdp.Node, error) {
return func(ctx context.Context, h *Target, cur *cdp.Frame, ids ...cdp.NodeID) ([]*cdp.Node, error) {
nodes := make([]*cdp.Node, len(ids))
cur.RLock()
for i, id := range ids {
@ -225,7 +225,7 @@ func (s *Selector) waitReady(check func(context.Context, *Target, *cdp.Node) err
wg.Add(1)
go func(i int, n *cdp.Node) {
defer wg.Done()
errs[i] = check(ctxt, h, n)
errs[i] = check(ctx, h, n)
}(i, n)
}
wg.Wait()
@ -255,9 +255,9 @@ func NodeReady(s *Selector) {
// NodeVisible is a query option to wait until the element is visible.
func NodeVisible(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h *Target, n *cdp.Node) error {
WaitFunc(s.waitReady(func(ctx context.Context, h *Target, n *cdp.Node) error {
// check box model
_, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctxt, h)
_, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctx, h)
if err != nil {
if isCouldNotComputeBoxModelError(err) {
return ErrNotVisible
@ -268,7 +268,7 @@ func NodeVisible(s *Selector) {
// check offsetParent
var res bool
err = EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctxt, h)
err = EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctx, h)
if err != nil {
return err
}
@ -281,9 +281,9 @@ func NodeVisible(s *Selector) {
// NodeNotVisible is a query option to wait until the element is not visible.
func NodeNotVisible(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h *Target, n *cdp.Node) error {
WaitFunc(s.waitReady(func(ctx context.Context, h *Target, n *cdp.Node) error {
// check box model
_, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctxt, h)
_, err := dom.GetBoxModel().WithNodeID(n.NodeID).Do(ctx, h)
if err != nil {
if isCouldNotComputeBoxModelError(err) {
return nil
@ -294,7 +294,7 @@ func NodeNotVisible(s *Selector) {
// check offsetParent
var res bool
err = EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctxt, h)
err = EvaluateAsDevTools(fmt.Sprintf(visibleJS, n.FullXPath()), &res).Do(ctx, h)
if err != nil {
return err
}
@ -307,7 +307,7 @@ func NodeNotVisible(s *Selector) {
// NodeEnabled is a query option to wait until the element is enabled.
func NodeEnabled(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h *Target, n *cdp.Node) error {
WaitFunc(s.waitReady(func(ctx context.Context, h *Target, n *cdp.Node) error {
n.RLock()
defer n.RUnlock()
@ -323,7 +323,7 @@ func NodeEnabled(s *Selector) {
// NodeSelected is a query option to wait until the element is selected.
func NodeSelected(s *Selector) {
WaitFunc(s.waitReady(func(ctxt context.Context, h *Target, n *cdp.Node) error {
WaitFunc(s.waitReady(func(ctx context.Context, h *Target, n *cdp.Node) error {
n.RLock()
defer n.RUnlock()
@ -341,7 +341,7 @@ func NodeSelected(s *Selector) {
// matching the selector.
func NodeNotPresent(s *Selector) {
s.exp = 0
WaitFunc(func(ctxt context.Context, h *Target, cur *cdp.Frame, ids ...cdp.NodeID) ([]*cdp.Node, error) {
WaitFunc(func(ctx context.Context, h *Target, cur *cdp.Frame, ids ...cdp.NodeID) ([]*cdp.Node, error) {
if len(ids) != 0 {
return nil, ErrHasResults
}