OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 GEN('#if defined(OS_CHROMEOS)'); | |
6 | |
7 GEN_INCLUDE(['../options_browsertest_base.js']); | |
8 | |
9 function BluetoothWebUITestAsync() {} | |
10 | |
11 BluetoothWebUITestAsync.prototype = { | |
12 __proto__: OptionsBrowsertestBase.prototype, | |
13 | |
14 /** @override */ | |
15 isAsync: true, | |
16 | |
17 /** | |
18 * Start tests from the main-settings page. | |
19 */ | |
20 browsePreload: 'chrome://settings-frame/', | |
21 | |
22 // These entries match the fake entries in FakeBluetoothDeviceClient. | |
23 fakePairedDevice: { | |
24 address: '00:11:22:33:44:55', | |
25 connectable: true, | |
26 connected: false, | |
27 name: 'Fake Device (name)', | |
28 paired: true | |
29 }, | |
30 | |
31 fakePairedDevice2: { | |
32 address: '20:7D:74:00:00:04', | |
33 connectable: false, | |
34 connected: false, | |
35 name: 'Paired Unconnectable Device (name)', | |
36 paired: true | |
37 }, | |
38 | |
39 fakeUnpairedDevice: { | |
40 address: '28:CF:DA:00:00:00', | |
41 connectable: true, | |
42 connected: false, | |
43 name: 'Bluetooth 2.0 Mouse', | |
44 paired: false | |
45 }, | |
46 | |
47 fakeUnpairedDevice2: { | |
48 address: '00:24:BE:00:00:00', | |
49 connectable: true, | |
50 connected: false, | |
51 name: 'PIN Device', | |
52 paired: false | |
53 }, | |
54 | |
55 /** @override */ | |
56 setUp: function() { | |
57 OptionsBrowsertestBase.prototype.setUp.call(this); | |
58 | |
59 var unsupportedAriaAttributeSelectors = [ | |
60 '#bluetooth-paired-devices-list', | |
61 '#bluetooth-unpaired-devices-list', | |
62 ]; | |
63 | |
64 // Enable when failure is resolved. | |
65 // AX_ARIA_10: http://crbug.com/570564 | |
66 this.accessibilityAuditConfig.ignoreSelectors( | |
67 'unsupportedAriaAttribute', | |
68 unsupportedAriaAttributeSelectors); | |
69 }, | |
70 | |
71 /** | |
72 * Retrieves the list item associated with a Bluetooth device. | |
73 * @param {!Element} listElement Element containing a list of devices. | |
74 * @param {string} deviceName The name of the device. | |
75 * @return {Element|undefined} List item matching the device name. | |
76 */ | |
77 getElementForDevice: function(listElement, deviceName) { | |
78 var items = listElement.querySelectorAll('.bluetooth-device'); | |
79 for (var i = 0; i < items.length; i++) { | |
80 var candidate = items[i]; | |
81 var name = candidate.data.name; | |
82 if (name == deviceName) | |
83 return candidate; | |
84 } | |
85 return undefined; | |
86 }, | |
87 | |
88 /** | |
89 * Selects a bluetooth device from the list with the matching address. | |
90 * @param {!Element} listElement A list of Bluetooth devices. | |
91 * @param {string} address Device address. | |
92 */ | |
93 selectDevice: function(listElement, address) { | |
94 listElement.setSelectedDevice_(address); | |
95 cr.dispatchSimpleEvent(listElement, 'change'); | |
96 }, | |
97 | |
98 /** | |
99 * Fake input of a pincode or passkey. | |
100 * @param {!Element} element Text input field. | |
101 * @param {string} text New value for the input field. | |
102 */ | |
103 fakeInput: function(element, text) { | |
104 element.value = text; | |
105 cr.dispatchSimpleEvent(element, 'input'); | |
106 }, | |
107 }; | |
108 | |
109 TEST_F('BluetoothWebUITestAsync', 'testEnableBluetooth', function() { | |
110 assertEquals(this.browsePreload, document.location.href); | |
111 expectFalse($('enable-bluetooth').checked); | |
112 expectTrue($('bluetooth-paired-devices-list').parentNode.hidden); | |
113 | |
114 $('enable-bluetooth').click(); | |
115 | |
116 // The UI may not be updated until all callbacks have been handled, so | |
117 // send a new request that will get processed after any currently pending | |
118 // callbacks. | |
119 chrome.bluetooth.getAdapterState(function(state) { | |
120 expectTrue(state.powered); | |
121 expectFalse($('bluetooth-paired-devices-list').parentNode.hidden); | |
122 testDone(); | |
123 }.bind(this)); | |
124 }); | |
125 | |
126 // TODO(crbug.com/603499) Test is flaky. | |
127 TEST_F('BluetoothWebUITestAsync', 'DISABLED_testAddDevice', function() { | |
128 assertEquals(this.browsePreload, document.location.href); | |
129 | |
130 // Enable bluetooth. | |
131 $('enable-bluetooth').click(); | |
132 | |
133 // Wait for the UI to process any pending messages. | |
134 window.setTimeout(function() { | |
135 // Wait for fake bluetooth impl to send any updates. | |
136 chrome.bluetooth.getAdapterState(function(state) { | |
137 var pairedDeviceList = $('bluetooth-paired-devices-list'); | |
138 var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); | |
139 | |
140 // Verify that devices are in the correct list. | |
141 var index = pairedDeviceList.find(this.fakePairedDevice.address); | |
142 expectEquals(1, index); | |
143 index = pairedDeviceList.find(this.fakePairedDevice2.address); | |
144 expectEquals(0, index); | |
145 index = pairedDeviceList.find(this.fakeUnpairedDevice.address); | |
146 expectEquals(undefined, index); | |
147 expectTrue(!!this.getElementForDevice(pairedDeviceList, | |
148 this.fakePairedDevice.name)); | |
149 expectFalse(!!this.getElementForDevice(unpairedDeviceList, | |
150 this.fakePairedDevice.name)); | |
151 | |
152 // Test clicking on the 'Add a device' button. This should send a | |
153 // startDiscovering request. | |
154 $('bluetooth-add-device').click(); | |
155 expectFalse($('bluetooth-options').hidden); | |
156 | |
157 // Wait for fake bluetooth impl to send any updates. | |
158 chrome.bluetooth.getAdapterState(function(state) { | |
159 expectTrue(state.discovering); | |
160 expectFalse(unpairedDeviceList.parentNode.hidden); | |
161 | |
162 index = unpairedDeviceList.find(this.fakeUnpairedDevice.address); | |
163 expectEquals(0, index); | |
164 | |
165 var connectButton = $('bluetooth-add-device-apply-button'); | |
166 expectTrue(connectButton.disabled); | |
167 expectFalse($('bluetooth-add-device-cancel-button').disabled); | |
168 | |
169 // Test selecting an element and clicking on the connect button. | |
170 this.selectDevice(unpairedDeviceList, this.fakeUnpairedDevice.address); | |
171 expectFalse(connectButton.disabled); | |
172 connectButton.click(); | |
173 | |
174 // Wait for fake bluetooth impl to send any updates. | |
175 chrome.bluetooth.getAdapterState(function(state) { | |
176 // Verify that the pairing UI is shown. | |
177 expectFalse($('bluetooth-pairing').hidden); | |
178 testDone(); | |
179 }.bind(this)); | |
180 }.bind(this)); | |
181 }.bind(this)); | |
182 }.bind(this)); | |
183 }); | |
184 | |
185 TEST_F('BluetoothWebUITestAsync', 'testDevicePairing', function() { | |
186 assertEquals(this.browsePreload, document.location.href); | |
187 | |
188 // Enable bluetooth. | |
189 $('enable-bluetooth').click(); | |
190 | |
191 // Wait for the UI to process any pending messages. | |
192 window.setTimeout(function() { | |
193 // Wait for fake bluetooth impl to send any updates. | |
194 chrome.bluetooth.getAdapterState(function(state) { | |
195 var pairedDeviceList = $('bluetooth-paired-devices-list'); | |
196 var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); | |
197 | |
198 $('bluetooth-add-device').click(); | |
199 | |
200 // Wait for fake bluetooth impl to send any updates. | |
201 chrome.bluetooth.getAdapterState(function(state) { | |
202 expectFalse(unpairedDeviceList.parentNode.hidden); | |
203 | |
204 // Test selecting an element and clicking on the connect button. | |
205 var index = unpairedDeviceList.find(this.fakeUnpairedDevice2.address); | |
206 expectNotEquals(undefined, index); | |
207 this.selectDevice(unpairedDeviceList, this.fakeUnpairedDevice2.address); | |
208 var connectButton = $('bluetooth-add-device-apply-button'); | |
209 expectFalse(connectButton.disabled); | |
210 connectButton.click(); | |
211 | |
212 // Wait for fake bluetooth impl to send any updates. | |
213 chrome.bluetooth.getAdapterState(function(state) { | |
214 // Verify that the pairing UI is shown. | |
215 expectFalse($('bluetooth-pairing').hidden); | |
216 expectTrue($('bluetooth-pairing-passkey-display').hidden); | |
217 expectTrue($('bluetooth-pairing-passkey-entry').hidden); | |
218 expectFalse($('bluetooth-pairing-pincode-entry').hidden); | |
219 | |
220 var pincode = '123456'; | |
221 this.fakeInput($('bluetooth-pincode'), pincode); | |
222 $('bluetooth-pair-device-connect-button').click(); | |
223 | |
224 // Wait for fake bluetooth impl to send any updates. | |
225 chrome.bluetooth.getAdapterState(function(state) { | |
226 expectTrue($('bluetooth-pairing-pincode-entry').hidden); | |
227 testDone(); | |
228 }.bind(this)); | |
229 }.bind(this)); | |
230 }.bind(this)); | |
231 }.bind(this)); | |
232 }.bind(this)); | |
233 }); | |
234 | |
235 // TODO(crbug.com/608126) Test is flaky. | |
236 TEST_F('BluetoothWebUITestAsync', 'DISABLED_testConnect', function() { | |
237 assertEquals(this.browsePreload, document.location.href); | |
238 | |
239 // Enable bluetooth. | |
240 $('enable-bluetooth').click(); | |
241 | |
242 // Wait for the UI to process any pending messages. | |
243 window.setTimeout(function() { | |
244 // Wait for fake bluetooth impl to send any updates. | |
245 chrome.bluetooth.getAdapterState(function(state) { | |
246 var pairedDeviceList = $('bluetooth-paired-devices-list'); | |
247 var element = this.getElementForDevice( | |
248 pairedDeviceList, this.fakePairedDevice.name); | |
249 assertTrue(!!element, this.fakePairedDevice.name); | |
250 expectFalse(!!element.getAttribute('connected')); | |
251 | |
252 var connectButton = $('bluetooth-reconnect-device'); | |
253 expectTrue(connectButton.disabled); | |
254 | |
255 // Simulate connecting to a previously paired device. | |
256 this.selectDevice(pairedDeviceList, this.fakePairedDevice.address); | |
257 expectFalse(connectButton.disabled); | |
258 connectButton.click(); | |
259 | |
260 // Call bluetooth.getAdapterState to ensure that all state has been | |
261 // updated. | |
262 chrome.bluetooth.getAdapterState(function(state) { | |
263 element = this.getElementForDevice( | |
264 pairedDeviceList, this.fakePairedDevice.name); | |
265 expectTrue(!!element.getAttribute('connected')); | |
266 var deleteButton = element.querySelector('.row-delete-button'); | |
267 expectTrue(!!deleteButton); | |
268 testDone(); | |
269 }.bind(this)); | |
270 }.bind(this)); | |
271 }.bind(this)); | |
272 }); | |
273 | |
274 TEST_F('BluetoothWebUITestAsync', 'testDisconnect', function() { | |
275 assertEquals(this.browsePreload, document.location.href); | |
276 | |
277 // Enable bluetooth. | |
278 $('enable-bluetooth').click(); | |
279 | |
280 // Wait for the UI to process any pending messages. | |
281 window.setTimeout(function() { | |
282 // Wait for fake bluetooth impl to send any updates. | |
283 chrome.bluetooth.getAdapterState(function(state) { | |
284 var pairedDeviceList = $('bluetooth-paired-devices-list'); | |
285 | |
286 // First connect to the device so that the fake implementation state is | |
287 // connected. | |
288 chrome.bluetoothPrivate.connect( | |
289 this.fakePairedDevice.address, function(result) { | |
290 assertEquals( | |
291 chrome.bluetoothPrivate.ConnectResultType.SUCCESS, result); | |
292 | |
293 var element = this.getElementForDevice( | |
294 pairedDeviceList, this.fakePairedDevice.name); | |
295 assertTrue(!!element, this.fakePairedDevice.name); | |
296 expectTrue(!!element.getAttribute('connected')); | |
297 | |
298 // Simulate disconnecting from a connected device. | |
299 var button = element.querySelector('.row-delete-button'); | |
300 button.click(); | |
301 | |
302 // Wait for fake bluetooth impl to send any updates. | |
303 chrome.bluetooth.getAdapterState(function(state) { | |
304 element = this.getElementForDevice( | |
305 pairedDeviceList, this.fakePairedDevice.name); | |
306 expectFalse(!!element.getAttribute('connected')); | |
307 button = element.querySelector('.row-delete-button'); | |
308 expectTrue(!!button); | |
309 testDone(); | |
310 }.bind(this)); | |
311 }.bind(this)); | |
312 }.bind(this)); | |
313 }.bind(this)); | |
314 }); | |
315 | |
316 // TODO(crbug.com/605090): Disabled because of flakiness. | |
317 TEST_F('BluetoothWebUITestAsync', 'DISABLED_testForget', function() { | |
318 assertEquals(this.browsePreload, document.location.href); | |
319 | |
320 // Enable bluetooth. | |
321 $('enable-bluetooth').click(); | |
322 | |
323 // Wait for the UI to process any pending messages. | |
324 window.setTimeout(function() { | |
325 // Wait for fake bluetooth impl to send any updates. | |
326 chrome.bluetooth.getAdapterState(function(state) { | |
327 var pairedDeviceList = $('bluetooth-paired-devices-list'); | |
328 | |
329 var element = this.getElementForDevice(pairedDeviceList, | |
330 this.fakePairedDevice.name); | |
331 var button = element.querySelector('.row-delete-button'); | |
332 button.click(); | |
333 | |
334 // Wait for fake bluetooth impl to send any updates. | |
335 chrome.bluetooth.getAdapterState(function(state) { | |
336 expectFalse(!!this.getElementForDevice(pairedDeviceList, | |
337 this.fakePairedDevice.name)); | |
338 testDone(); | |
339 }.bind(this)); | |
340 }.bind(this)); | |
341 }.bind(this)); | |
342 }); | |
343 | |
344 | |
345 TEST_F('BluetoothWebUITestAsync', 'testMaliciousInput', function() { | |
346 assertEquals(this.browsePreload, document.location.href); | |
347 | |
348 var maliciousStrings = [ | |
349 '<SCRIPT>alert(1)</SCRIPT>', | |
350 '>\'>\\"><SCRIPT>alert(1)</SCRIPT>', | |
351 '<IMG SRC=\\"javascript:alert(1)\\">', | |
352 '<A HREF=\\"data:text/html;base64,' + | |
353 'PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo=\\">..</A>', | |
354 '<div>', | |
355 '<textarea>', | |
356 '<style>', | |
357 '[0xC0][0xBC]SCRIPT[0xC0][0xBE]alert(1)[0xC0][0xBC]/SCRIPT[0xC0][0xBE]', | |
358 '+ADw-SCRIPT+AD4-alert(1)+ADw-/SCRIPT+AD4-', | |
359 '&#<script>alert(1)</script>;', | |
360 '<!-- Hello -- world > <SCRIPT>alert(1)</SCRIPT> -->', | |
361 '<!<!-- Hello world > <SCRIPT>alert(1)</SCRIPT> -->', | |
362 '\x3CSCRIPT\x3Ealert(1)\x3C/SCRIPT\x3E', | |
363 '<IMG SRC=\\"j[0x00]avascript:alert(1)\\">', | |
364 '<BASE HREF=\\"javascript:1;/**/\\"><IMG SRC=\\"alert(1)\\">', | |
365 'javascript:alert(1);', | |
366 ' xss_injection=\\"\\" ', | |
367 '\\" xss_injection=\\"', | |
368 '\' xss_injection=\'', | |
369 '<!--', | |
370 '\'', | |
371 '\\"' | |
372 ]; | |
373 | |
374 var fakeEvent = { | |
375 device: { | |
376 address: '28:CF:DA:00:00:00', | |
377 connectable: true, | |
378 connected: false, | |
379 name: 'Bluetooth 2.0 Mouse', | |
380 paired: false | |
381 }, | |
382 pairing: 'bluetoothStartConnecting' | |
383 }; | |
384 | |
385 var nodeCount = function(node) { | |
386 if (node.getAttribute) | |
387 assertFalse(!!node.getAttribute('xss_injection')); | |
388 var length = node.childNodes.length; | |
389 var tally = length; | |
390 for (var i = 0; i < length; i++) { | |
391 tally += nodeCount(node.childNodes[i]); | |
392 } | |
393 return tally; | |
394 }; | |
395 | |
396 // Enable bluetooth. | |
397 $('enable-bluetooth').click(); | |
398 | |
399 // Wait for the UI to process any pending messages. | |
400 window.setTimeout(function() { | |
401 // Wait for fake bluetooth impl to send any updates. | |
402 chrome.bluetooth.getAdapterState(function(state) { | |
403 var unpairedDeviceList = $('bluetooth-unpaired-devices-list'); | |
404 var pairDeviceDialog = $('bluetooth-pairing'); | |
405 | |
406 // Show the pairing dialog. | |
407 $('bluetooth-add-device').click(); | |
408 BluetoothPairing.showDialog(fakeEvent); | |
409 | |
410 // Wait for fake bluetooth impl to send any updates. | |
411 chrome.bluetooth.getAdapterState(function(state) { | |
412 expectFalse(unpairedDeviceList.parentNode.hidden); | |
413 | |
414 // Determine the expected sizes. | |
415 var unpairedDeviceListSize = nodeCount(unpairedDeviceList); | |
416 var pairDeviceDialogSize = nodeCount(pairDeviceDialog); | |
417 | |
418 // Ensure that updating the device with a malicious name does not | |
419 // corrupt the structure of the document. Tests the unpaired device | |
420 // list and bluetooth pairing dialog. | |
421 for (var i = 0; i < maliciousStrings.length; i++) { | |
422 fakeEvent.device.name = maliciousStrings[i]; | |
423 BluetoothPairing.showDialog(fakeEvent); | |
424 assertEquals(unpairedDeviceListSize, nodeCount(unpairedDeviceList)); | |
425 var element = this.getElementForDevice( | |
426 unpairedDeviceList, fakeEvent.device.name); | |
427 assertTrue(!!element, fakeEvent.device.name); | |
428 var label = element.querySelector('.bluetooth-device-label'); | |
429 assertTrue(!!label); | |
430 assertEquals(maliciousStrings[i], label.textContent); | |
431 assertEquals(pairDeviceDialogSize, nodeCount(pairDeviceDialog)); | |
432 } | |
433 | |
434 testDone(); | |
435 }.bind(this)); | |
436 }.bind(this)); | |
437 }.bind(this)); | |
438 }); | |
439 | |
440 GEN('#endif'); | |
OLD | NEW |