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

Side by Side Diff: chrome/test/data/webui/bluetooth_internals_browsertest.js

Issue 2428773005: bluetooth: Basic browser tests for chrome://bluetooth-internals. (Closed)
Patch Set: Merge upstream Created 4 years, 1 month 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
« no previous file with comments | « chrome/test/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 /**
6 * @fileoverview Tests for chrome://bluetooth-internals
7 */
8
9 /** @const {string} Path to source root. */
10 var ROOT_PATH = '../../../../';
11
12 /**
13 * Test fixture for BluetoothInternals WebUI testing.
14 * @constructor
15 * @extends testing.Test
16 */
17 function BluetoothInternalsTest() {
18 this.adapterFactory = null;
19 this.setupResolver = new PromiseResolver();
20 }
21
22 BluetoothInternalsTest.prototype = {
23 __proto__: testing.Test.prototype,
24
25 /** @override */
26 browsePreload: 'chrome://bluetooth-internals',
27
28 /** @override */
29 isAsync: true,
30
31 /** @override */
32 runAccessibilityChecks: false,
33
34 /** @override */
35 extraLibraries: [
36 ROOT_PATH + 'third_party/mocha/mocha.js',
37 ROOT_PATH + 'chrome/test/data/webui/mocha_adapter.js',
38 ROOT_PATH + 'ui/webui/resources/js/promise_resolver.js',
39 ROOT_PATH + 'ui/webui/resources/js/cr.js',
40 ROOT_PATH + 'ui/webui/resources/js/util.js',
41 ROOT_PATH + 'chrome/test/data/webui/settings/test_browser_proxy.js',
42 ],
43
44 preLoad: function() {
45 // A function that is called from chrome://bluetooth-internals to allow this
46 // test to replace the real Mojo browser proxy with a fake one, before any
47 // other code runs.
48 window.setupFn = function() {
49 return importModules([
50 'content/public/renderer/frame_interfaces',
51 'device/bluetooth/public/interfaces/adapter.mojom',
52 'device/bluetooth/public/interfaces/device.mojom',
53 'mojo/public/js/bindings',
54 'mojo/public/js/connection',
55 ]).then(function([frameInterfaces, adapter, device, bindings,
56 connection]) {
57 /**
58 * A test adapter factory proxy for the chrome://bluetooth-internals
59 * page.
60 *
61 * @constructor
62 * @extends {TestBrowserProxyBase}
63 */
64 var TestAdapterFactoryProxy = function() {
65 settings.TestBrowserProxy.call(this, [
66 'getAdapter',
67 ]);
68
69 this.adapter = new TestAdapter();
70 this.adapterHandle_ = connection.bindStubDerivedImpl(this.adapter);
71 };
72
73 TestAdapterFactoryProxy.prototype = {
74 __proto__: settings.TestBrowserProxy.prototype,
75 getAdapter: function() {
76 this.methodCalled('getAdapter');
77
78 // Create message pipe bound to TestAdapter.
79 return Promise.resolve({
80 adapter: this.adapterHandle_,
81 });
82 }
83 };
84
85 /**
86 * A test adapter for the chrome://bluetooth-internals page.
87 * Must be used to create message pipe handle from test code.
88 *
89 * @constructor
90 * @extends {adapter.Adapter.stubClass}
91 */
92 var TestAdapter = function() {
93 this.proxy = new TestAdapterProxy();
94 };
95
96 TestAdapter.prototype = {
97 __proto__: adapter.Adapter.stubClass.prototype,
98 getInfo: function() { return this.proxy.getInfo(); },
99 getDevices: function() { return this.proxy.getDevices(); },
100 setClient: function(client) { return this.proxy.setClient(client); }
101 };
102
103 /**
104 * A test adapter proxy for the chrome://bluetooth-internals page.
105 *
106 * @constructor
107 * @extends {TestBrowserProxyBase}
108 */
109 var TestAdapterProxy = function() {
110 settings.TestBrowserProxy.call(this, [
111 'getInfo',
112 'getDevices',
113 'setClient',
114 ]);
115
116 this.adapterInfo_ = null;
117 this.devices_ = [];
118 };
119
120 TestAdapterProxy.prototype = {
121 __proto__: settings.TestBrowserProxy.prototype,
122
123 getInfo: function() {
124 this.methodCalled('getInfo');
125 return Promise.resolve({info: this.adapterInfo_});
126 },
127
128 getDevices: function() {
129 this.methodCalled('getDevices');
130 return Promise.resolve({devices: this.devices_});
131 },
132
133 setClient: function(client) {
134 this.methodCalled('setClient', client);
135 },
136
137 setTestAdapter: function(adapterInfo) {
138 this.adapterInfo_ = adapterInfo;
139 },
140
141 setTestDevices: function(devices) {
142 this.devices_ = devices;
143 }
144 };
145
146 frameInterfaces.addInterfaceOverrideForTesting(
147 adapter.AdapterFactory.name,
148 function(handle) {
149 var stub = connection.bindHandleToStub(
150 handle, adapter.AdapterFactory);
151 this.adapterFactory = new TestAdapterFactoryProxy();
152 bindings.StubBindings(stub).delegate = this.adapterFactory;
153
154 this.setupResolver.resolve();
155 }.bind(this));
156 }.bind(this));
157 }.bind(this);
158 },
159 };
160
161 TEST_F('BluetoothInternalsTest', 'Startup_BluetoothInternals', function() {
162 var fakeAdapterInfo = {
163 address: '02:1C:7E:6A:11:5A',
164 discoverable: false,
165 discovering: false,
166 initialized: true,
167 name: 'computer.example.com-0',
168 powered: true,
169 present: true,
170 };
171
172 var fakeDeviceInfo1 = {
173 address: "AA:AA:84:96:92:84",
174 name: "AAA",
175 name_for_display: "AAA",
176 rssi: {value: -40},
177 services: []
178 };
179
180 var fakeDeviceInfo2 = {
181 address: "BB:BB:84:96:92:84",
182 name: "BBB",
183 name_for_display: "BBB",
184 rssi: null,
185 services: []
186 };
187
188 var fakeDeviceInfo3 = {
189 address: "CC:CC:84:96:92:84",
190 name: "CCC",
191 name_for_display: "CCC",
192 };
193
194 var adapterFactory = null;
195
196 // Before tests are run, make sure setup completes.
197 var setupPromise = this.setupResolver.promise.then(function() {
198 adapterFactory = this.adapterFactory;
199 }.bind(this));
200
201
202 suite('BluetoothInternalsUITest', function() {
203 var EXPECTED_DEVICES = 2;
204
205 suiteSetup(function() {
206 return setupPromise.then(function() {
207 adapterFactory.adapter.proxy.setTestDevices([
208 fakeDeviceInfo1,
209 fakeDeviceInfo2
210 ]);
211 adapterFactory.adapter.proxy.setTestAdapter(fakeAdapterInfo);
212
213 return Promise.all([
214 adapterFactory.whenCalled('getAdapter'),
215 adapterFactory.adapter.proxy.whenCalled('getInfo'),
216 adapterFactory.adapter.proxy.whenCalled('getDevices'),
217 adapterFactory.adapter.proxy.whenCalled('setClient'),
218 ]);
219 });
220 });
221
222 setup(function() {
223 devices.splice(0, devices.length);
224 adapterBroker.adapterClient_.deviceAdded(fakeDeviceInfo1);
225 adapterBroker.adapterClient_.deviceAdded(fakeDeviceInfo2);
226 });
227
228 teardown(function() {
229 adapterFactory.reset();
230 });
231
232 /**
233 * Updates device info and verifies the contents of the device table.
234 * @param {!device_collection.DeviceInfo} deviceInfo
235 */
236 function changeDevice(deviceInfo) {
237 var deviceRow = document.querySelector('#' + escapeDeviceAddress(
238 deviceInfo.address));
239 var nameForDisplayColumn = deviceRow.children[0];
240 var addressColumn = deviceRow.children[1];
241 var rssiColumn = deviceRow.children[2];
242 var servicesColumn = deviceRow.children[3];
243
244 expectTrue(!!nameForDisplayColumn);
245 expectTrue(!!addressColumn);
246 expectTrue(!!rssiColumn);
247 expectTrue(!!servicesColumn);
248
249 adapterBroker.adapterClient_.deviceChanged(deviceInfo);
250
251 expectEquals(deviceInfo.name_for_display,
252 nameForDisplayColumn.textContent);
253 expectEquals(deviceInfo.address, addressColumn.textContent);
254
255 if (deviceInfo.rssi) {
256 expectEquals(String(deviceInfo.rssi.value), rssiColumn.textContent);
257 }
258
259 if (deviceInfo.services) {
260 expectEquals(String(deviceInfo.services.length),
261 servicesColumn.textContent);
262 } else {
263 expectEquals('Unknown', servicesColumn.textContent);
264 }
265 }
266
267 /**
268 * Escapes colons in a device address for CSS formatting.
269 * @param {string} address
270 */
271 function escapeDeviceAddress(address) {
272 return address.replace(/:/g, '\\:');
273 }
274
275 /**
276 * Expects whether device with |address| is removed.
277 * @param {string} address
278 * @param {boolean} expectRemoved
279 */
280 function expectDeviceRemoved(address, expectRemoved) {
281 var removedRow = document.querySelector(
282 '#' + escapeDeviceAddress(address));
283
284 expectEquals(expectRemoved, removedRow.classList.contains('removed'));
285 }
286
287 /**
288 * Tests whether a device is added successfully and not duplicated.
289 */
290 test('DeviceAdded', function() {
291 var devices = document.querySelectorAll('#device-table tbody tr');
292 expectEquals(EXPECTED_DEVICES, devices.length);
293
294 // Copy device info because device collection will not copy this object.
295 var infoCopy = Object.assign({}, fakeDeviceInfo3);
296 adapterBroker.adapterClient_.deviceAdded(infoCopy);
297
298 // Same device shouldn't appear twice.
299 adapterBroker.adapterClient_.deviceAdded(infoCopy);
300
301 devices = document.querySelectorAll('#device-table tbody tr');
302 expectEquals(EXPECTED_DEVICES + 1, devices.length);
303 });
304
305 /**
306 * Tests whether a device is marked properly as removed.
307 */
308 test('DeviceSetToRemoved', function() {
309 var devices = document.querySelectorAll('#device-table tbody tr');
310 expectEquals(EXPECTED_DEVICES, devices.length);
311 adapterBroker.adapterClient_.deviceRemoved(fakeDeviceInfo2);
312
313 // The number of rows shouldn't change.
314 devices = document.querySelectorAll('#device-table tbody tr');
315 expectEquals(EXPECTED_DEVICES, devices.length);
316
317 expectDeviceRemoved(fakeDeviceInfo2.address, true);
318 });
319
320 /**
321 * Tests whether a changed device updates the device table properly.
322 */
323 test('DeviceChanged', function() {
324 var devices = document.querySelectorAll('#device-table tbody tr');
325 expectEquals(EXPECTED_DEVICES, devices.length);
326
327 // Copy device info because device collection will not copy this object.
328 var newDeviceInfo = Object.assign({}, fakeDeviceInfo1);
329 newDeviceInfo.name_for_display = 'DDDD';
330 newDeviceInfo.rssi = { value: -20 };
331 newDeviceInfo.services = ['service1', 'service2', 'service3'];
332
333 changeDevice(newDeviceInfo);
334 });
335
336 /**
337 * Tests the entire device cycle, added -> updated -> removed -> re-added.
338 */
339 test('DeviceUpdateCycle', function() {
340 var devices = document.querySelectorAll('#device-table tbody tr');
341 expectEquals(EXPECTED_DEVICES, devices.length);
342
343 // Copy device info because device collection will not copy this object.
344 var originalDeviceInfo = Object.assign({}, fakeDeviceInfo3);
345 adapterBroker.adapterClient_.deviceAdded(originalDeviceInfo);
346
347 var newDeviceInfo = Object.assign({}, fakeDeviceInfo3);
348 newDeviceInfo.name_for_display = 'DDDD';
349 newDeviceInfo.rssi = { value: -20 };
350 newDeviceInfo.services = ['service1', 'service2', 'service3'];
351
352 changeDevice(newDeviceInfo);
353 changeDevice(originalDeviceInfo);
354
355 adapterBroker.adapterClient_.deviceRemoved(originalDeviceInfo);
356 expectDeviceRemoved(originalDeviceInfo.address, true);
357
358 adapterBroker.adapterClient_.deviceAdded(originalDeviceInfo);
359 expectDeviceRemoved(originalDeviceInfo.address, false);
360 });
361
362 test('DeviceAddedRssiCheck', function() {
363 var devices = document.querySelectorAll('#device-table tbody tr');
364 expectEquals(EXPECTED_DEVICES, devices.length);
365
366 // Copy device info because device collection will not copy this object.
367 var newDeviceInfo = Object.assign({}, fakeDeviceInfo3);
368 adapterBroker.adapterClient_.deviceAdded(newDeviceInfo);
369
370 var deviceRow = document.querySelector('#' + escapeDeviceAddress(
371 newDeviceInfo.address));
372 var rssiColumn = deviceRow.children[2];
373 expectEquals('Unknown', rssiColumn.textContent);
374
375 var newDeviceInfo1 = Object.assign({}, fakeDeviceInfo3);
376 newDeviceInfo1.rssi = {value: -42};
377 adapterBroker.adapterClient_.deviceChanged(newDeviceInfo1);
378 expectEquals('-42', rssiColumn.textContent);
379
380 // Device table should keep last valid rssi value.
381 var newDeviceInfo2 = Object.assign({}, fakeDeviceInfo3);
382 newDeviceInfo2.rssi = null;
383 adapterBroker.adapterClient_.deviceChanged(newDeviceInfo2);
384 expectEquals('-42', rssiColumn.textContent);
385
386 var newDeviceInfo3 = Object.assign({}, fakeDeviceInfo3);
387 newDeviceInfo3.rssi = {value: -17};
388 adapterBroker.adapterClient_.deviceChanged(newDeviceInfo3);
389 expectEquals('-17', rssiColumn.textContent);
390 });
391 });
392
393 // Run all registered tests.
394 mocha.run();
395 });
OLDNEW
« no previous file with comments | « chrome/test/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698