grafana / xk6-browser

The browser module adds support for browser automation and end-to-end web testing via the Chrome Devtools Protocol to k6.
https://grafana.com/docs/k6/latest/javascript-api/k6-browser/
GNU Affero General Public License v3.0
343 stars 41 forks source link

Support BrowserContext permissions option #313

Closed BarthV closed 2 years ago

BarthV commented 2 years ago

Hi :)

I'm trying to set camera and/or microphone permissions using both xk6-browser context browserContext.grantPermissions(permissions[, options]) or NewContext parameter permissions: ['midi'], // Permisions to grant by default.

But when I'm doing it , it fails with a panic error :

import launcher from 'k6/x/browser';

export default function () {
  const browser = launcher.launch('chromium', { headless: false });
  const context = browser.newContext({
    permissions: ["camera", "microphone"],
  });
  const page = context.newPage();
  page.goto('http://whatsmyuseragent.org/');
  page.screenshot({ path: `example-chromium.png` });
  page.close();
  browser.close();
}

output :

> xk6-browser run test.js                                                                                                                 master [ff1c8ff] (!) modified untracked

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: test.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
           * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

ERRO[0000] panic: interface conversion: interface {} is []interface {}, not []string
goroutine 71 [running]:
runtime/debug.Stack()
    runtime/debug/stack.go:24 +0x88
go.k6.io/k6/js/common.RunWithPanicCatching.func1(0x1400016c000, 0x140029b3898, {0x10198c840, 0x14000134d20})
    go.k6.io/k6@v0.38.1/js/common/util.go:101 +0x170
panic({0x10179dac0, 0x14002a01140})
    runtime/panic.go:1038 +0x21c
github.com/dop251/goja.AssertFunction.func1.1(0x140029b36b0)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/runtime.go:2300 +0x98
panic({0x10179dac0, 0x14002a01140})
    runtime/panic.go:1038 +0x21c
github.com/dop251/goja.(*vm).try.func1(0x1400226c400, 0x0, 0x140029b3560, 0x0, 0x0, 0x0, 0x140029b35f8)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/vm.go:537 +0x620
panic({0x10179dac0, 0x14002a01140})
    runtime/panic.go:1038 +0x21c
github.com/grafana/xk6-browser/common.(*BrowserContextOptions).Parse(0x14000d54000, {0x101969108, 0x14001d1b920}, {0x101987698, 0x14001653a10})
    github.com/grafana/xk6-browser@v0.0.0-00010101000000-000000000000/common/browser_context_options.go:119 +0x1140
github.com/grafana/xk6-browser/common.(*Browser).NewContext(0x1400219e000, {0x101987698, 0x14001653a10})
    github.com/grafana/xk6-browser@v0.0.0-00010101000000-000000000000/common/browser.go:438 +0x3f8
reflect.Value.call({0x1018c6a40, 0x1400219e000, 0xe13}, {0x10140056a, 0x4}, {0x14001d346d8, 0x1, 0x1})
    reflect/value.go:556 +0x5a8
reflect.Value.Call({0x1018c6a40, 0x1400219e000, 0xe13}, {0x14001d346d8, 0x1, 0x1})
    reflect/value.go:339 +0x8c
github.com/dop251/goja.(*Runtime).wrapReflectFunc.func1({{0x101987698, 0x14001653620}, {0x140029be240, 0x1, 0x6}})
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/runtime.go:1886 +0x188
github.com/dop251/goja.(*vm)._nativeCall(0x1400226c400, 0x14000855f40, 0x1)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/vm.go:2727 +0x204
github.com/dop251/goja.call.exec(0x1, 0x1400226c400)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/vm.go:2699 +0x900
github.com/dop251/goja.(*vm).run(0x1400226c400)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/vm.go:408 +0x94
github.com/dop251/goja.(*baseJsFuncObject)._call(0x14001972160, {{0x101987ee8, 0x102555620}, {0x140029181d0, 0x1, 0x1}}, {0x0, 0x0}, {0x101987ee8, 0x102555620})
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/func.go:193 +0x3a0
github.com/dop251/goja.(*baseJsFuncObject).call(...)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/func.go:203
github.com/dop251/goja.(*baseJsFuncObject).Call(0x14001972160, {{0x101987ee8, 0x102555620}, {0x140029181d0, 0x1, 0x1}})
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/func.go:156 +0x88
github.com/dop251/goja.AssertFunction.func1.2()
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/runtime.go:2305 +0x80
github.com/dop251/goja.(*vm).try(0x1400226c400, 0x140029a5618)
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/vm.go:545 +0x110
github.com/dop251/goja.AssertFunction.func1({0x101987ee8, 0x102555620}, {0x140029181d0, 0x1, 0x1})
    github.com/dop251/goja@v0.0.0-20220405120441-9037c2b61cbf/runtime.go:2304 +0xc0
