Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit 6efa205

Browse files
committed
Add logs to ExecutionContext
Also add a minor log for BrowserContext as it is somewhat related.
1 parent b11bde2 commit 6efa205

File tree

1 file changed

+78
-39
lines changed

1 file changed

+78
-39
lines changed

common/execution_context.go

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/chromedp/cdproto/cdp"
2929
"github.com/chromedp/cdproto/dom"
3030
"github.com/chromedp/cdproto/runtime"
31+
"github.com/chromedp/cdproto/target"
3132
"github.com/dop251/goja"
3233
"github.com/grafana/xk6-browser/api"
3334
k6common "go.k6.io/k6/js/common"
@@ -52,6 +53,21 @@ func NewExecutionContext(
5253
ctx context.Context, session *Session, frame *Frame,
5354
id runtime.ExecutionContextID, logger *Logger,
5455
) *ExecutionContext {
56+
var (
57+
sid target.SessionID
58+
fid cdp.FrameID
59+
furl string
60+
)
61+
if session != nil {
62+
sid = session.id
63+
}
64+
if frame != nil {
65+
fid = frame.id
66+
furl = frame.url
67+
}
68+
logger.Debugf("NewExecutionContext", "sid:%s fid:%s ecid:%d furl:%q",
69+
sid, fid, id, furl)
70+
5571
return &ExecutionContext{
5672
ctx: ctx,
5773
session: session,
@@ -64,21 +80,31 @@ func NewExecutionContext(
6480

6581
// Adopts specified backend node into this execution context from another execution context
6682
func (e *ExecutionContext) adoptBackendNodeId(backendNodeID cdp.BackendNodeID) (*ElementHandle, error) {
67-
var remoteObj *runtime.RemoteObject
68-
var err error
83+
e.logger.Debugf("ExecutionContext:adoptBackendNodeId", "sid:%s tid:%s fid:%s ecid:%d furl:%q bnid:%d",
84+
e.session.id, e.session.targetID, e.frame.id, e.id, e.frame.url, backendNodeID)
85+
86+
var (
87+
remoteObj *runtime.RemoteObject
88+
err error
89+
)
6990

7091
action := dom.ResolveNode().
7192
WithBackendNodeID(backendNodeID).
7293
WithExecutionContextID(e.id)
94+
7395
if remoteObj, err = action.Do(cdp.WithExecutor(e.ctx, e.session)); err != nil {
74-
return nil, fmt.Errorf("unable to get DOM node: %w", err)
96+
return nil, fmt.Errorf("cannot resolve dom node: %w", err)
7597
}
7698

7799
return NewJSHandle(e.ctx, e.session, e, e.frame, remoteObj, e.logger).AsElement().(*ElementHandle), nil
78100
}
79101

80102
// Adopts the specified element handle into this execution context from another execution context
81103
func (e *ExecutionContext) adoptElementHandle(elementHandle *ElementHandle) (*ElementHandle, error) {
104+
e.logger.Debugf("ExecutionContext:adoptElementHandle", "sid:%s tid:%s fid:%s ecid:%d furl:%q ehfid:%s ehsid:%s",
105+
e.session.id, e.session.targetID, e.frame.id, e.id, e.frame.url,
106+
elementHandle.frame.id, elementHandle.session.id)
107+
82108
if elementHandle.execCtx == e {
83109
panic("Cannot adopt handle that already belongs to this execution context")
84110
}
@@ -91,95 +117,108 @@ func (e *ExecutionContext) adoptElementHandle(elementHandle *ElementHandle) (*El
91117

92118
action := dom.DescribeNode().WithObjectID(elementHandle.remoteObject.ObjectID)
93119
if node, err = action.Do(cdp.WithExecutor(e.ctx, e.session)); err != nil {
94-
return nil, fmt.Errorf("unable to get DOM node: %w", err)
120+
return nil, fmt.Errorf("cannot describe dom node: %w", err)
95121
}
96122

97123
return e.adoptBackendNodeId(node.BackendNodeID)
98124
}
99125

100126
// evaluate will evaluate provided callable within this execution context and return by value or handle
101127
func (e *ExecutionContext) evaluate(apiCtx context.Context, forceCallable bool, returnByValue bool, pageFunc goja.Value, args ...goja.Value) (res interface{}, err error) {
128+
e.logger.Debugf("ExecutionContext:evaluate", "sid:%s tid:%s fid:%s ecid:%d furl:%q",
129+
e.session.id, e.session.targetID, e.frame.id, e.id, e.frame.url)
130+
102131
suffix := `//# sourceURL=` + evaluationScriptURL
103132

104-
isCallable := forceCallable
133+
var (
134+
isCallable = forceCallable
135+
expression = pageFunc.ToString().String()
136+
)
105137
if !forceCallable {
106-
_, isCallable = goja.AssertFunction(pageFunc.(goja.Value))
138+
_, isCallable = goja.AssertFunction(pageFunc)
107139
}
108-
109140
if !isCallable {
110-
expression := pageFunc.ToString().String()
111141
expressionWithSourceURL := expression
112142
if !sourceURLRegex.Match([]byte(expression)) {
113143
expressionWithSourceURL = expression + "\n" + suffix
114144
}
115145

116-
var remoteObject *runtime.RemoteObject
117-
var exceptionDetails *runtime.ExceptionDetails
146+
var (
147+
remoteObject *runtime.RemoteObject
148+
exceptionDetails *runtime.ExceptionDetails
149+
)
118150
action := runtime.Evaluate(expressionWithSourceURL).
119151
WithContextID(e.id).
120152
WithReturnByValue(returnByValue).
121153
WithAwaitPromise(true).
122154
WithUserGesture(true)
123155
if remoteObject, exceptionDetails, err = action.Do(cdp.WithExecutor(apiCtx, e.session)); err != nil {
124-
return nil, fmt.Errorf("unable to evaluate expression: %w", err)
156+
return nil, fmt.Errorf("cannot evaluate expression (%s): %w", expressionWithSourceURL, exceptionDetails)
125157
}
126158
if exceptionDetails != nil {
127-
return nil, fmt.Errorf("unable to evaluate expression: %w", exceptionDetails)
159+
return nil, fmt.Errorf("cannot evaluate expression (%s): %w", expressionWithSourceURL, exceptionDetails)
128160
}
129-
if remoteObject != nil {
130-
if returnByValue {
131-
res, err = valueFromRemoteObject(apiCtx, remoteObject)
132-
if err != nil {
133-
return nil, fmt.Errorf("unable to extract value from remote object: %w", err)
134-
}
135-
} else if remoteObject.ObjectID != "" {
136-
// Note: we don't use the passed in apiCtx here as it could be tied to a timeout
137-
res = NewJSHandle(e.ctx, e.session, e, e.frame, remoteObject, e.logger)
161+
if remoteObject == nil {
162+
return
163+
}
164+
if returnByValue {
165+
res, err = valueFromRemoteObject(apiCtx, remoteObject)
166+
if err != nil {
167+
return nil, fmt.Errorf("cannot extract value from remote object (%s): %w", remoteObject.ObjectID, err)
138168
}
169+
} else if remoteObject.ObjectID != "" {
170+
// Note: we don't use the passed in apiCtx here as it could be tied to a timeout
171+
res = NewJSHandle(e.ctx, e.session, e, e.frame, remoteObject, e.logger)
139172
}
140173
} else {
141-
functionText := pageFunc.ToString().String()
142174
var arguments []*runtime.CallArgument
143175
for _, arg := range args {
144176
result, err := convertArgument(apiCtx, e, arg)
145177
if err != nil {
146-
return nil, fmt.Errorf("unable to convert argument: %w", err)
178+
return nil, fmt.Errorf("cannot convert argument (%q): %w", arg, err)
147179
}
148180
arguments = append(arguments, result)
149181
}
150182

151-
var remoteObject *runtime.RemoteObject
152-
var exceptionDetails *runtime.ExceptionDetails
153-
action := runtime.CallFunctionOn(functionText + "\n" + suffix + "\n").
183+
var (
184+
remoteObject *runtime.RemoteObject
185+
exceptionDetails *runtime.ExceptionDetails
186+
functionOn = expression + "\n" + suffix + "\n"
187+
)
188+
action := runtime.CallFunctionOn(functionOn).
154189
WithArguments(arguments).
155190
WithExecutionContextID(e.id).
156191
WithReturnByValue(returnByValue).
157192
WithAwaitPromise(true).
158193
WithUserGesture(true)
159194
if remoteObject, exceptionDetails, err = action.Do(cdp.WithExecutor(apiCtx, e.session)); err != nil {
160-
return nil, fmt.Errorf("unable to evaluate expression: %w", err)
195+
return nil, fmt.Errorf("cannot call function on expression (%q) in execution context (%d): %w", functionOn, e.id, err)
161196
}
162197
if exceptionDetails != nil {
163-
return nil, fmt.Errorf("unable to evaluate expression: %w", exceptionDetails)
198+
return nil, fmt.Errorf("cannot call function on expression (%q) in execution context (%d): %w", functionOn, e.id, err)
164199
}
165-
if remoteObject != nil {
166-
if returnByValue {
167-
res, err = valueFromRemoteObject(apiCtx, remoteObject)
168-
if err != nil {
169-
return nil, fmt.Errorf("unable to extract value from remote object: %w", err)
170-
}
171-
} else if remoteObject.ObjectID != "" {
172-
// Note: we don't use the passed in apiCtx here as it could be tied to a timeout
173-
res = NewJSHandle(e.ctx, e.session, e, e.frame, remoteObject, e.logger)
200+
if remoteObject == nil {
201+
return
202+
}
203+
if returnByValue {
204+
res, err = valueFromRemoteObject(apiCtx, remoteObject)
205+
if err != nil {
206+
return nil, fmt.Errorf("cannot extract value from remote object (%s): %w", remoteObject.ObjectID, err)
174207
}
208+
} else if remoteObject.ObjectID != "" {
209+
// Note: we don't use the passed in apiCtx here as it could be tied to a timeout
210+
res = NewJSHandle(e.ctx, e.session, e, e.frame, remoteObject, e.logger)
175211
}
176212
}
177213

178-
return res, err
214+
return res, nil
179215
}
180216

181217
// getInjectedScript returns a JS handle to the injected script of helper functions
182218
func (e *ExecutionContext) getInjectedScript(apiCtx context.Context) (api.JSHandle, error) {
219+
e.logger.Debugf("ExecutionContext:getInjectedScript", "sid:%s tid:%s fid:%s ecid:%d furl:%q",
220+
e.session.id, e.session.targetID, e.frame.id, e.id, e.frame.url)
221+
183222
if e.injectedScript == nil {
184223
rt := k6common.GetRuntime(e.ctx)
185224
suffix := `//# sourceURL=` + evaluationScriptURL
@@ -192,7 +231,7 @@ func (e *ExecutionContext) getInjectedScript(apiCtx context.Context) (api.JSHand
192231

193232
handle, err := e.evaluate(apiCtx, false, false, rt.ToValue(expressionWithSourceURL))
194233
if handle == nil || err != nil {
195-
return nil, err
234+
return nil, fmt.Errorf("cannot get injected script (%q): %w", suffix, err)
196235
}
197236
e.injectedScript = handle.(api.JSHandle)
198237
}

0 commit comments

Comments
 (0)