2 <script src=
"../resources/testharness.js"></script>
3 <script src=
"../resources/testharnessreport.js"></script>
4 <script src=
"resources/bluetooth-helpers.js"></script>
8 test(function(t
) { assert_exists(window
, 'testRunner'); t
.done(); },
9 'window.testRunner is required for the following tests.');
12 testRunner
.setBluetoothMockDataSet('GenericAccessAdapter');
13 return requestDeviceWithKeyDown({filters
: [{services
: ['generic_access']}]})
14 .then(device
=> device
.connectGATT())
15 .then(gattServer
=> gattServer
.getPrimaryService('generic_access'))
16 .then(service
=> service
.getCharacteristic('gap.device_name'))
17 .then(characteristic
=> {
18 testRunner
.setBluetoothMockDataSet('EmptyAdapter');
19 return assert_promise_rejects_with_message(
20 characteristic
.writeValue(new ArrayBuffer(1 /* length */)), {
22 message
: 'Bluetooth Device is no longer in range.'
23 }, 'Device went out of range.');
25 }, 'Device goes out of range. Reject with NetworkError.');
28 testRunner
.setBluetoothMockDataSet('GenericAccessAdapter');
29 return requestDeviceWithKeyDown({filters
: [{services
: ['generic_access']}]})
30 .then(device
=> device
.connectGATT())
31 .then(gattServer
=> gattServer
.getPrimaryService('generic_access'))
32 .then(service
=> service
.getCharacteristic('gap.device_name'))
33 .then(characteristic
=> {
34 testRunner
.setBluetoothMockDataSet('MissingServiceGenericAccessAdapter');
35 return assert_promise_rejects_with_message(
36 characteristic
.writeValue(new ArrayBuffer(1 /* length */)), {
37 name
: 'InvalidStateError',
38 message
: 'GATT Service no longer exists.'
39 }, 'Service got removed.');
41 }, 'Service gets removed. Reject with InvalidStateError.');
44 testRunner
.setBluetoothMockDataSet('GenericAccessAdapter');
45 return requestDeviceWithKeyDown({filters
: [{services
: ['generic_access']}]})
46 .then(device
=> device
.connectGATT())
47 .then(gattServer
=> gattServer
.getPrimaryService('generic_access'))
48 .then(service
=> service
.getCharacteristic('gap.device_name'))
49 .then(characteristic
=> {
50 testRunner
.setBluetoothMockDataSet('MissingCharacteristicGenericAccessAdapter');
51 return assert_promise_rejects_with_message(
52 characteristic
.writeValue(new ArrayBuffer(1 /* length */)), {
53 name
: 'InvalidStateError',
54 message
: 'GATT Characteristic no longer exists.'
55 }, 'Characteristic got removed.');
57 }, 'Characteristic gets removed. Reject with InvalidStateError.');
59 // The following tests make sure the Web Bluetooth implementation
60 // responds correctly to the different types of errors the
61 // underlying platform might return for GATT operations.
63 // Each implementation maps these characteristics to specific code paths
64 // that result in different errors thus increasing code coverage
65 // when testing. Therefore some of these characteristics might not be useful
66 // for all implementations.
68 testName
: 'GATT Error: Unknown.',
69 uuid
: errorUUID(0xA1),
71 name
: 'NotSupportedError',
72 message
: 'GATT Error Unknown.'
75 testName
: 'GATT Error: Failed.',
76 uuid
: errorUUID(0xA2),
78 name
: 'NotSupportedError',
79 message
: 'GATT operation failed for unknown reason.'
82 testName
: 'GATT Error: In Progress.',
83 uuid
: errorUUID(0xA3),
86 message
: 'GATT operation already in progress.'
89 testName
: 'GATT Error: Invalid Length.',
90 uuid
: errorUUID(0xA4),
92 name
: 'InvalidModificationError',
93 message
: 'GATT Error: invalid attribute length.'
96 testName
: 'GATT Error: Not Permitted.',
97 uuid
: errorUUID(0xA5),
99 name
: 'NotSupportedError',
100 message
: 'GATT operation not permitted.'
103 testName
: 'GATT Error: Not Authorized.',
104 uuid
: errorUUID(0xA6),
106 name
: 'SecurityError',
107 message
: 'GATT operation not authorized.'
110 testName
: 'GATT Error: Not Paired.',
111 uuid
: errorUUID(0xA7),
112 // TODO(ortuno): Change to InsufficientAuthenticationError or similiar
113 // once https://github.com/WebBluetoothCG/web-bluetooth/issues/137 is
116 name
: 'NetworkError',
117 message
: 'GATT Error: Not paired.'
120 testName
: 'GATT Error: Not Supported.',
121 uuid
: errorUUID(0xA8),
123 name
: 'NotSupportedError',
124 message
: 'GATT Error: Not supported.'
126 }].forEach(testSpec
=> {
128 testRunner
.setBluetoothMockDataSet('FailingGATTOperationsAdapter');
129 return requestDeviceWithKeyDown({filters
: [{services
: [errorUUID(0xA0)]}]})
130 .then(device
=> device
.connectGATT())
131 .then(gattServer
=> gattServer
.getPrimaryService(errorUUID(0xA0)))
132 .then(service
=> service
.getCharacteristic(testSpec
.uuid
))
133 .then(characteristic
=> {
134 return assert_promise_rejects_with_message(
135 characteristic
.writeValue(new Uint8Array([1])),
137 'Trying to write to a characteristic failed.');
139 }, testSpec
.testName
);
143 testRunner
.setBluetoothMockDataSet('GenericAccessAdapter');
144 return requestDeviceWithKeyDown({filters
: [{services
: ['generic_access']}]})
145 .then(device
=> device
.connectGATT())
146 .then(gattServer
=> gattServer
.getPrimaryService('generic_access'))
147 .then(service
=> service
.getCharacteristic('gap.device_name'))
148 .then(characteristic
=> {
149 return assert_promise_rejects_with_message(
150 characteristic
.writeValue(new Uint8Array(513 /* length */)), {
151 name
: 'InvalidModificationError',
152 message
: 'Value can\'t exceed 512 bytes.'
153 }, 'Value passed was too long.');
155 }, 'Trying to write more than 512 bytes should return an error.');
158 testRunner
.setBluetoothMockDataSet('GenericAccessAdapter');
159 return requestDeviceWithKeyDown({filters
: [{services
: ['generic_access']}]})
160 .then(device
=> device
.connectGATT())
161 .then(gattServer
=> gattServer
.getPrimaryService('generic_access'))
162 .then(service
=> service
.getCharacteristic('gap.device_name'))
163 .then(characteristic
=> Promise
.all(
164 [characteristic
.writeValue(new Uint8Array(1 /* length */)),
165 characteristic
.writeValue(new ArrayBuffer(1 /* length */)),
166 characteristic
.writeValue(new DataView(new ArrayBuffer(1 /* length */)))]));
167 }, 'A regular write request to a writable characteristic should succeed.');