Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[set_geolocation_override.https.html]
expected:
if product != "chrome": ERROR
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<!DOCTYPE html>
<meta charset="utf-8"/>
<title>TestDriver bidi.emulation.set_geolocation_override method</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js?feature=bidi"></script>
<script src="/resources/testdriver-vendor.js"></script>

<script>
promise_setup(async () => {
// Ensure permission is granted before proceeding.
await test_driver.bidi.permissions.set_permission({
descriptor: {name: "geolocation"},
state: "granted",
});

// Ensure any previously set geolocation emulations are cleared.
await test_driver.bidi.emulation.set_geolocation_override(
{coordinates: null});
});

/** Get the current geolocation or error */
function get_current_geolocation() {
return new Promise(
resolve => window.navigator.geolocation.getCurrentPosition(
position => resolve(position.coords.toJSON()),
error => resolve({code: error.code, message: error.message}),
// Fail fast if geolocation is not available.
{timeout: 500}
))
}

/** Asserts that relevant coordinate properties match */
function assert_coordinates_match(actual, expected) {
for (const key in expected) {
assert_equals(actual[key], expected[key],
`"${key}" should match the expected value ${expected[key]}`);
}
}

const SOME_COORDINATES = {
latitude: 52.51,
longitude: 13.39,
accuracy: 0.5,
altitude: 34,
altitudeAccuracy: 0.75,
heading: 180,
speed: 2.77
};

