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

Desobekify BrowserContext wait for event options #1512

Merged
merged 7 commits into from
Nov 6, 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
56 changes: 50 additions & 6 deletions browser/browser_context_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"reflect"
"time"

"github.com/grafana/sobek"

Expand Down Expand Up @@ -109,14 +110,12 @@ func mapBrowserContext(vu moduleVU, bc *common.BrowserContext) mapping { //nolin
})
},
"waitForEvent": func(event string, optsOrPredicate sobek.Value) (*sobek.Promise, error) {
ctx := vu.Context()
popts := common.NewWaitForEventOptions(
bc.Timeout(),
)
if err := popts.Parse(ctx, optsOrPredicate); err != nil {
return nil, fmt.Errorf("parsing waitForEvent options: %w", err)
popts, err := parseWaitForEventOptions(vu.Runtime(), optsOrPredicate, bc.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing wait for event options: %w", err)
}

ctx := vu.Context()
return k6ext.Promise(ctx, func() (result any, reason error) {
var runInTaskQueue func(p *common.Page) (bool, error)
if popts.PredicateFn != nil {
Expand Down Expand Up @@ -186,3 +185,48 @@ func mapBrowserContext(vu moduleVU, bc *common.BrowserContext) mapping { //nolin
},
}
}

// waitForEventOptions are the options used by the browserContext.waitForEvent API.
type waitForEventOptions struct {
Timeout time.Duration
PredicateFn sobek.Callable
}

// parseWaitForEventOptions parses optsOrPredicate into a WaitForEventOptions.
// It returns a WaitForEventOptions with the default timeout if optsOrPredicate is nil,
// or not a callable predicate function.
// It can parse only a callable predicate function or an object which contains a
// callable predicate function and a timeout.
func parseWaitForEventOptions(
rt *sobek.Runtime, optsOrPredicate sobek.Value, defaultTime time.Duration,
) (*waitForEventOptions, error) {
w := &waitForEventOptions{
Timeout: defaultTime,
}

if !sobekValueExists(optsOrPredicate) {
return w, nil
}
var isCallable bool
w.PredicateFn, isCallable = sobek.AssertFunction(optsOrPredicate)
if isCallable {
return w, nil
}

opts := optsOrPredicate.ToObject(rt)
for _, k := range opts.Keys() {
switch k {
case "predicate":
w.PredicateFn, isCallable = sobek.AssertFunction(opts.Get(k))
if !isCallable {
return nil, errors.New("predicate function is not callable")
}
case "timeout":
w.Timeout = time.Duration(opts.Get(k).ToInteger()) * time.Millisecond
default:
return nil, fmt.Errorf("unknown option: %s", k)
}
}

return w, nil
}
10 changes: 4 additions & 6 deletions browser/sync_browser_context_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,12 @@ func syncMapBrowserContext(vu moduleVU, bc *common.BrowserContext) mapping { //n
"setHTTPCredentials": bc.SetHTTPCredentials, //nolint:staticcheck
"setOffline": bc.SetOffline,
"waitForEvent": func(event string, optsOrPredicate sobek.Value) (*sobek.Promise, error) {
ctx := vu.Context()
popts := common.NewWaitForEventOptions(
bc.Timeout(),
)
if err := popts.Parse(ctx, optsOrPredicate); err != nil {
return nil, fmt.Errorf("parsing waitForEvent options: %w", err)
popts, err := parseWaitForEventOptions(vu.Runtime(), optsOrPredicate, bc.Timeout())
if err != nil {
return nil, fmt.Errorf("parsing wait for event options: %w", err)
}

ctx := vu.Context()
return k6ext.Promise(ctx, func() (result any, reason error) {
var runInTaskQueue func(p *common.Page) (bool, error)
if popts.PredicateFn != nil {
Expand Down
50 changes: 0 additions & 50 deletions common/browser_context_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package common

import (
"context"
"errors"
"fmt"
"time"

"github.com/grafana/sobek"

Expand Down Expand Up @@ -98,54 +96,6 @@ func NewBrowserContextOptions() *BrowserContextOptions {
}
}

// WaitForEventOptions are the options used by the browserContext.waitForEvent API.
type WaitForEventOptions struct {
Timeout time.Duration
PredicateFn sobek.Callable
}

// NewWaitForEventOptions created a new instance of WaitForEventOptions with a
// default timeout.
func NewWaitForEventOptions(defaultTimeout time.Duration) *WaitForEventOptions {
return &WaitForEventOptions{
Timeout: defaultTimeout,
}
}

// Parse will parse the options or a callable predicate function. It can parse
// only a callable predicate function or an object which contains a callable
// predicate function and a timeout.
func (w *WaitForEventOptions) Parse(ctx context.Context, optsOrPredicate sobek.Value) error {
if !sobekValueExists(optsOrPredicate) {
return nil
}

var (
isCallable bool
rt = k6ext.Runtime(ctx)
)

w.PredicateFn, isCallable = sobek.AssertFunction(optsOrPredicate)
if isCallable {
return nil
}

opts := optsOrPredicate.ToObject(rt)
for _, k := range opts.Keys() {
switch k {
case "predicate":
w.PredicateFn, isCallable = sobek.AssertFunction(opts.Get(k))
if !isCallable {
return errors.New("predicate function is not callable")
}
case "timeout": //nolint:goconst
w.Timeout = time.Duration(opts.Get(k).ToInteger()) * time.Millisecond
}
}

return nil
}

// GrantPermissionsOptions is used by BrowserContext.GrantPermissions.
type GrantPermissionsOptions struct {
Origin string
Expand Down
Loading