blob: efd10a41f8c48974a0c71fe64f36ebe6332b0641 [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(function(t) { assert_true(window.testRunner instanceof Object); t.done(); },
'window.testRunner is required for the following tests.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('EmptyAdapter');
return assert_promise_rejects(requestDeviceWithKeyDown(),
new TypeError());
}, 'Requires an argument.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('EmptyAdapter');
return assert_promise_rejects(requestDeviceWithKeyDown({}),
new TypeError());
}, 'RequestDeviceOptions requires a |filters| member.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('FailStartDiscoveryAdapter');
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(() => {
testRunner.setBluetoothMockDataSet('NotPresentAdapter');
return assert_promise_rejects_with_message(
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
{name: 'NotFoundError', message: 'Bluetooth adapter not available.'},
'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()
.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.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('EmptyAdapter');
return assert_promise_rejects_with_message(
requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]}),
{name: 'NotFoundError', message: 'User cancelled the requestDevice() chooser.'},
'No Bluetooth devices in range.');
}, 'Reject with NotFoundError if there are no devices around.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
return Promise.all([
requestDeviceWithKeyDown({filters: [{services: [generic_access.alias]}]}),
requestDeviceWithKeyDown({filters: [{services: [generic_access.name]}]}),
requestDeviceWithKeyDown({filters: [{services: [generic_access.uuid]}]})
]).then(devices => {
devices.forEach(device => {
assert_equals(device.constructor.name, 'BluetoothDevice');
});
});
}, 'Mock will resolve.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
return assert_promise_rejects(
navigator.bluetooth.requestDevice({filters: [{services: ['generic_access']}]}),
'SecurityError');
}, 'Requires a user gesture.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
return callWithKeyDown(() => {
var first = navigator.bluetooth.requestDevice({filters: [{services: ['generic_access']}]});
var second = navigator.bluetooth.requestDevice({filters: [{services: ['generic_access']}]});
return Promise.all([
first.then(device => assert_equals(device.constructor.name, 'BluetoothDevice')),
assert_promise_rejects(second, 'SecurityError'),
]);
});
}, 'Consumes a user gesture.');
promise_test(() => {
testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
return Promise.all([
requestDeviceWithKeyDown({filters: [{services: [generic_access.alias]}]}),
requestDeviceWithKeyDown({filters: [{services: [generic_access.name]}]}),
requestDeviceWithKeyDown({filters: [{services: [generic_access.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.name]
});
}, '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: ['generic_access', 'heart_rate']}]
}).then(device => assert_equals(device.name, 'Heart Rate 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: ['generic_access', 'battery_service']}]
}), 'NotFoundError');
}, 'Too-strict filters do prevent matching.');
</script>