Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit e7a1c49

Browse files
chengweih001moz-wptsync-bot
authored andcommitted
Bug 1946336 [wpt PR 50518] - [testdriver] Add some test_driver.bidi.bluetooth commands and event, a=testonly
Automatic update from web-platform-tests [testdriver] Add some test_driver.bidi.bluetooth commands and event (#50518) Add the following WebDriver BiDi commands and event and extend the documentation: - `test_driver.bidi.bluetooth.simulatePreconnectedPeripheral` method matching [`bluetooth.simulatePreconnectedPeripheral`](https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command) - `test_driver.bidi.bluetooth.handleRequestDevicePrompt` method matching [`bluetooth.handleRequestDevicePrompt`](https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-handlerequestdeviceprompt-command) - `test_driver.bidi.bluetooth.requestDevicePromptUpdated` method matching [`bluetooth.requestDevicePromptUpdated`](https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-requestdevicepromptupdated-event) -- wpt-commits: beb1a3808c4acd66198d3dc69176c31f0cc81474 wpt-pr: 50518
1 parent 4f0da8d commit e7a1c49

File tree

15 files changed

+648
-3
lines changed

15 files changed

+648
-3
lines changed

testing/web-platform/tests/docs/writing-tests/testdriver.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,5 +302,8 @@ const event = await log_entry_promise;
302302
The module provides access to [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth).
303303

304304
```eval_rst
305+
.. js:autofunction:: test_driver.bidi.bluetooth.handle_request_device_prompt
305306
.. js:autofunction:: test_driver.bidi.bluetooth.simulate_adapter
307+
.. js:autofunction:: test_driver.bidi.bluetooth.simulate_preconnected_peripheral
308+
.. js:autofunction:: test_driver.bidi.bluetooth.request_device_prompt_updated
306309
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
disabled:
2+
if product != "chrome": @True
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
disabled:
2+
if product != "chrome": @True
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8"/>
3+
<title>TestDriver bidi.bluetooth.handle_request_device_prompt method</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/resources/testdriver.js?feature=bidi"></script>
7+
<script src="/resources/testdriver-vendor.js"></script>
8+
<script src="resources/bidi-bluetooth-helper.js"></script>
9+
10+
<script>
11+
const name = 'LE Device';
12+
promise_setup(async () => {
13+
await test_driver.bidi.bluetooth.simulate_adapter({
14+
state: "powered-on"
15+
});
16+
await test_driver.bidi.bluetooth.simulate_preconnected_peripheral({
17+
address: "09:09:09:09:09:09",
18+
name: name,
19+
manufacturerData: [],
20+
knownServiceUuids: []
21+
});
22+
await test_driver.bidi.bluetooth.request_device_prompt_updated.subscribe();
23+
});
24+
25+
promise_test(async (t) => {
26+
const handle_prompt_promise =
27+
test_driver.bidi.bluetooth.request_device_prompt_updated.once().then(
28+
(promptEvent) => {
29+
assert_greater_than_equal(promptEvent.devices.length, 0);
30+
return test_driver.bidi.bluetooth.handle_request_device_prompt({
31+
prompt: promptEvent.prompt,
32+
accept: true,
33+
device: promptEvent.devices[0].id
34+
});
35+
});
36+
const [device] = await Promise.all([requestDeviceWithTrustedClick({
37+
acceptAllDevices: true
38+
}), handle_prompt_promise]);
39+
assert_equals(device.name, name);
40+
}, "accept upon request_device_prompt_updated event");
41+
42+
promise_test(async (t) => {
43+
const handle_prompt_promise =
44+
test_driver.bidi.bluetooth.request_device_prompt_updated.once().then(
45+
(promptEvent) => {
46+
return test_driver.bidi.bluetooth.handle_request_device_prompt({
47+
prompt: promptEvent.prompt,
48+
accept: false,
49+
device: ''
50+
});
51+
});
52+
return Promise.all([
53+
promise_rejects_dom(t, 'NotFoundError',
54+
requestDeviceWithTrustedClick(
55+
{ acceptAllDevices: true })
56+
), handle_prompt_promise]);
57+
}, "cancel upon request_device_prompt_updated event");
58+
</script>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
'use strict';
2+
3+
/**
4+
* Waits until the document has finished loading.
5+
* @returns {Promise<void>} Resolves if the document is already completely
6+
* loaded or when the 'onload' event is fired.
7+
*/
8+
function waitForDocumentReady() {
9+
return new Promise(resolve => {
10+
if (document.readyState === 'complete') {
11+
resolve();
12+
}
13+
14+
window.addEventListener('load', () => {
15+
resolve();
16+
}, {once: true});
17+
});
18+
}
19+
20+
/**
21+
* Simulates a user activation prior to running |callback|.
22+
* @param {Function} callback The function to run after the user activation.
23+
* @returns {Promise<*>} Resolves when the user activation has been simulated
24+
* with the result of |callback|.
25+
*/
26+
async function callWithTrustedClick(callback) {
27+
await waitForDocumentReady();
28+
return new Promise(resolve => {
29+
let button = document.createElement('button');
30+
button.textContent = 'click to continue test';
31+
button.style.display = 'block';
32+
button.style.fontSize = '20px';
33+
button.style.padding = '10px';
34+
button.onclick = () => {
35+
document.body.removeChild(button);
36+
resolve(callback());
37+
};
38+
document.body.appendChild(button);
39+
test_driver.click(button);
40+
});
41+
}
42+
43+
/**
44+
* Register a one-time handler that selects the first device in the device
45+
* prompt upon a device prompt updated event.
46+
* @returns {Promise} fulfilled after the bluetooth device prompt
47+
* is handled, or rejected if the operation fails.
48+
*/
49+
function selectFirstDeviceOnDevicePromptUpdated() {
50+
return test_driver.bidi.bluetooth.request_device_prompt_updated.once().then(
51+
(promptEvent) => {
52+
assert_greater_than_equal(promptEvent.devices.length, 0);
53+
return test_driver.bidi.bluetooth.handle_request_device_prompt({
54+
prompt: promptEvent.prompt,
55+
accept: true,
56+
device: promptEvent.devices[0].id
57+
});
58+
});
59+
}
60+
61+
/**
62+
* Calls requestDevice() in a context that's 'allowed to show a popup'.
63+
* @returns {Promise<BluetoothDevice>} Resolves with a Bluetooth device if
64+
* successful or rejects with an error.
65+
*/
66+
function requestDeviceWithTrustedClick(...args) {
67+
return callWithTrustedClick(
68+
() => navigator.bluetooth.requestDevice(...args));
69+
}
70+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8"/>
3+
<title>TestDriver bidi.bluetooth.simulate_preconnected_peripheral method</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script src="/resources/testdriver.js?feature=bidi"></script>
7+
<script src="/resources/testdriver-vendor.js"></script>
8+
<script src="resources/bidi-bluetooth-helper.js"></script>
9+
10+
<script>
11+
promise_setup(async () => {
12+
await test_driver.bidi.bluetooth.simulate_adapter({
13+
state: "powered-on"
14+
});
15+
await test_driver.bidi.bluetooth.request_device_prompt_updated.subscribe();
16+
});
17+
18+
promise_test(async (t) => {
19+
const name = 'LE Device';
20+
await test_driver.bidi.bluetooth.simulate_preconnected_peripheral({
21+
address: "09:09:09:09:09:09",
22+
name: name,
23+
manufacturerData: [],
24+
knownServiceUuids: []
25+
});
26+
const handle_prompt_promise = selectFirstDeviceOnDevicePromptUpdated();
27+
const [device] = await Promise.all([requestDeviceWithTrustedClick({
28+
acceptAllDevices: true
29+
}), handle_prompt_promise]);
30+
assert_equals(device.name, name);
31+
}, "simulate a preconnected peripheral.");
32+
</script>
33+

testing/web-platform/tests/resources/testdriver.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,42 @@
8282
* `bluetooth <https://webbluetoothcg.github.io/web-bluetooth>`_ module.
8383
*/
8484
bluetooth: {
85+
/**
86+
* Handle a bluetooth device prompt with the given params. Matches the
87+
* `bluetooth.handleRequestDevicePrompt
88+
* <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-handlerequestdeviceprompt-command>`_
89+
* WebDriver BiDi command.
90+
*
91+
* @example
92+
* await test_driver.bidi.bluetooth.handleRequestDevicePrompt({
93+
* prompt: "pmt-e0a234b",
94+
* accept: true,
95+
* device: "dvc-9b3b872"
96+
* });
97+
*
98+
* @param {object} params - Parameters for the command.
99+
* @param {string} params.prompt - The id of a bluetooth device prompt.
100+
* Matches the
101+
* `bluetooth.HandleRequestDevicePromptParameters:prompt <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-handlerequestdeviceprompt-command>`_
102+
* value.
103+
* @param {bool} params.accept - Whether to accept a bluetooth device prompt.
104+
* Matches the
105+
* `bluetooth.HandleRequestDevicePromptAcceptParameters:accept <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-handlerequestdeviceprompt-command>`_
106+
* value.
107+
* @param {string} params.device - The device id from a bluetooth device
108+
* prompt to be accepted. Matches the
109+
* `bluetooth.HandleRequestDevicePromptAcceptParameters:device <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-handlerequestdeviceprompt-command>`_
110+
* value.
111+
* @param {Context} [params.context] The optional context parameter specifies in
112+
* which browsing context the bluetooth device prompt should be handled. If not
113+
* provided, the current browsing context is used.
114+
* @returns {Promise} fulfilled after the bluetooth device prompt
115+
* is handled, or rejected if the operation fails.
116+
*/
117+
handle_request_device_prompt: function(params) {
118+
return window.test_driver_internal.bidi.bluetooth
119+
.handle_request_device_prompt(params);
120+
},
85121
/**
86122
* Creates a simulated bluetooth adapter with the given params. Matches the
87123
* `bluetooth.simulateAdapter <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateAdapter-command>`_
@@ -105,6 +141,116 @@
105141
*/
106142
simulate_adapter: function (params) {
107143
return window.test_driver_internal.bidi.bluetooth.simulate_adapter(params);
144+
},
145+
/**
146+
* Creates a simulated bluetooth peripheral with the given params.
147+
* Matches the
148+
* `bluetooth.simulatePreconnectedPeripheral <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command>`_
149+
* WebDriver BiDi command.
150+
*
151+
* @example
152+
* await test_driver.bidi.bluetooth.simulatePreconnectedPeripheral({
153+
* "address": "09:09:09:09:09:09",
154+
* "name": "Some Device",
155+
* "manufacturerData": [{key: 17, data: "AP8BAX8="}],
156+
* "knownServiceUuids": [
157+
* "12345678-1234-5678-9abc-def123456789",
158+
* ],
159+
* });
160+
*
161+
* @param {object} params - Parameters for the command.
162+
* @param {string} params.address - The address of the simulated
163+
* bluetooth peripheral. Matches the
164+
* `bluetooth.SimulatePreconnectedPeripheralParameters:address <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command>`_
165+
* value.
166+
* @param {string} params.name - The name of the simulated bluetooth
167+
* peripheral. Matches the
168+
* `bluetooth.SimulatePreconnectedPeripheralParameters:name <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command>`_
169+
* value.
170+
* @param {Array.ManufacturerData} params.manufacturerData - The manufacturerData of the
171+
* simulated bluetooth peripheral. Matches the
172+
* `bluetooth.SimulatePreconnectedPeripheralParameters:manufacturerData <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command>`_
173+
* value.
174+
* @param {string} params.knownServiceUuids - The knownServiceUuids of
175+
* the simulated bluetooth peripheral. Matches the
176+
* `bluetooth.SimulatePreconnectedPeripheralParameters:knownServiceUuids <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-simulateconnectedperipheral-command>`_
177+
* value.
178+
* @param {Context} [params.context] The optional context parameter
179+
* specifies in which browsing context the simulated bluetooth peripheral should be
180+
* set. If not provided, the current browsing context is used.
181+
* @returns {Promise} fulfilled after the simulated bluetooth peripheral is created
182+
* and set, or rejected if the operation fails.
183+
*/
184+
simulate_preconnected_peripheral: function(params) {
185+
return window.test_driver_internal.bidi.bluetooth
186+
.simulate_preconnected_peripheral(params);
187+
},
188+
/**
189+
* `bluetooth.RequestDevicePromptUpdatedParameters <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-requestdevicepromptupdated-event>`_
190+
* event.
191+
*/
192+
request_device_prompt_updated: {
193+
/**
194+
* @typedef {object} RequestDevicePromptUpdated
195+
* `bluetooth.RequestDevicePromptUpdatedParameters <https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-requestdevicepromptupdated-event>`_
196+
* event.
197+
*/
198+
199+
/**
200+
* Subscribes to the event. Events will be emitted only if
201+
* there is a subscription for the event. This method does
202+
* not add actual listeners. To listen to the event, use the
203+
* `on` or `once` methods. The buffered events will be
204+
* emitted before the command promise is resolved.
205+
*
206+
* @param {object} [params] Parameters for the subscription.
207+
* @param {null|Array.<(Context)>} [params.contexts] The
208+
* optional contexts parameter specifies which browsing
209+
* contexts to subscribe to the event on. It should be
210+
* either an array of Context objects, or null. If null, the
211+
* event will be subscribed to globally. If omitted, the
212+
* event will be subscribed to on the current browsing
213+
* context.
214+
* @returns {Promise<void>} Resolves when the subscription
215+
* is successfully done.
216+
*/
217+
subscribe: async function(params = {}) {
218+
assertBidiIsEnabled();
219+
return window.test_driver_internal.bidi.bluetooth
220+
.request_device_prompt_updated.subscribe(params);
221+
},
222+
/**
223+
* Adds an event listener for the event.
224+
*
225+
* @param {function(RequestDevicePromptUpdated): void} callback The
226+
* callback to be called when the event is emitted. The
227+
* callback is called with the event object as a parameter.
228+
* @returns {function(): void} A function that removes the
229+
* added event listener when called.
230+
*/
231+
on: function(callback) {
232+
assertBidiIsEnabled();
233+
return window.test_driver_internal.bidi.bluetooth
234+
.request_device_prompt_updated.on(callback);
235+
},
236+
/**
237+
* Adds an event listener for the event that is only called
238+
* once and removed afterward.
239+
*
240+
* @return {Promise<RequestDevicePromptUpdated>} The promise which
241+
* is resolved with the event object when the event is emitted.
242+
*/
243+
once: function() {
244+
assertBidiIsEnabled();
245+
return new Promise(resolve => {
246+
const remove_handler =
247+
window.test_driver_internal.bidi.bluetooth
248+
.request_device_prompt_updated.on(event => {
249+
resolve(event);
250+
remove_handler();
251+
});
252+
});
253+
},
108254
}
109255
},
110256
/**
@@ -1340,9 +1486,27 @@
13401486

13411487
bidi: {
13421488
bluetooth: {
1489+
handle_request_device_prompt: function() {
1490+
throw new Error(
1491+
'bidi.bluetooth.handle_request_device_prompt is not implemented by testdriver-vendor.js');
1492+
},
13431493
simulate_adapter: function () {
13441494
throw new Error(
13451495
"bidi.bluetooth.simulate_adapter is not implemented by testdriver-vendor.js");
1496+
},
1497+
simulate_preconnected_peripheral: function() {
1498+
throw new Error(
1499+
'bidi.bluetooth.simulate_preconnected_peripheral is not implemented by testdriver-vendor.js');
1500+
},
1501+
request_device_prompt_updated: {
1502+
async subscribe() {
1503+
throw new Error(
1504+
'bidi.bluetooth.request_device_prompt_updated.subscribe is not implemented by testdriver-vendor.js');
1505+
},
1506+
on() {
1507+
throw new Error(
1508+
'bidi.bluetooth.request_device_prompt_updated.on is not implemented by testdriver-vendor.js');
1509+
}
13461510
}
13471511
},
13481512
log: {

0 commit comments

Comments
 (0)