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

Refactor browserContext.grantPermissions #1075

Merged
merged 9 commits into from
Oct 23, 2023
25 changes: 15 additions & 10 deletions browser/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -631,16 +631,21 @@ func mapWorker(vu moduleVU, w *common.Worker) mapping {
func mapBrowserContext(vu moduleVU, bc *common.BrowserContext) mapping { //nolint:funlen
rt := vu.Runtime()
return mapping{
"addCookies": bc.AddCookies,
"addInitScript": bc.AddInitScript,
"browser": bc.Browser,
"clearCookies": bc.ClearCookies,
"clearPermissions": bc.ClearPermissions,
"close": bc.Close,
"cookies": bc.Cookies,
"exposeBinding": bc.ExposeBinding,
"exposeFunction": bc.ExposeFunction,
"grantPermissions": bc.GrantPermissions,
"addCookies": bc.AddCookies,
"addInitScript": bc.AddInitScript,
"browser": bc.Browser,
"clearCookies": bc.ClearCookies,
"clearPermissions": bc.ClearPermissions,
"close": bc.Close,
"cookies": bc.Cookies,
"exposeBinding": bc.ExposeBinding,
"exposeFunction": bc.ExposeFunction,
"grantPermissions": func(permissions []string, opts goja.Value) error {
pOpts := common.NewGrantPermissionsOptions()
pOpts.Parse(vu.Context(), opts)

return bc.GrantPermissions(permissions, pOpts) //nolint:wrapcheck
},
"newCDPSession": bc.NewCDPSession,
"route": bc.Route,
"setDefaultNavigationTimeout": bc.SetDefaultNavigationTimeout,
Expand Down
31 changes: 14 additions & 17 deletions common/browser_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ func NewBrowserContext(
}

if opts != nil && len(opts.Permissions) > 0 {
b.GrantPermissions(opts.Permissions, nil)
err := b.GrantPermissions(opts.Permissions, NewGrantPermissionsOptions())
if err != nil {
return nil, err
}
}

rt := b.vu.Runtime()
Expand Down Expand Up @@ -214,7 +217,7 @@ func (b *BrowserContext) ExposeFunction(name string, callback goja.Callable) {
}

// GrantPermissions enables the specified permissions, all others will be disabled.
func (b *BrowserContext) GrantPermissions(permissions []string, opts goja.Value) {
func (b *BrowserContext) GrantPermissions(permissions []string, opts *GrantPermissionsOptions) error {
b.logger.Debugf("BrowserContext:GrantPermissions", "bctxid:%v", b.id)

permsToProtocol := map[string]cdpbrowser.PermissionType{
Expand All @@ -234,28 +237,22 @@ func (b *BrowserContext) GrantPermissions(permissions []string, opts goja.Value)
"clipboard-write": cdpbrowser.PermissionTypeClipboardSanitizedWrite,
"payment-handler": cdpbrowser.PermissionTypePaymentHandler,
}
origin := ""

rt := b.vu.Runtime()
if opts != nil && !goja.IsUndefined(opts) && !goja.IsNull(opts) {
opts := opts.ToObject(rt)
for _, k := range opts.Keys() {
if k == "origin" {
origin = opts.Get(k).String()
break
}
}
}

perms := make([]cdpbrowser.PermissionType, 0, len(permissions))
for _, p := range permissions {
perms = append(perms, permsToProtocol[p])
proto, ok := permsToProtocol[p]
if !ok {
return fmt.Errorf("%q is an invalid permission", p)
}
perms = append(perms, proto)
}

action := cdpbrowser.GrantPermissions(perms).WithOrigin(origin).WithBrowserContextID(b.id)
action := cdpbrowser.GrantPermissions(perms).WithOrigin(opts.Origin).WithBrowserContextID(b.id)
if err := action.Do(cdp.WithExecutor(b.ctx, b.browser.conn)); err != nil {
k6ext.Panic(b.ctx, "internal error while granting browser permissions: %w", err)
return fmt.Errorf("granting browser permissions: %w", err)
}

return nil
}

// NewCDPSession returns a new CDP session attached to this target.
Expand Down
25 changes: 25 additions & 0 deletions common/browser_context_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,28 @@ func (w *WaitForEventOptions) Parse(ctx context.Context, optsOrPredicate goja.Va

return nil
}

// GrantPermissionsOptions is used by BrowserContext.GrantPermissions.
type GrantPermissionsOptions struct {
Origin string
}

// NewGrantPermissionsOptions returns a new GrantPermissionsOptions.
func NewGrantPermissionsOptions() *GrantPermissionsOptions {
return &GrantPermissionsOptions{}
}

// Parse parses the options from opts if opts exists in the Goja runtime.
func (g *GrantPermissionsOptions) Parse(ctx context.Context, opts goja.Value) {
rt := k6ext.Runtime(ctx)

if gojaValueExists(opts) {
opts := opts.ToObject(rt)
for _, k := range opts.Keys() {
if k == "origin" {
g.Origin = opts.Get(k).String()
break
}
}
}
}
47 changes: 47 additions & 0 deletions tests/browser_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,3 +794,50 @@ func TestBrowserContextWaitForEvent(t *testing.T) {
})
}
}

func TestBrowserContextGrantPermissions(t *testing.T) {
t.Parallel()

testCases := []struct {
name string
permission string
wantErr string
}{
inancgumus marked this conversation as resolved.
Show resolved Hide resolved
{name: "geolocation", permission: "geolocation"},
{name: "midi", permission: "midi"},
{name: "midi-sysex", permission: "midi-sysex"},
{name: "notifications", permission: "notifications"},
{name: "camera", permission: "camera"},
{name: "microphone", permission: "microphone"},
{name: "background-sync", permission: "background-sync"},
{name: "ambient-light-sensor", permission: "ambient-light-sensor"},
{name: "accelerometer", permission: "accelerometer"},
{name: "gyroscope", permission: "gyroscope"},
{name: "magnetometer", permission: "magnetometer"},
{name: "accessibility-events", permission: "accessibility-events"},
{name: "clipboard-read", permission: "clipboard-read"},
{name: "clipboard-write", permission: "clipboard-write"},
{name: "payment-handler", permission: "payment-handler"},
{name: "fake-permission", permission: "fake-permission", wantErr: `"fake-permission" is an invalid permission`},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

tb := newTestBrowser(t)
bCtx, err := tb.NewContext(nil)
require.NoError(t, err)

err = bCtx.GrantPermissions([]string{tc.permission}, common.NewGrantPermissionsOptions())

if tc.wantErr == "" {
assert.NoError(t, err)
return
}

assert.EqualError(t, err, tc.wantErr)
})
}
}