| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE html> | |
| 2 <script src="../resources/testharness.js"></script> | |
| 3 <script src="../resources/testharnessreport.js"></script> | |
| 4 <script src="../resources/bluetooth/bluetooth-helpers.js"></script> | |
| 5 <script> | |
| 6 'use strict'; | |
| 7 | |
| 8 test(t => { assert_true(window.testRunner instanceof Object); t.done(); }, | |
| 9 'window.testRunner is required for the following tests.'); | |
| 10 | |
| 11 promise_test(() => { | |
| 12 testRunner.setBluetoothManualChooser(true); | |
| 13 let requestDevicePromise = | |
| 14 setBluetoothFakeAdapter('FailStartDiscoveryAdapter') | |
| 15 .then(() => requestDeviceWithKeyDown({ | |
| 16 filters: [{services: ['generic_access']}]})); | |
| 17 return getBluetoothManualChooserEvents(3) | |
| 18 .then(events => { | |
| 19 assert_array_equals(events, | |
| 20 ['chooser-opened(file://)', | |
| 21 'discovering', | |
| 22 'discovery-failed-to-start'], | |
| 23 events); | |
| 24 testRunner.sendBluetoothManualChooserEvent('cancelled', ''); | |
| 25 return assert_promise_rejects_with_message( | |
| 26 requestDevicePromise, | |
| 27 new DOMException('User cancelled the requestDevice() chooser.', | |
| 28 'NotFoundError'), | |
| 29 'The adapter failed to start a discovery session.'); | |
| 30 }); | |
| 31 }, 'Discovery session fails to start.'); | |
| 32 | |
| 33 promise_test(() => { | |
| 34 return setBluetoothFakeAdapter('NotPresentAdapter') | |
| 35 .then(() => assert_promise_rejects_with_message( | |
| 36 requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}), | |
| 37 new DOMException('Bluetooth adapter not available.', 'NotFoundError'), | |
| 38 'Bluetooth adapter is not present.')); | |
| 39 }, 'Reject with NotFoundError if the adapter is not present.'); | |
| 40 | |
| 41 promise_test(() => { | |
| 42 testRunner.setBluetoothManualChooser(true); | |
| 43 let requestDevicePromise = | |
| 44 setBluetoothFakeAdapter('NotPoweredAdapter') | |
| 45 .then(() => requestDeviceWithKeyDown({ | |
| 46 filters: [{services: ['generic_access']}]})); | |
| 47 return getBluetoothManualChooserEvents(2) | |
| 48 .then(events => { | |
| 49 assert_array_equals(events, | |
| 50 ['chooser-opened(file://)', | |
| 51 'adapter-disabled'], | |
| 52 events); | |
| 53 testRunner.sendBluetoothManualChooserEvent('cancelled', ''); | |
| 54 return assert_promise_rejects_with_message( | |
| 55 requestDevicePromise, | |
| 56 new DOMException('User cancelled the requestDevice() chooser.', | |
| 57 'NotFoundError'), | |
| 58 'Bluetooth adapter is not powered.'); | |
| 59 }); | |
| 60 }, 'Reject with NotFoundError if the adapter is off.'); | |
| 61 | |
| 62 promise_test(() => { | |
| 63 return setBluetoothFakeAdapter('EmptyAdapter') | |
| 64 .then(() => assert_promise_rejects_with_message( | |
| 65 requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}), | |
| 66 new DOMException('User cancelled the requestDevice() chooser.', | |
| 67 'NotFoundError'), | |
| 68 'No Bluetooth devices in range.')); | |
| 69 }, 'Reject with NotFoundError if there are no devices around.'); | |
| 70 | |
| 71 promise_test(() => { | |
| 72 return setBluetoothFakeAdapter('HeartRateAdapter') | |
| 73 .then(() => Promise.all([ | |
| 74 requestDeviceWithKeyDown({filters: [{services: [heart_rate.alias]}]}), | |
| 75 requestDeviceWithKeyDown({filters: [{services: [heart_rate.name]}]}), | |
| 76 requestDeviceWithKeyDown({filters: [{services: [heart_rate.uuid]}]}) | |
| 77 ])).then(devices => { | |
| 78 devices.forEach(device => { | |
| 79 assert_equals(device.constructor.name, 'BluetoothDevice'); | |
| 80 }); | |
| 81 }); | |
| 82 }, 'Mock will resolve.'); | |
| 83 | |
| 84 promise_test(t => { | |
| 85 return setBluetoothFakeAdapter('HeartRateAdapter') | |
| 86 .then(() => promise_rejects(t, | |
| 87 'SecurityError', | |
| 88 navigator.bluetooth.requestDevice({ | |
| 89 filters: [{services: ['heart_rate']}]}))); | |
| 90 }, 'Requires a user gesture.'); | |
| 91 | |
| 92 promise_test(t => { | |
| 93 return setBluetoothFakeAdapter('HeartRateAdapter') | |
| 94 .then(() => callWithKeyDown(() => { | |
| 95 var first = navigator.bluetooth.requestDevice({ | |
| 96 filters: [{services: ['heart_rate']}]}); | |
| 97 var second = navigator.bluetooth.requestDevice({ | |
| 98 filters: [{services: ['heart_rate']}]}); | |
| 99 return Promise.all([ | |
| 100 first.then(device => assert_equals( | |
| 101 device.constructor.name, 'BluetoothDevice')), | |
| 102 promise_rejects(t, 'SecurityError', second), | |
| 103 ]); | |
| 104 })); | |
| 105 }, 'Consumes a user gesture.'); | |
| 106 | |
| 107 promise_test(() => { | |
| 108 return setBluetoothFakeAdapter('HeartRateAdapter') | |
| 109 .then(() => Promise.all([ | |
| 110 requestDeviceWithKeyDown({filters: [{services: [heart_rate.alias]}]}), | |
| 111 requestDeviceWithKeyDown({filters: [{services: [heart_rate.name]}]}), | |
| 112 requestDeviceWithKeyDown({filters: [{services: [heart_rate.uuid]}]}) | |
| 113 ])).then(devices => { | |
| 114 // requestDevice should return the same object if it was created | |
| 115 // earlier. https://crbug.com/495270 | |
| 116 // TODO(ortuno): Change to assert_equals. | |
| 117 assert_not_equals(devices[0], devices[1]); | |
| 118 assert_not_equals(devices[1], devices[2]); | |
| 119 }); | |
| 120 }, 'Returned device should always be the same.'); | |
| 121 | |
| 122 promise_test(() => { | |
| 123 // The work of this test is done in the ScanFilterCheckingAdapter. It asserts | |
| 124 // that this requestDevice() call tells the platform to scan for only devices | |
| 125 // that include the Battery, Glucose, or Heart Rate services. | |
| 126 return setBluetoothFakeAdapter('ScanFilterCheckingAdapter') | |
| 127 .then(() => requestDeviceWithKeyDown({ | |
| 128 filters: [{services: ['battery_service']}, | |
| 129 {services: ['glucose', 'heart_rate']}], | |
| 130 // The optionalServices shouldn't affect the platform's scan. | |
| 131 optionalServices: ['generic_access'] | |
| 132 })); | |
| 133 }, 'Filters restrict the platform\'s Bluetooth scan.'); | |
| 134 | |
| 135 promise_test(() => { | |
| 136 testRunner.setBluetoothManualChooser(true); | |
| 137 let requestDevicePromise = | |
| 138 setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 139 .then(() => requestDeviceWithKeyDown({ | |
| 140 filters: [{services: ['glucose']}, | |
| 141 {services: ['heart_rate']}] | |
| 142 })); | |
| 143 return getBluetoothManualChooserEvents(5) | |
| 144 .then(events => { | |
| 145 assert_equals(events.length, 5, events); | |
| 146 assert_equals(events[0], 'chooser-opened(file://)', 'events[0]'); | |
| 147 let idsByName = new AddDeviceEventSet(); | |
| 148 for (let addedDevice of [events[1], events[2]]) { | |
| 149 idsByName.assert_add_device_event(addedDevice); | |
| 150 } | |
| 151 assert_true(idsByName.has('Heart Rate Device')); | |
| 152 assert_true(idsByName.has('Glucose Device')); | |
| 153 assert_equals(events[3], 'discovering'); | |
| 154 assert_equals(events[4], 'discovery-idle'); | |
| 155 testRunner.sendBluetoothManualChooserEvent('selected', | |
| 156 idsByName.get('Glucose Device')
); | |
| 157 return requestDevicePromise; | |
| 158 }).then(device => assert_equals(device.name, 'Glucose Device')); | |
| 159 }, 'The chooser includes all devices.'); | |
| 160 | |
| 161 promise_test(() => { | |
| 162 return setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 163 .then(() => requestDeviceWithKeyDown({ | |
| 164 filters: [{services: ['glucose']}]})) | |
| 165 .then(device => assert_equals(device.name, 'Glucose Device')); | |
| 166 }, 'Simple filter selects matching device.'); | |
| 167 | |
| 168 promise_test(() => { | |
| 169 return setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 170 .then(() => requestDeviceWithKeyDown({ | |
| 171 filters: [{services: ['glucose', 'tx_power']}] | |
| 172 })).then(device => assert_equals(device.name, 'Glucose Device')); | |
| 173 }, 'Filter with 2 services returns a matching device.'); | |
| 174 | |
| 175 promise_test(() => { | |
| 176 return setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 177 .then(() => requestDeviceWithKeyDown({ | |
| 178 filters: [{services: ['battery_service']}, | |
| 179 {services: ['heart_rate']}] | |
| 180 })).then(device => assert_equals(device.name, 'Heart Rate Device')); | |
| 181 }, 'An extra filter doesn\'t prevent matching.'); | |
| 182 | |
| 183 promise_test(() => { | |
| 184 return setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 185 .then(() => requestDeviceWithKeyDown({ | |
| 186 filters: [{services: ['glucose']}], | |
| 187 optionalServices: ['tx_power']})) | |
| 188 .then(device => { | |
| 189 assert_equals(device.uuids.length, 2); | |
| 190 assert_in_array(BluetoothUUID.getService('glucose'), device.uuids); | |
| 191 assert_in_array(BluetoothUUID.getService('tx_power'), device.uuids); | |
| 192 }); | |
| 193 }, 'We should only see UUID\'s that we\'ve been given permission for.') | |
| 194 | |
| 195 | |
| 196 promise_test(t => { | |
| 197 // Both devices support the Generic Access service, but things need to | |
| 198 // support both services to pass the filter, and neither has a Battery | |
| 199 // service. | |
| 200 return setBluetoothFakeAdapter('GlucoseHeartRateAdapter') | |
| 201 .then(() => promise_rejects(t, 'NotFoundError', | |
| 202 requestDeviceWithKeyDown({ | |
| 203 filters: [{services: ['heart_rate', 'battery_service']}] | |
| 204 }))); | |
| 205 }, 'Too-strict filters do prevent matching.'); | |
| 206 | |
| 207 promise_test(() => { | |
| 208 testRunner.setBluetoothManualChooser(true); | |
| 209 | |
| 210 // Open the chooser, looking for a Heart Rate device. | |
| 211 let requestDevicePromise = | |
| 212 setBluetoothFakeAdapter('SecondDiscoveryFindsHeartRateAdapter') | |
| 213 .then(() => requestDeviceWithKeyDown({ | |
| 214 filters: [{services: ['heart_rate']}] | |
| 215 })); | |
| 216 | |
| 217 // The adapter finds nothing, so we just see discovery start and stop. | |
| 218 return getBluetoothManualChooserEvents(3).then(events => { | |
| 219 assert_array_equals(events, | |
| 220 ['chooser-opened(file://)', | |
| 221 'discovering', | |
| 222 'discovery-idle', | |
| 223 ]); | |
| 224 | |
| 225 // On the second discovery, the adapter finds the Heart Rate device. | |
| 226 testRunner.sendBluetoothManualChooserEvent('rescan', ''); | |
| 227 return getBluetoothManualChooserEvents(3); | |
| 228 }).then(events => { | |
| 229 assert_equals(events.length, 3, events); | |
| 230 assert_equals(events[0], 'discovering', 'events[0]'); | |
| 231 let idsByName = new AddDeviceEventSet(); | |
| 232 idsByName.assert_add_device_event(events[1]); | |
| 233 assert_true(idsByName.has('Heart Rate Device')); | |
| 234 assert_equals(events[2], 'discovery-idle'); | |
| 235 | |
| 236 // Select it and let the test complete. | |
| 237 testRunner.sendBluetoothManualChooserEvent('selected', | |
| 238 idsByName.get('Heart Rate Device'
)); | |
| 239 return requestDevicePromise; | |
| 240 }).then(device => assert_equals(device.name, 'Heart Rate Device')); | |
| 241 }, 'The chooser can restart the BT scan.'); | |
| 242 </script> | |
| OLD | NEW |