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

Commit bc90dd1

Browse files
committed
Add a new EvaluateWithContext
This new EvaluateWithContext will allow us to pass in a context with a timeout. For issue #971, we're seeing that often the evaluate to hide the page on page.close ends up in a deadlock (waiting for the response from the chrome browser after executing the CDP evaluate command). We are not sure of the root cause of the issue, but this fix will help prevent this deadlock allow the test run to complete in a timely manner without it causing a time out error.
1 parent 78b14b6 commit bc90dd1

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

api/frame.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package api
22

3-
import "github.com/dop251/goja"
3+
import (
4+
"context"
5+
6+
"github.com/dop251/goja"
7+
)
48

59
// Frame is the interface of a CDP target frame.
610
type Frame interface {
@@ -12,6 +16,8 @@ type Frame interface {
1216
Content() string
1317
Dblclick(selector string, opts goja.Value)
1418
DispatchEvent(selector string, typ string, eventInit goja.Value, opts goja.Value)
19+
// EvaluateWithContext for internal use only
20+
EvaluateWithContext(ctx context.Context, pageFunc goja.Value, args ...goja.Value) (any, error)
1521
Evaluate(pageFunc goja.Value, args ...goja.Value) any
1622
EvaluateHandle(pageFunc goja.Value, args ...goja.Value) (JSHandle, error)
1723
Fill(selector string, value string, opts goja.Value)

browser/mapping_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ func customMappings() map[string]string {
3535
"Page.getMouse": "mouse",
3636
"Page.getTouchscreen": "touchscreen",
3737
// internal methods
38-
"ElementHandle.objectID": "",
39-
"Frame.id": "",
40-
"Frame.loaderID": "",
41-
"JSHandle.objectID": "",
42-
"Browser.close": "",
38+
"ElementHandle.objectID": "",
39+
"Frame.id": "",
40+
"Frame.loaderID": "",
41+
"JSHandle.objectID": "",
42+
"Browser.close": "",
43+
"Frame.evaluateWithContext": "",
4344
// TODO: browser.on method is unexposed until more event
4445
// types other than 'disconnect' are supported.
4546
// See: https://github.com/grafana/xk6-browser/issues/913

common/frame.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,28 @@ func (f *Frame) dispatchEvent(selector, typ string, eventInit goja.Value, opts *
709709
return nil
710710
}
711711

712+
// EvaluateWithContext will evaluate provided page function within an execution context.
713+
// The passed in context will be used instead of the frame's context. The context must
714+
// be a derivative of one that contains the goja runtime.
715+
func (f *Frame) EvaluateWithContext(ctx context.Context, pageFunc goja.Value, args ...goja.Value) (any, error) {
716+
f.log.Debugf("Frame:EvaluateWithContext", "fid:%s furl:%q", f.ID(), f.URL())
717+
718+
f.waitForExecutionContext(mainWorld)
719+
720+
opts := evalOptions{
721+
forceCallable: true,
722+
returnByValue: true,
723+
}
724+
result, err := f.evaluate(ctx, mainWorld, opts, pageFunc, args...)
725+
if err != nil {
726+
return nil, fmt.Errorf("evaluating JS: %w", err)
727+
}
728+
729+
applySlowMo(ctx)
730+
731+
return result, nil
732+
}
733+
712734
// Evaluate will evaluate provided page function within an execution context.
713735
func (f *Frame) Evaluate(pageFunc goja.Value, args ...goja.Value) any {
714736
f.log.Debugf("Frame:Evaluate", "fid:%s furl:%q", f.ID(), f.URL())

0 commit comments

Comments
 (0)