Skip to content

Commit

Permalink
[wdspec] add bluetooth module (#49066)
Browse files Browse the repository at this point in the history
Add BiDi bluetooth module and and some wdspec tests. 
https://webbluetoothcg.github.io/web-bluetooth
  • Loading branch information
sadym-chromium authored Nov 8, 2024
1 parent e44f453 commit 7b54230
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions tools/webdriver/webdriver/bidi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def __init__(self,

# Modules.
# For each module, have a property representing that module
self.bluetooth = modules.Bluetooth(self)
self.browser = modules.Browser(self)
self.browsing_context = modules.BrowsingContext(self)
self.input = modules.Input(self)
Expand Down
1 change: 1 addition & 0 deletions tools/webdriver/webdriver/bidi/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# flake8: noqa

from .bluetooth import Bluetooth
from .browser import Browser
from .browsing_context import BrowsingContext
from .input import Input
Expand Down
21 changes: 21 additions & 0 deletions tools/webdriver/webdriver/bidi/modules/bluetooth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import Any, Mapping

from ._module import BidiModule, command


class Bluetooth(BidiModule):
"""
Represents bluetooth automation module specified in
https://webbluetoothcg.github.io/web-bluetooth/#automated-testing
"""

@command
def simulate_adapter(self, context: str, state: str) -> Mapping[str, Any]:
"""
Represents a command `bluetooth.simulateAdapter` specified in
https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateAdapter-command
"""
return {
"context": context,
"state": state
}
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from webdriver.bidi.modules.script import ContextTarget


async def get_bluetooth_availability(bidi_session, context):
result = await bidi_session.script.evaluate(
expression="navigator.bluetooth.getAvailability()",
target=ContextTarget(context["context"]), await_promise=True, )
return result['value']


async def set_simulate_adapter(bidi_session, context, test_page, state):
# Navigate to a page, as bluetooth is not guaranteed to work on
# `about:blank`.
await bidi_session.browsing_context.navigate(context=context['context'],
url=test_page, wait="complete")

await bidi_session.bluetooth.simulate_adapter(context=context["context"],
state=state)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import pytest

from . import get_bluetooth_availability, set_simulate_adapter

pytestmark = pytest.mark.asyncio


async def test_contexts_are_isolated(bidi_session, top_context, test_page):
another_browsing_context = await bidi_session.browsing_context.create(
type_hint="tab")

await set_simulate_adapter(bidi_session, top_context, test_page,
"powered-on")
await set_simulate_adapter(bidi_session, another_browsing_context,
test_page, "absent")

assert await get_bluetooth_availability(bidi_session, top_context) is True
assert await get_bluetooth_availability(bidi_session,
another_browsing_context) is False
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pytest
import webdriver.bidi.error as error

pytestmark = pytest.mark.asyncio


@pytest.mark.parametrize("state", [None, False, 42, {}, []])
async def test_state_invalid_type(bidi_session, top_context, state):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.bluetooth.simulate_adapter(
context=top_context["context"], state=state)


@pytest.mark.parametrize("state", ["", "invalid"])
async def test_state_invalid_value(bidi_session, top_context, state):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.bluetooth.simulate_adapter(
context=top_context["context"], state=state)


@pytest.mark.parametrize("context", [None, False, 42, {}, []])
async def test_context_invalid_type(bidi_session, context):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.bluetooth.simulate_adapter(
context=context, state="powered-on")


async def test_context_unknown_value(bidi_session):
with pytest.raises(error.NoSuchFrameException):
await bidi_session.bluetooth.simulate_adapter(
context="UNKNOWN_CONTEXT", state="powered-on")
31 changes: 31 additions & 0 deletions webdriver/tests/bidi/external/bluetooth/simulate_adapter/state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import pytest

from . import get_bluetooth_availability, set_simulate_adapter

pytestmark = pytest.mark.asyncio


@pytest.mark.parametrize("state,availability",
[("absent", False), ("powered-off", True),
("powered-on", True)])
async def test_state(bidi_session, top_context, test_page, state, availability):
await set_simulate_adapter(bidi_session, top_context, test_page, state)
assert await get_bluetooth_availability(bidi_session,
top_context) == availability


@pytest.mark.parametrize("state_1,availability_1",
[("absent", False), ("powered-off", True),
("powered-on", True)])
@pytest.mark.parametrize("state_2,availability_2",
[("absent", False), ("powered-off", True),
("powered-on", True)])
async def test_set_twice(bidi_session, top_context, test_page, state_1,
availability_1, state_2, availability_2):
await set_simulate_adapter(bidi_session, top_context, test_page, state_1)
assert await get_bluetooth_availability(bidi_session,
top_context) == availability_1

await set_simulate_adapter(bidi_session, top_context, test_page, state_2)
assert await get_bluetooth_availability(bidi_session,
top_context) == availability_2

0 comments on commit 7b54230

Please sign in to comment.