Test that the right events are sent to the Bluetooth chooser.
And that the chooser can control which device is returned from requestDevice().
Depends on https://codereview.chromium.org/1325953002 for testing functions, which are specified in https://webbluetoothcg.github.io/web-bluetooth/tests/.
BUG=500989
Review URL: https://codereview.chromium.org/1304353004
git-svn-id: svn://svn.chromium.org/blink/trunk@202647 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/LayoutTests/bluetooth/requestDevice.html b/LayoutTests/bluetooth/requestDevice.html
index 834bc70..efd10a4 100644
--- a/LayoutTests/bluetooth/requestDevice.html
+++ b/LayoutTests/bluetooth/requestDevice.html
@@ -21,14 +21,23 @@
new TypeError());
}, 'RequestDeviceOptions requires a |filters| member.');
-// TODO(jyasskin): Add a test that the chooser is informed of a failed discovery
-// session.
promise_test(() => {
testRunner.setBluetoothMockDataSet('FailStartDiscoveryAdapter');
- return assert_promise_rejects_with_message(
- requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
- {name: 'NotFoundError', message: 'User cancelled the requestDevice() chooser.'},
- 'The adapter failed to start a discovery session.');
+ testRunner.setBluetoothManualChooser();
+ let requestDevicePromise =
+ requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]});
+ return getBluetoothManualChooserEvents()
+ .then(events => {
+ assert_array_equals(events,
+ ['chooser-opened(file:///)',
+ 'discovering',
+ 'discovery-failed-to-start']);
+ testRunner.sendBluetoothManualChooserEvent('cancelled', '');
+ return assert_promise_rejects_with_message(
+ requestDevicePromise,
+ {name: 'NotFoundError', message: 'User cancelled the requestDevice() chooser.'},
+ 'The adapter failed to start a discovery session.');
+ });
}, 'Discovery session fails to start.');
promise_test(() => {
@@ -39,18 +48,24 @@
'Bluetooth adapter is not present.');
}, 'Reject with NotFoundError if the adapter is not present.');
-// TODO(jyasskin): Add a test that the chooser is informed of a disabled
-// Bluetooth adapter.
promise_test(() => {
testRunner.setBluetoothMockDataSet('NotPoweredAdapter');
- return assert_promise_rejects_with_message(
- requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
- {name: 'NotFoundError', message: 'User cancelled the requestDevice() chooser.'},
- 'Bluetooth adapter is not powered.');
+ testRunner.setBluetoothManualChooser();
+ let requestDevicePromise =
+ requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]});
+ return getBluetoothManualChooserEvents()
+ .then(events => {
+ assert_array_equals(events,
+ ['chooser-opened(file:///)',
+ 'adapter-disabled']);
+ testRunner.sendBluetoothManualChooserEvent('cancelled', '');
+ return assert_promise_rejects_with_message(
+ requestDevicePromise,
+ {name: 'NotFoundError', message: 'User cancelled the requestDevice() chooser.'},
+ 'Bluetooth adapter is not powered.');
+ });
}, 'Reject with NotFoundError if the adapter is off.');
-// TODO(jyasskin): Add a test that the chooser gets a full list of found
-// devices.
promise_test(() => {
testRunner.setBluetoothMockDataSet('EmptyAdapter');
return assert_promise_rejects_with_message(
@@ -123,6 +138,31 @@
promise_test(() => {
testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
+ testRunner.setBluetoothManualChooser();
+ let requestDevicePromise = requestDeviceWithKeyDown({
+ filters: [{services: ['glucose']},
+ {services: ['heart_rate']}]
+ });
+ return getBluetoothManualChooserEvents(5)
+ .then(events => {
+ assert_equals(events.length, 5, events);
+ assert_equals(events[0], 'chooser-opened(file:///)', 'events[0]');
+ let idsByName = new AddDeviceEventSet();
+ for (let addedDevice of [events[1], events[2]]) {
+ idsByName.assert_add_device_event(addedDevice);
+ }
+ assert_true(idsByName.has('Heart Rate Device'));
+ assert_true(idsByName.has('Glucose Device'));
+ assert_equals(events[3], 'discovering');
+ assert_equals(events[4], 'discovery-idle');
+ testRunner.sendBluetoothManualChooserEvent('selected',
+ idsByName.get('Glucose Device'));
+ return requestDevicePromise;
+ }).then(device => assert_equals(device.name, 'Glucose Device'));
+}, 'The chooser includes all devices.');
+
+promise_test(() => {
+ testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
return requestDeviceWithKeyDown({filters: [{services: ['glucose']}]})
.then(device => assert_equals(device.name, 'Glucose Device'));
}, 'Simple filter selects matching device.');
diff --git a/LayoutTests/bluetooth/resources/bluetooth-helpers.js b/LayoutTests/bluetooth/resources/bluetooth-helpers.js
index 0648804..af4654d 100644
--- a/LayoutTests/bluetooth/resources/bluetooth-helpers.js
+++ b/LayoutTests/bluetooth/resources/bluetooth-helpers.js
@@ -57,6 +57,26 @@
return callWithKeyDown(() => navigator.bluetooth.requestDevice.apply(navigator.bluetooth, args));
}
+// Calls testRunner.getBluetoothManualChooserEvents() until it's returned
+// |expected_count| events. Or just once if |expected_count| is undefined.
+function getBluetoothManualChooserEvents(expected_count) {
+ if (expected_count === undefined) {
+ expected_count = 0;
+ }
+ return new Promise((resolve, reject) => {
+ let events = [];
+ let accumulate_events = new_events => {
+ events.push(...new_events);
+ if (events.length >= expected_count) {
+ resolve(events);
+ } else {
+ testRunner.getBluetoothManualChooserEvents(accumulate_events);
+ }
+ };
+ testRunner.getBluetoothManualChooserEvents(accumulate_events);
+ });
+}
+
// errorUUID(alias) returns a UUID with the top 32 bits of
// '00000000-97e5-4cd7-b9f1-f5a427670c59' replaced with the bits of |alias|.
// For example, errorUUID(0xDEADBEEF) returns
@@ -85,3 +105,24 @@
}
});
}
+
+// Parses add-device(name)=id lines in
+// testRunner.getBluetoothManualChooserEvents() output, and exposes the name->id
+// mapping.
+class AddDeviceEventSet {
+ constructor() {
+ this._idsByName = new Map();
+ this._addDeviceRegex = /^add-device\(([^)]+)\)=(.+)$/;
+ }
+ assert_add_device_event(event, description) {
+ let match = this._addDeviceRegex.exec(event);
+ assert_true(!!match, event + "isn't an add-device event: " + description);
+ this._idsByName.set(match[1], match[2]);
+ }
+ has(name) {
+ return this._idsByName.has(name);
+ }
+ get(name) {
+ return this._idsByName.get(name);
+ }
+}