Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: third_party/WebKit/LayoutTests/bluetooth/resources/bluetooth-helpers.js

Issue 1869523003: Move LayoutTests/bluetooth/resources to LayoutTests/resources/bluetooth. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkcr
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 'use strict';
2
3 // Bluetooth UUID constants:
4 // Services:
5 var blacklist_test_service_uuid = "611c954a-263b-4f4a-aab6-01ddb953f985";
6 // Characteristics:
7 var blacklist_exclude_reads_characteristic_uuid =
8 "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
9
10 // Sometimes we need to test that using either the name, alias, or UUID
11 // produces the same result. The following objects help us do that.
12 var generic_access = {
13 alias: 0x1800,
14 name: 'generic_access',
15 uuid: '00001800-0000-1000-8000-00805f9b34fb'
16 };
17 var device_name = {
18 alias: 0x2a00,
19 name: 'gap.device_name',
20 uuid: '00002a00-0000-1000-8000-00805f9b34fb'
21 };
22 var reconnection_address = {
23 alias: 0x2a03,
24 name: 'gap.reconnection_address',
25 uuid: '00002a03-0000-1000-8000-00805f9b34fb'
26 };
27 var heart_rate = {
28 alias: 0x180d,
29 name: 'heart_rate',
30 uuid: '0000180d-0000-1000-8000-00805f9b34fb'
31 };
32 var body_sensor_location = {
33 alias: 0x2a38,
34 name: 'body_sensor_location',
35 uuid: '00002a38-0000-1000-8000-00805f9b34fb'
36 };
37 var glucose = {
38 alias: 0x1808,
39 name: 'glucose',
40 uuid: '00001808-0000-1000-8000-00805f9b34fb'
41 };
42 var battery_service = {
43 alias: 0x180f,
44 name: 'battery_service',
45 uuid: '0000180f-0000-1000-8000-00805f9b34fb'
46 };
47 var battery_level = {
48 alias: 0x2A19,
49 name: 'battery_level',
50 uuid: '00002a19-0000-1000-8000-00805f9b34fb'
51 };
52
53 // The following tests make sure the Web Bluetooth implementation
54 // responds correctly to the different types of errors the
55 // underlying platform might return for GATT operations.
56
57 // Each browser should map these characteristics to specific code paths
58 // that result in different errors thus increasing code coverage
59 // when testing. Therefore some of these characteristics might not be useful
60 // for all browsers.
61 //
62 // TODO(ortuno): According to the testing spec errorUUID(0x101) to
63 // errorUUID(0x1ff) should be use for the uuids of the characteristics.
64 var gatt_errors_tests = [{
65 testName: 'GATT Error: Unknown.',
66 uuid: errorUUID(0xA1),
67 error: new DOMException(
68 'GATT Error Unknown.',
69 'NotSupportedError')
70 }, {
71 testName: 'GATT Error: Failed.',
72 uuid: errorUUID(0xA2),
73 error: new DOMException(
74 'GATT operation failed for unknown reason.',
75 'NotSupportedError')
76 }, {
77 testName: 'GATT Error: In Progress.',
78 uuid: errorUUID(0xA3),
79 error: new DOMException(
80 'GATT operation already in progress.',
81 'NetworkError')
82 }, {
83 testName: 'GATT Error: Invalid Length.',
84 uuid: errorUUID(0xA4),
85 error: new DOMException(
86 'GATT Error: invalid attribute length.',
87 'InvalidModificationError')
88 }, {
89 testName: 'GATT Error: Not Permitted.',
90 uuid: errorUUID(0xA5),
91 error: new DOMException(
92 'GATT operation not permitted.',
93 'NotSupportedError')
94 }, {
95 testName: 'GATT Error: Not Authorized.',
96 uuid: errorUUID(0xA6),
97 error: new DOMException(
98 'GATT operation not authorized.',
99 'SecurityError')
100 }, {
101 testName: 'GATT Error: Not Paired.',
102 uuid: errorUUID(0xA7),
103 // TODO(ortuno): Change to InsufficientAuthenticationError or similiar
104 // once https://github.com/WebBluetoothCG/web-bluetooth/issues/137 is
105 // resolved.
106 error: new DOMException(
107 'GATT Error: Not paired.',
108 'NetworkError')
109 }, {
110 testName: 'GATT Error: Not Supported.',
111 uuid: errorUUID(0xA8),
112 error: new DOMException(
113 'GATT Error: Not supported.',
114 'NotSupportedError')
115 }];
116
117 // TODO(jyasskin): Upstream this to testharness.js: https://crbug.com/509058.
118 function callWithKeyDown(functionCalledOnKeyPress) {
119 return new Promise(resolve => {
120 function onKeyPress() {
121 document.removeEventListener('keypress', onKeyPress, false);
122 resolve(functionCalledOnKeyPress());
123 }
124 document.addEventListener('keypress', onKeyPress, false);
125
126 eventSender.keyDown(' ', []);
127 });
128 }
129
130 // Calls requestDevice() in a context that's 'allowed to show a popup'.
131 function requestDeviceWithKeyDown() {
132 let args = arguments;
133 return callWithKeyDown(() => navigator.bluetooth.requestDevice.apply(navigator .bluetooth, args));
134 }
135
136 // Calls testRunner.getBluetoothManualChooserEvents() until it's returned
137 // |expected_count| events. Or just once if |expected_count| is undefined.
138 function getBluetoothManualChooserEvents(expected_count) {
139 return new Promise((resolve, reject) => {
140 let events = [];
141 let accumulate_events = new_events => {
142 events.push(...new_events);
143 if (events.length >= expected_count) {
144 resolve(events);
145 } else {
146 testRunner.getBluetoothManualChooserEvents(accumulate_events);
147 }
148 };
149 testRunner.getBluetoothManualChooserEvents(accumulate_events);
150 });
151 }
152
153 function setBluetoothFakeAdapter(adapter_name) {
154 return new Promise(resolve => {
155 testRunner.setBluetoothFakeAdapter(adapter_name, resolve);
156 });
157 }
158
159 // errorUUID(alias) returns a UUID with the top 32 bits of
160 // '00000000-97e5-4cd7-b9f1-f5a427670c59' replaced with the bits of |alias|.
161 // For example, errorUUID(0xDEADBEEF) returns
162 // 'deadbeef-97e5-4cd7-b9f1-f5a427670c59'. The bottom 96 bits of error UUIDs
163 // were generated as a type 4 (random) UUID.
164 function errorUUID(uuidAlias) {
165 // Make the number positive.
166 uuidAlias >>>= 0;
167 // Append the alias as a hex number.
168 var strAlias = '0000000' + uuidAlias.toString(16);
169 // Get last 8 digits of strAlias.
170 strAlias = strAlias.substr(-8);
171 // Append Base Error UUID
172 return strAlias + '-97e5-4cd7-b9f1-f5a427670c59';
173 }
174
175 // Function to test that a promise rejects with the expected error type and
176 // message.
177 function assert_promise_rejects_with_message(promise, expected, description) {
178 return promise.then(() => {
179 assert_unreached('Promise should have rejected: ' + description);
180 }, error => {
181 assert_equals(error.name, expected.name, 'Unexpected Error Name:');
182 if (expected.message) {
183 assert_equals(error.message, expected.message, 'Unexpected Error Message:' );
184 }
185 });
186 }
187
188 // Parses add-device(name)=id lines in
189 // testRunner.getBluetoothManualChooserEvents() output, and exposes the name->id
190 // mapping.
191 class AddDeviceEventSet {
192 constructor() {
193 this._idsByName = new Map();
194 this._addDeviceRegex = /^add-device\(([^)]+)\)=(.+)$/;
195 }
196 assert_add_device_event(event, description) {
197 let match = this._addDeviceRegex.exec(event);
198 assert_true(!!match, event + "isn't an add-device event: " + description);
199 this._idsByName.set(match[1], match[2]);
200 }
201 has(name) {
202 return this._idsByName.has(name);
203 }
204 get(name) {
205 return this._idsByName.get(name);
206 }
207 }
208
209 function runGarbageCollection()
210 {
211 // Run gc() as a promise.
212 return new Promise(
213 function(resolve, reject) {
214 GCController.collect();
215 setTimeout(resolve, 0);
216 });
217 }
218
219 // Creates |num_listeners| promises. Each adds an event listener
220 // to object. The promises resolve once the object fires |event| but
221 // reject if the event is fired before |object|.|func|() resolves.
222 // Returns a promise that fulfills with the result of |object|.|func()|
223 // and |event.target.value| of each of the other promises.
224 function assert_event_fires_after_promise(object, func, event, num_listeners) {
225 num_listeners = num_listeners !== undefined ? num_listeners : 1;
226
227 if (object[func] === undefined) {
228 return Promise.reject('Function \'' + func + '\' not available in object.');
229 }
230 let should_resolve = false;
231 let event_promises = [];
232 for (let i = 0; i < num_listeners; i++) {
233 event_promises.push(new Promise((resolve, reject) => {
234 let event_listener = (e) => {
235 object.removeEventListener(event, event_listener);
236 if (should_resolve) {
237 resolve(e.target.value);
238 } else {
239 reject(event + ' was triggered before the promise resolved.');
240 }
241 };
242 object.addEventListener(event, event_listener);
243 }));
244 }
245 return object[func]().then(result => {
246 should_resolve = true;
247 return Promise.all([result, ...event_promises]);
248 });
249 }
250
251 // Returns a promise that resolves after 100ms unless
252 // the the event is fired on the object in which case
253 // the promise rejects.
254 function assert_no_events(object, event_name) {
255 return new Promise((resolve, reject) => {
256 let event_listener = (e) => {
257 object.removeEventListener(event_name, event_listener);
258 assert_unreached('Object should not fire an event.');
259 };
260 object.addEventListener(event_name, event_listener);
261 // TODO(ortuno): Remove timeout.
262 // http://crbug.com/543884
263 setTimeout(() => {
264 object.removeEventListener(event_name, event_listener);
265 resolve();
266 }, 100);
267 });
268 }
269
270 class TestCharacteristicProperties {
271 constructor(properties) {
272 this.broadcast = properties.broadcast || false;
273 this.read = properties.read || false;
274 this.writeWithoutResponse = properties.writeWithoutResponse || false;
275 this.write = properties.write || false;
276 this.notify = properties.notify || false;
277 this.indicate = properties.indicate || false;
278 this.authenticatedSignedWrites = properties.authenticatedSignedWrites || fal se;
279 this.reliableWrite = properties.reliableWrite || false;
280 this.writableAuxiliaries = properties.writableAuxiliaries || false;
281 }
282 }
283
284 function assert_properties_equal(properties, expected_properties) {
285 for (let key in expected_properties) {
286 assert_equals(properties[key], expected_properties[key]);
287 }
288 }
289
290 // Generates a string of size |size|.
291 function generate_string(size, char) {
292 // When passing an array of n undefined's to String the resulting string
293 // has size n - 1.
294 return char.repeat(size);
295 }
296
297 class EventCatcher {
298 constructor(object, event) {
299 this.eventFired = false;
300 let event_listener = e => {
301 object.removeEventListener(event, event_listener);
302 this.eventFired = true;
303 }
304 object.addEventListener(event, event_listener);
305 }
306 }
307
308 // Bluetooth tests sometimes have left-over state that could leak into the
309 // next test. add_result_callback which is exposed by testharness.js allows us
310 // to clean up this state after each test. In the future we will split tests
311 // into separate files so that we don't have to add this callback ourselves.
312 // TODO(ortuno): Split tests into separate files.
313 // https://crbug.com/554240
314 add_result_callback(() => {
315 // At the end of each test we clean up all the leftover data in the browser,
316 // including revoking permissions. This happens before the test document is
317 // detached. Once the document is detached any device that connected tries
318 // to disconnect but by then the document no longer has permission to
319 // interact with the device. So before we clean up the browser data
320 // we change the visibility which results in all devices disconnecing.
321 // TODO(ortuno): Remove setPageVisibility hack. In the future, the browser
322 // will notify the renderer that the device disconnected so we won't need
323 // this hack.
324 // https://crbug.com/581855
325 testRunner.setBluetoothManualChooser(false);
326 setBluetoothFakeAdapter('');
327 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698