blob: de7ffc36910a267d4efea4a99f14c88309bcb89b [file] [log] [blame]
<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharness-helpers.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/bluetooth-helpers.js"></script>
<script>
'use strict';
test(t => { assert_true(window.testRunner instanceof Object); t.done(); },
'window.testRunner is required for the following tests.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('FailStartDiscoveryAdapter');
testRunner.setBluetoothManualChooser();
let requestDevicePromise =
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]});
return getBluetoothManualChooserEvents(3)
.then(events => {
assert_array_equals(events,
['chooser-opened(file:///)',
'discovering',
'discovery-failed-to-start'],
events);
testRunner.sendBluetoothManualChooserEvent('cancelled', '');
return assert_promise_rejects_with_message(
requestDevicePromise,
new DOMException('User cancelled the requestDevice() chooser.',
'NotFoundError'),
'The adapter failed to start a discovery session.');
});
}, 'Discovery session fails to start.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('NotPresentAdapter');
return assert_promise_rejects_with_message(
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
new DOMException('Bluetooth adapter not available.', 'NotFoundError'),
'Bluetooth adapter is not present.');
}, 'Reject with NotFoundError if the adapter is not present.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('NotPoweredAdapter');
testRunner.setBluetoothManualChooser();
let requestDevicePromise =
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]});
return getBluetoothManualChooserEvents(2)
.then(events => {
assert_array_equals(events,
['chooser-opened(file:///)',
'adapter-disabled'],
events);
testRunner.sendBluetoothManualChooserEvent('cancelled', '');
return assert_promise_rejects_with_message(
requestDevicePromise,
new DOMException('User cancelled the requestDevice() chooser.',
'NotFoundError'),
'Bluetooth adapter is not powered.');
});
}, 'Reject with NotFoundError if the adapter is off.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('EmptyAdapter');
return assert_promise_rejects_with_message(
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
new DOMException('User cancelled the requestDevice() chooser.',
'NotFoundError'),
'No Bluetooth devices in range.');
}, 'Reject with NotFoundError if there are no devices around.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('HeartRateAdapter');
return Promise.all([
requestDeviceWithKeyDown({filters: [{services: [heart_rate.alias]}]}),
requestDeviceWithKeyDown({filters: [{services: [heart_rate.name]}]}),
requestDeviceWithKeyDown({filters: [{services: [heart_rate.uuid]}]})
]).then(devices => {
devices.forEach(device => {
assert_equals(device.constructor.name, 'BluetoothDevice');
});
});
}, 'Mock will resolve.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('HeartRateAdapter');
return assert_promise_rejects(
navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]}),
new DOMException('', 'SecurityError'));
}, 'Requires a user gesture.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('HeartRateAdapter');
return callWithKeyDown(() => {
var first = navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
var second = navigator.bluetooth.requestDevice({filters: [{services: ['heart_rate']}]});
return Promise.all([
first.then(device => assert_equals(device.constructor.name, 'BluetoothDevice')),
assert_promise_rejects(second, new DOMException('', 'SecurityError')),
]);
});
}, 'Consumes a user gesture.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('HeartRateAdapter');
return Promise.all([
requestDeviceWithKeyDown({filters: [{services: [heart_rate.alias]}]}),
requestDeviceWithKeyDown({filters: [{services: [heart_rate.name]}]}),
requestDeviceWithKeyDown({filters: [{services: [heart_rate.uuid]}]})
]).then(devices => {
// requestDevice should return the same object if it was created
// earlier. https://crbug.com/495270
// TODO(ortuno): Change to assert_equals.
assert_not_equals(devices[0], devices[1]);
assert_not_equals(devices[1], devices[2]);
});
}, 'Returned device should always be the same.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('ScanFilterCheckingAdapter');
// The work of this test is done in the ScanFilterCheckingAdapter. It asserts
// that this requestDevice() call tells the platform to scan for only devices
// that include the Battery, Glucose, or Heart Rate services.
return requestDeviceWithKeyDown({
filters: [
{services: ['battery_service']},
{services: ['glucose', 'heart_rate']}
],
// The optionalServices shouldn't affect the platform's scan.
optionalServices: ['generic_access']
});
}, 'Filters restrict the platform\'s Bluetooth scan.');
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.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
return requestDeviceWithKeyDown({
filters: [{services: ['glucose', 'tx_power']}]
}).then(device => assert_equals(device.name, 'Glucose Device'));
}, 'Filter with 2 services returns a matching device.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
return requestDeviceWithKeyDown({
filters: [{services: ['battery_service']},
{services: ['heart_rate']}]
}).then(device => assert_equals(device.name, 'Heart Rate Device'));
}, 'An extra filter doesn\'t prevent matching.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GlucoseHeartRateAdapter');
// Both devices support the Generic Access service, but things need to
// support both services to pass the filter, and neither has a Battery
// service.
return assert_promise_rejects(requestDeviceWithKeyDown({
filters: [{services: ['heart_rate', 'battery_service']}]
}), new DOMException('', 'NotFoundError'));
}, 'Too-strict filters do prevent matching.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('SecondDiscoveryFindsHeartRateAdapter');
testRunner.setBluetoothManualChooser();
// Open the chooser, looking for a Heart Rate device.
let requestDevicePromise = requestDeviceWithKeyDown({
filters: [{services: ['heart_rate']}]
});
// The adapter finds nothing, so we just see discovery start and stop.
return getBluetoothManualChooserEvents(3).then(events => {
assert_array_equals(events,
['chooser-opened(file:///)',
'discovering',
'discovery-idle',
]);
// On the second discovery, the adapter finds the Heart Rate device.
testRunner.sendBluetoothManualChooserEvent('rescan', '');
return getBluetoothManualChooserEvents(3);
}).then(events => {
assert_equals(events.length, 3, events);
assert_equals(events[0], 'discovering', 'events[0]');
let idsByName = new AddDeviceEventSet();
idsByName.assert_add_device_event(events[1]);
assert_true(idsByName.has('Heart Rate Device'));
assert_equals(events[2], 'discovery-idle');
// Select it and let the test complete.
testRunner.sendBluetoothManualChooserEvent('selected',
idsByName.get('Heart Rate Device'));
return requestDevicePromise;
}).then(device => assert_equals(device.name, 'Heart Rate Device'));
}, 'The chooser can restart the BT scan.');
</script>