feat: Wallabidi.Browser.grant_permissions/2 for fake camera/mic access - #82
Open
pinetops wants to merge 1 commit into
Open
feat: Wallabidi.Browser.grant_permissions/2 for fake camera/mic access#82pinetops wants to merge 1 commit into
pinetops wants to merge 1 commit into
Conversation
Wraps CDP's Browser.grantPermissions so a headless session's getUserMedia/getDisplayMedia calls succeed without a real permission prompt — headless Chrome has no UI surface to show or auto-accept one, so calls otherwise fail with NotAllowedError. Motivating case: driving a headless bot into a WebRTC call. grant_permissions(session, [:camera, :microphone]) grants for every origin in the session's browser context (no origin scoping — a session joining a call on a domain not known in advance is the common case, not a single already-known origin). Chrome CDP only. Lightpanda and Chrome BiDi both override the Generic driver delegate to raise Wallabidi.DriverError directly — NOT gated via function_exported?/3 in the Orchestrator, because Lightpanda and Chrome CDP share the exact same wire_protocol module (Wallabidi.Remote.CDP.Client). This is the same class of bug caught while building an earlier (since-reverted) streaming feature; covered here by test/wallabidi/remote/driver/permissions_dispatch_test.exs from the start. Verified end-to-end against real Chrome: a getUserMedia call fails with NotAllowedError before grant_permissions and succeeds (getTracks() returns real audio+video) immediately after, on the same session. Also caught and fixed a wrong assumption about CDP's permission type strings — they're "audioCapture"/"videoCapture", not "camera"/"microphone" as initially guessed — by testing against real Chrome rather than trusting the first plausible-looking name. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
Wallabidi.Browser.grant_permissions/2, wrapping CDP'sBrowser.grantPermissionsso a headless session'sgetUserMedia/getDisplayMediacalls succeed without a real permission prompt — headless Chrome has no UI surface to show or auto-accept one, so those calls otherwise fail withNotAllowedError. Motivating case: driving a headless bot into a WebRTC call (a known gap flagged in an earlier design pass).Grants for every origin in the session's browser context (no origin scoping) — a session joining a call on a domain not known in advance is the common case here, not a single already-known origin.
A bug avoided (same class as a previous PR's)
Chrome CDP and Lightpanda share the exact same
wire_protocolmodule (Wallabidi.Remote.CDP.Client), so gating this CDP-only capability viafunction_exported?/3in theOrchestratorcan't tell the two drivers apart — Lightpanda would silently attempt the real CDP dispatch instead of raising a clean error.LightpandaCDPandChromeBiDiboth override theGenericdriver delegate directly instead, so dispatch never reachesOrchestrator/CDP.Clientfor either. Covered from the start bytest/wallabidi/remote/driver/permissions_dispatch_test.exs.A wrong assumption caught by testing against real Chrome
Initially mapped
:camera/:microphoneto CDP's permission strings as"camera"/"microphone"— plausible-looking, but wrong. Real Chrome rejected them ("Unknown permission type: camera"); the actual current CDPBrowser.PermissionTypevalues are"audioCapture"/"videoCapture". Fixed after testing directly against a live session, not left as an assumption.Test plan
mix test(unit suite) — 193 tests, 0 failures, includes the Lightpanda/BiDi dispatch regression test and anArgumentError-on-unknown-permission testWALLABIDI_DRIVER=chrome_cdp mix test integration_test/cases/browser/permissions_test.exs— new end-to-end test against real Chrome:getUserMediafails withNotAllowedErrorbeforegrant_permissions, succeeds (getTracks()returns real audio+video) immediately after, same sessionWALLABIDI_DRIVER=chrome_cdp mix test integration_test/cases/browser/— full 222-test browser suite, no regressionsgrant_permissionsraises cleanly against real Lightpanda and Chrome BiDi sessionsmix format --check-formatted,mix credo --strict,mix compile --warnings-as-errors,mix docs— all clean🤖 Generated with Claude Code