promise_test(async (t) => {
// Get the initial geolocation (might be error).
const initial_coords = await get_current_geolocation();

// Set the geolocation override
await test_driver.bidi.emulation.set_geolocation_override({
coordinates: SOME_COORDINATES
});

// Get the geolocation after setting the override.
const coords = await get_current_geolocation();
// Assert the coordinates match the override.
assert_coordinates_match(coords, SOME_COORDINATES);

// Clear the geolocation override.
await test_driver.bidi.emulation.set_geolocation_override(
{coordinates: null});
// Assert coordinates are set to the original value.
assert_coordinates_match(await get_current_geolocation(), initial_coords);
}, "emulate geolocation and clear override");
</script>
55 changes: 53 additions & 2 deletions resources/testdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,57 @@
}
},
/**
* `log <https://w3c.github.io/webdriver-bidi/#module-log>`_ module.
* `emulation <https://www.w3.org/TR/webdriver-bidi/#module-emulation>`_ module.
*/
emulation: {
/**
* Overrides the geolocation coordinates for the specified
* browsing contexts.
* Matches the `emulation.setGeolocationOverride
* <https://w3c.github.io/webdriver-bidi/#command-emulation-setGeolocationOverride>`_
* WebDriver BiDi command.
*
* @example
* await test_driver.bidi.emulation.set_geolocation_override({
* coordinates: {
* latitude: 52.51,
* longitude: 13.39,
* accuracy: 0.5,
* altitude: 34,
* altitudeAccuracy: 0.75,
* heading: 180,
* speed: 2.77
* }
* });
*
* @param {object} params - Parameters for the command.
* @param {null|object} params.coordinates - The optional
* geolocation coordinates to set. Matches the
* `emulation.GeolocationCoordinates <https://w3c.github.io/webdriver-bidi/#type-emulation-GeolocationCoordinates>`_
* value. If null or omitted, the emulation will be removed.
* @param {null|Array.<(Context)>} [params.contexts] The
* optional contexts parameter specifies which browsing contexts
* to set the geolocation override on. It should be either an
* array of Context objects (window or browsing context id), or
* null. If null or omitted, the override will be set on the
* current browsing context.
* @returns {Promise<void>} Resolves when the geolocation
* override is successfully set.
*/
set_geolocation_override: function (params) {
// Ensure the bidi feature is enabled before calling the internal method
assertBidiIsEnabled();
return window.test_driver_internal.bidi.emulation.set_geolocation_override(
params);
},
},
/**
* `log <https://www.w3.org/TR/webdriver-bidi/#module-log>`_ module.
*/
log: {
entry_added: {
/**
* @typedef {object} LogEntryAdded `log.entryAdded <https://w3c.github.io/webdriver-bidi/#event-log-entryAdded>`_ event.
* @typedef {object} LogEntryAdded `log.entryAdded <https://www.w3.org/TR/webdriver-bidi/#event-log-entryAdded>`_ event.
*/

/**
Expand Down Expand Up @@ -1576,6 +1621,12 @@
}
}
},
emulation: {
set_geolocation_override: function (params) {
throw new Error(
"bidi.emulation.set_geolocation_override is not implemented by testdriver-vendor.js");
}
},
log: {
entry_added: {
async subscribe() {
Expand Down
29 changes: 29 additions & 0 deletions tools/wptrunner/wptrunner/executors/asyncactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,34 @@ async def __call__(self, payload):
return await self.protocol.bidi_bluetooth.simulate_preconnected_peripheral(
context, address, name, manufacturer_data, known_service_uuids)


class BidiEmulationSetGeolocationOverrideAction:
name = "bidi.emulation.set_geolocation_override"

def __init__(self, logger, protocol):
do_delayed_imports()
self.logger = logger
self.protocol = protocol

async def __call__(self, payload):
coordinates = payload['coordinates']
contexts = []
for context in payload["contexts"]:
# Context can be either a browsing context id, or a BiDi serialized window. In the latter case, the
# value is extracted from the serialized object.
if isinstance(context, str):
contexts.append(context)
elif isinstance(context, webdriver.bidi.protocol.BidiWindow):
contexts.append(context.browsing_context)
else:
raise ValueError("Unexpected context type: %s" % context)
if len(contexts) == 0:
raise ValueError("At least one context must be provided")

return await self.protocol.bidi_emulation.set_geolocation_override(
coordinates, contexts)


class BidiSessionSubscribeAction:
name = "bidi.session.subscribe"

Expand Down Expand Up @@ -133,5 +161,6 @@ async def __call__(self, payload):
BidiBluetoothHandleRequestDevicePrompt,
BidiBluetoothSimulateAdapterAction,
BidiBluetoothSimulatePreconnectedPeripheralAction,
BidiEmulationSetGeolocationOverrideAction,
BidiPermissionsSetPermissionAction,
BidiSessionSubscribeAction]
15 changes: 15 additions & 0 deletions tools/wptrunner/wptrunner/executors/executorwebdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
VirtualSensorProtocolPart,
BidiBluetoothProtocolPart,
BidiBrowsingContextProtocolPart,
BidiEmulationProtocolPart,
BidiEventsProtocolPart,
BidiPermissionsProtocolPart,
BidiScriptProtocolPart,
Expand Down Expand Up @@ -263,6 +264,19 @@ async def call_function(self, function_declaration, target, arguments=None):
await_promise=True)


class WebDriverBidiEmulationProtocolPart(BidiEmulationProtocolPart):
def __init__(self, parent):
super().__init__(parent)
self.webdriver = None

def setup(self):
self.webdriver = self.parent.webdriver

async def set_geolocation_override(self, coordinates, contexts):
return await self.webdriver.bidi_session.emulation.set_geolocation_override(
coordinates=coordinates, contexts=contexts)


class WebDriverBidiPermissionsProtocolPart(BidiPermissionsProtocolPart):
def __init__(self, parent):
super().__init__(parent)
Expand Down Expand Up @@ -810,6 +824,7 @@ class WebDriverBidiProtocol(WebDriverProtocol):
enable_bidi = True
implements = [WebDriverBidiBluetoothProtocolPart,
WebDriverBidiBrowsingContextProtocolPart,
WebDriverBidiEmulationProtocolPart,
WebDriverBidiEventsProtocolPart,
WebDriverBidiPermissionsProtocolPart,
WebDriverBidiScriptProtocolPart,
Expand Down
12 changes: 12 additions & 0 deletions tools/wptrunner/wptrunner/executors/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,18 @@ async def set_permission(self, descriptor, state, origin):
pass


class BidiEmulationProtocolPart(ProtocolPart):
"""Protocol part for emulation"""
__metaclass__ = ABCMeta
name = "bidi_emulation"

@abstractmethod
async def set_geolocation_override(self,
coordinates: Optional[Mapping[str, Any]],
contexts: List[str]) -> None:
pass


class BidiScriptProtocolPart(ProtocolPart):
"""Protocol part for executing BiDi scripts"""
__metaclass__ = ABCMeta
Expand Down
11 changes: 11 additions & 0 deletions tools/wptrunner/wptrunner/testdriver-extra.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,17 @@
'bluetooth.requestDevicePromptUpdated', on_event);
};

window.test_driver_internal.bidi.emulation.set_geolocation_override =
function (params) {
return create_action("bidi.emulation.set_geolocation_override", {
// Default to the current window.
contexts: [window],
// Default to no coordinates.
coordinates: null,
...(params ?? {})
});
}

window.test_driver_internal.bidi.log.entry_added.subscribe =
function (params) {
return subscribe({
Expand Down