Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare Page.evaluate for async migration #1343

Merged
merged 3 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions browser/frame_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func mapFrame(vu moduleVU, f *common.Frame) mapping { //nolint:gocognit,cyclop
}
return f.DispatchEvent(selector, typ, exportArg(eventInit), popts) //nolint:wrapcheck
},
"evaluate": func(pageFunction goja.Value, gargs ...goja.Value) any {
return f.Evaluate(pageFunction.String(), exportArgs(gargs)...)
"evaluate": func(pageFunction goja.Value, gargs ...goja.Value) (any, error) {
return f.Evaluate(pageFunction.String(), exportArgs(gargs)...) //nolint:wrapcheck
},
"evaluateHandle": func(pageFunction goja.Value, gargs ...goja.Value) (mapping, error) {
jsh, err := f.EvaluateHandle(pageFunction.String(), exportArgs(gargs)...)
Expand Down
8 changes: 4 additions & 4 deletions browser/mapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ type pageAPI interface {
DispatchEvent(selector string, typ string, eventInit goja.Value, opts goja.Value)
EmulateMedia(opts goja.Value)
EmulateVisionDeficiency(typ string)
Evaluate(pageFunc goja.Value, arg ...goja.Value) any
Evaluate(pageFunc goja.Value, arg ...goja.Value) (any, error)
EvaluateHandle(pageFunc goja.Value, arg ...goja.Value) (common.JSHandleAPI, error)
Fill(selector string, value string, opts goja.Value)
Focus(selector string, opts goja.Value)
Expand Down Expand Up @@ -344,10 +344,10 @@ type pageAPI interface {
TextContent(selector string, opts goja.Value) string
ThrottleCPU(common.CPUProfile) error
ThrottleNetwork(common.NetworkProfile) error
Title() string
Title() (string, error)
Type(selector string, text string, opts goja.Value)
Uncheck(selector string, opts goja.Value)
URL() string
URL() (string, error)
ViewportSize() map[string]float64
WaitForFunction(fn, opts goja.Value, args ...goja.Value) (any, error)
WaitForLoadState(state string, opts goja.Value)
Expand Down Expand Up @@ -375,7 +375,7 @@ type frameAPI interface {
DispatchEvent(selector string, typ string, eventInit goja.Value, opts goja.Value)
// EvaluateWithContext for internal use only
EvaluateWithContext(ctx context.Context, pageFunc goja.Value, args ...goja.Value) (any, error)
Evaluate(pageFunc goja.Value, args ...goja.Value) any
Evaluate(pageFunc goja.Value, args ...goja.Value) (any, error)
EvaluateHandle(pageFunc goja.Value, args ...goja.Value) (common.JSHandleAPI, error)
Fill(selector string, value string, opts goja.Value)
Focus(selector string, opts goja.Value)
Expand Down
4 changes: 2 additions & 2 deletions browser/page_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func mapPage(vu moduleVU, p *common.Page) mapping { //nolint:gocognit,cyclop
},
"emulateMedia": p.EmulateMedia,
"emulateVisionDeficiency": p.EmulateVisionDeficiency,
"evaluate": func(pageFunction goja.Value, gargs ...goja.Value) any {
return p.Evaluate(pageFunction.String(), exportArgs(gargs)...)
"evaluate": func(pageFunction goja.Value, gargs ...goja.Value) (any, error) {
return p.Evaluate(pageFunction.String(), exportArgs(gargs)...) //nolint:wrapcheck
},
"evaluateHandle": func(pageFunc goja.Value, gargs ...goja.Value) (mapping, error) {
jsh, err := p.EvaluateHandle(pageFunc.String(), exportArgs(gargs)...)
Expand Down
18 changes: 8 additions & 10 deletions common/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,9 +715,11 @@ func (f *Frame) Content() string {
return content;
}`

v, _ := f.Evaluate(js)

// TODO: return error

return f.Evaluate(js).(string) //nolint:forcetypeassert
return v.(string) //nolint:forcetypeassert
}

// Dblclick double clicks an element matching provided selector.
Expand Down Expand Up @@ -806,15 +808,10 @@ func (f *Frame) EvaluateWithContext(ctx context.Context, pageFunc string, args .
}

// Evaluate will evaluate provided page function within an execution context.
func (f *Frame) Evaluate(pageFunc string, args ...any) any {
func (f *Frame) Evaluate(pageFunc string, args ...any) (any, error) {
f.log.Debugf("Frame:Evaluate", "fid:%s furl:%q", f.ID(), f.URL())

result, err := f.EvaluateWithContext(f.ctx, pageFunc, args...)
if err != nil {
k6ext.Panic(f.ctx, "%v", err)
}

return result
return f.EvaluateWithContext(f.ctx, pageFunc, args...)
}

// EvaluateGlobal will evaluate the given JS code in the global object.
Expand Down Expand Up @@ -1653,11 +1650,12 @@ func (f *Frame) Timeout() time.Duration {
func (f *Frame) Title() string {
f.log.Debugf("Frame:Title", "fid:%s furl:%q", f.ID(), f.URL())

v := `() => document.title`
script := `() => document.title`

// TODO: return error

return f.Evaluate(v).(string) //nolint:forcetypeassert
v, _ := f.Evaluate(script)
return v.(string) //nolint:forcetypeassert
}

// Type text on the first element found matches the selector.
Expand Down
33 changes: 24 additions & 9 deletions common/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ func (p *Page) EmulateVisionDeficiency(typ string) {
}

// Evaluate runs JS code within the execution context of the main frame of the page.
func (p *Page) Evaluate(pageFunc string, args ...any) any {
func (p *Page) Evaluate(pageFunc string, args ...any) (any, error) {
p.logger.Debugf("Page:Evaluate", "sid:%v", p.sessionID())

return p.MainFrame().Evaluate(pageFunc, args...)
Expand Down Expand Up @@ -1173,13 +1173,21 @@ func (p *Page) Timeout() time.Duration {
return p.defaultTimeout()
}

func (p *Page) Title() string {
// Title returns the page title.
func (p *Page) Title() (string, error) {
p.logger.Debugf("Page:Title", "sid:%v", p.sessionID())

// TODO: return error
js := `() => document.title`
v, err := p.Evaluate(js)
if err != nil {
return "", fmt.Errorf("getting page title: %w", err)
}
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("getting page title: expected string, got %T", v)
}

v := `() => document.title`
return p.Evaluate(v).(string) //nolint:forcetypeassert
return s, nil
}

// ThrottleCPU will slow the CPU down from chrome's perspective to simulate
Expand Down Expand Up @@ -1223,13 +1231,20 @@ func (p *Page) Type(selector string, text string, opts goja.Value) {
}

// URL returns the location of the page.
func (p *Page) URL() string {
func (p *Page) URL() (string, error) {
p.logger.Debugf("Page:URL", "sid:%v", p.sessionID())

// TODO: return error
js := `() => document.location.toString()`
v, err := p.Evaluate(js)
if err != nil {
return "", fmt.Errorf("getting page URL: %w", err)
}
s, ok := v.(string)
if !ok {
return "", fmt.Errorf("getting page URL: expected string, got %T", v)
}

v := `() => document.location.toString()`
return p.Evaluate(v).(string) //nolint:forcetypeassert
return s, nil
}

// ViewportSize will return information on the viewport width and height.
Expand Down
6 changes: 4 additions & 2 deletions tests/browser_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ func TestBrowserContextCookies(t *testing.T) {
)

// setting document.cookie into the page
cookie := p.Evaluate(tt.documentCookiesSnippet)
cookie, err := p.Evaluate(tt.documentCookiesSnippet)
require.NoError(t, err)
require.Equalf(t,
tt.wantDocumentCookies,
cookie,
Expand Down Expand Up @@ -934,7 +935,8 @@ func TestBrowserContextClearPermissions(t *testing.T) {
{ name: %q }
).then(result => result.state)
`, perm)
v := p.Evaluate(js)
v, err := p.Evaluate(js)
require.NoError(t, err)
s := asString(t, v)
return s == "granted"
}
Expand Down
49 changes: 30 additions & 19 deletions tests/element_handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ func TestElementHandleBoundingBoxSVG(t *testing.T) {
const rect = e.getBoundingClientRect();
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
}`
box := p.Evaluate(pageFn, element)
box, err := p.Evaluate(pageFn, element)
require.NoError(t, err)
rect := convert(t, box, &common.Rect{})
require.EqualValues(t, bbox, rect)
}
Expand All @@ -108,7 +109,8 @@ func TestElementHandleClick(t *testing.T) {
err = button.Click(opts)
require.NoError(t, err)

res := p.Evaluate(`() => window['result']`)
res, err := p.Evaluate(`() => window['result']`)
require.NoError(t, err)
assert.Equal(t, res, "Clicked")
}

Expand All @@ -121,7 +123,8 @@ func TestElementHandleClickWithNodeRemoved(t *testing.T) {
p.SetContent(htmlInputButton, nil)

// Remove all nodes
p.Evaluate(`() => delete window['Node']`)
_, err := p.Evaluate(`() => delete window['Node']`)
require.NoError(t, err)

button, err := p.Query("button")
require.NoError(t, err)
Expand All @@ -133,7 +136,8 @@ func TestElementHandleClickWithNodeRemoved(t *testing.T) {
err = button.Click(opts)
require.NoError(t, err)

res := p.Evaluate(`() => window['result']`)
res, err := p.Evaluate(`() => window['result']`)
require.NoError(t, err)
assert.Equal(t, res, "Clicked")
}

Expand All @@ -148,7 +152,8 @@ func TestElementHandleClickWithDetachedNode(t *testing.T) {
require.NoError(t, err)

// Detach node to panic when clicked
p.Evaluate(`button => button.remove()`, button)
_, err = p.Evaluate(`button => button.remove()`, button)
require.NoError(t, err)

opts := common.NewElementHandleClickOptions(button.Timeout())
// FIX: this is just a workaround because navigation is never triggered
Expand Down Expand Up @@ -185,12 +190,11 @@ func TestElementHandleClickConcealedLink(t *testing.T) {
p, err := bc.NewPage()
require.NoError(t, err)

clickResult := func() any {
clickResult := func() (any, error) {
const cmd = `
() => window.clickResult
`
cr := p.Evaluate(cmd)
return cr
return p.Evaluate(cmd)
}
opts := &common.FrameGotoOptions{
Timeout: common.DefaultTimeout,
Expand All @@ -201,11 +205,15 @@ func TestElementHandleClickConcealedLink(t *testing.T) {
)
require.NotNil(t, resp)
require.NoError(t, err)
require.Equal(t, wantBefore, clickResult())
result, err := clickResult()
require.NoError(t, err)
require.Equal(t, wantBefore, result)

err = p.Click("#concealed", common.NewFrameClickOptions(p.Timeout()))
require.NoError(t, err)
require.Equal(t, wantAfter, clickResult())
result, err = clickResult()
require.NoError(t, err)
require.Equal(t, wantAfter, result)
}

func TestElementHandleNonClickable(t *testing.T) {
Expand Down Expand Up @@ -369,7 +377,8 @@ func TestElementHandleScreenshot(t *testing.T) {
Width float64 `js:"width"`
Height float64 `js:"height"`
}{Width: 800, Height: 600}))
p.Evaluate(`

_, err := p.Evaluate(`
() => {
document.body.style.margin = '0';
document.body.style.padding = '0';
Expand All @@ -385,7 +394,8 @@ func TestElementHandleScreenshot(t *testing.T) {

document.body.appendChild(div);
}
`)
`)
require.NoError(t, err)

elem, err := p.Query("div")
require.NoError(t, err)
Expand Down Expand Up @@ -423,17 +433,18 @@ func TestElementHandleWaitForSelector(t *testing.T) {
root, err := p.Query(".root")
require.NoError(t, err)

p.Evaluate(`
_, err = p.Evaluate(`
() => {
setTimeout(() => {
const div = document.createElement('div');
div.className = 'element-to-appear';
div.appendChild(document.createTextNode("Hello World"));
root = document.querySelector('.root');
root.appendChild(div);
setTimeout(() => {
const div = document.createElement('div');
div.className = 'element-to-appear';
div.appendChild(document.createTextNode("Hello World"));
root = document.querySelector('.root');
root.appendChild(div);
}, 100);
}
`)
require.NoError(t, err)
element, err := root.WaitForSelector(".element-to-appear", tb.toGojaValue(struct {
Timeout int64 `js:"timeout"`
}{Timeout: 1000}))
Expand Down
4 changes: 3 additions & 1 deletion tests/frame_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,7 @@ func TestWaitForFrameNavigation(t *testing.T) {
err = tb.run(ctx, waitForNav, click)
require.NoError(t, err)

assert.Equal(t, "Second page", p.Title())
title, err := p.Title()
require.NoError(t, err)
assert.Equal(t, "Second page", title)
}
6 changes: 4 additions & 2 deletions tests/launch_options_slowmo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ func TestBrowserOptionsSlowMo(t *testing.T) {
t.Parallel()
tb := newTestBrowser(t, withFileServer())
testPageSlowMoImpl(t, tb, func(_ *testBrowser, p *common.Page) {
p.Evaluate(`() => void 0`)
_, err := p.Evaluate(`() => void 0`)
require.NoError(t, err)
})
})
t.Run("evaluateHandle", func(t *testing.T) {
Expand Down Expand Up @@ -202,7 +203,8 @@ func TestBrowserOptionsSlowMo(t *testing.T) {
t.Parallel()
tb := newTestBrowser(t, withFileServer())
testFrameSlowMoImpl(t, tb, func(_ *testBrowser, f *common.Frame) {
f.Evaluate(`() => void 0`)
_, err := f.Evaluate(`() => void 0`)
require.NoError(t, err)
})
})
t.Run("evaluateHandle", func(t *testing.T) {
Expand Down
Loading
Loading