go.k6.io/k6/js.(*VU).runFn.func1.1()
    go.k6.io/k6@v0.38.1/js/runner.go:800 +0x68
go.k6.io/k6/js/eventloop.(*EventLoop).Start(0x14000e18690, 0x14001c66360)
    go.k6.io/k6@v0.38.1/js/eventloop/eventloop.go:112 +0x14c
go.k6.io/k6/js.(*VU).runFn.func1()
    go.k6.io/k6@v0.38.1/js/runner.go:799 +0xf0
go.k6.io/k6/js/common.RunWithPanicCatching({0x10198c840, 0x14000134d20}, 0x1400016c000, 0x140029a5950)
    go.k6.io/k6@v0.38.1/js/common/util.go:105 +0x84
go.k6.io/k6/js.(*VU).runFn(0x1400269ee60, {0x101969060, 0x140020d99c0}, 0x1, 0x140001a6858, 0x140029181c0, {0x140029181d0, 0x1, 0x1})
    go.k6.io/k6@v0.38.1/js/runner.go:798 +0x22c
go.k6.io/k6/js.(*ActiveVU).RunOnce(0x140020d9980)
    go.k6.io/k6@v0.38.1/js/runner.go:750 +0x424
go.k6.io/k6/lib/executor.getIterationRunner.func1({0x101969108, 0x14001abddd0}, {0x10194c740, 0x140020d9980})
    go.k6.io/k6@v0.38.1/lib/executor/helpers.go:145 +0x48
go.k6.io/k6/lib/executor.PerVUIterations.Run.func3({0x10195e050, 0x1400269ee60})
    go.k6.io/k6@v0.38.1/lib/executor/per_vu_iterations.go:236 +0x3a4
created by go.k6.io/k6/lib/executor.PerVUIterations.Run
    go.k6.io/k6@v0.38.1/lib/executor/per_vu_iterations.go:249 +0xaa0

Goja stack:
native

When I'm trying to set permissions after spawning a default context (putting everything as var instaead of const didn't change the result):

import launcher from 'k6/x/browser';

export default function () {
  const browser = launcher.launch('chromium', { headless: false });
  var context = browser.newContext();
  context.grantPermissions(["camera", "microphone"]);
  const page = context.newPage();
  page.goto('http://whatsmyuseragent.org/');
  page.screenshot({ path: `example-chromium.png` });
  page.close();
  browser.close();
}

output :

> xk6-browser run test.js
          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

  execution: local
     script: test.js
     output: -

  scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
           * default: 1 iterations for each of 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

ERRO[0000] unable to override permissions: invalid context
running at reflect.methodValueCall (native)
default at file:///Users/barthelemy.vessemont/k6-tests/test.js:6:28(23)
    at native  executor=per-vu-iterations scenario=default source=stacktrace
BarthV commented 2 years ago

Did I miss a thing or is there another way to achieve this ?

inancgumus commented 2 years ago

Hi @BarthV,

This problem is indeed a bug. Thanks for finding it out!

We've fixed the problem, and we will merge the fix soon on the main branch. You can build a new xk6-browser using the main branch if you need this feature right now. Or, you can wait for the next release (due by June 27, 2022).

Thanks again!

BarthV commented 2 years ago

This is great. thanks a lot for your work.