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

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: Fix tests 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 console.log('Importing modules');
50 return importModules([
51 'content/public/renderer/frame_interfaces',
dpapad 2016/11/02 23:19:14 Nit: There is 2 more spaces of indentation than ne
mbrunson 2016/11/03 20:59:05 Done.
52 'device/bluetooth/public/interfaces/adapter.mojom',
53 'device/bluetooth/public/interfaces/device.mojom',
54 'mojo/public/js/bindings',
55 'mojo/public/js/connection',
56 ]).then(function([frameInterfaces, adapter, device, bindings,
57 connection]) {
58 console.log('Modules imported');
dpapad 2016/11/02 23:19:15 Can you remove this.
mbrunson 2016/11/03 20:59:05 Done.
59
60 /**
61 * A test adapter factory proxy for the chrome://bluetooth-internals
62 * page.
63 *
64 * @constructor
65 * @extends {TestBrowserProxyBase}
66 */
67 var TestAdapterFactoryProxy = function() {
68 settings.TestBrowserProxy.call(this, [
69 'getAdapter',
70 ]);
71
72 this.adapter = new TestAdapter();
73 this.adapterHandle_ = connection.bindStubDerivedImpl(this.adapter);
74 };
75
76 TestAdapterFactoryProxy.prototype = {
77 __proto__: settings.TestBrowserProxy.prototype,
78 getAdapter: function() {
79 this.methodCalled('getAdapter');
80
81 // Create message pipe bound to TestAdapter.
82 return Promise.resolve({
83 adapter: this.adapterHandle_,
84 });
85 }
86 };
87
88 /**
89 * A test adapter for the chrome://bluetooth-internals page.
90 * Must be used to create message pipe handle from test code.
91 *
92 * @constructor
93 * @extends {adapter.Adapter.stubClass}
94 */
95 var TestAdapter = function() {
96 this.proxy = new TestAdapterProxy();
97 };
98
99 TestAdapter.prototype = {
100 __proto__: adapter.Adapter.stubClass.prototype,
101 getInfo: function() { return this.proxy.getInfo(); },
102 getDevices: function() { return this.proxy.getDevices(); },
103 setClient: function(client) { return this.proxy.setClient(client); }
104 };
105
106 /**
107 * A test adapter proxy for the chrome://bluetooth-internals page.
108 *
109 * @constructor
110 * @extends {TestBrowserProxyBase}
111 */
112 var TestAdapterProxy = function() {
113 settings.TestBrowserProxy.call(this, [
114 'getInfo',
115 'getDevices',
116 'setClient',
117 ]);
118
119 this.client = null;
120
121 this.adapterInfo_ = null;
122 this.devices_ = [];
123 };
124
125 TestAdapterProxy.prototype = {
126 __proto__: settings.TestBrowserProxy.prototype,
127 getInfo: function() {
128 this.methodCalled('getInfo');
129 return Promise.resolve({ info: this.adapterInfo_ });
dpapad 2016/11/02 23:19:15 No need for spaces {info: this.adapterInfo_}
mbrunson 2016/11/03 20:55:10 Done.
130 },
dpapad 2016/11/02 23:19:15 \n between functions
mbrunson 2016/11/03 20:55:10 Done.
131 getDevices: function() {
132 this.methodCalled('getDevices');
133 return Promise.resolve({ devices: this.devices_ });
134 },
135 setClient: function(client) {
136 this.methodCalled('setClient', client);
137 this.client = connection.bindHandleToProxy(client,
138 adapter.AdapterClient);
dpapad 2016/11/02 23:19:15 Indent is off. Also try to keep all arguments on t
mbrunson 2016/11/03 20:55:10 Done.
139 },
140 setTestAdapter: function(adapterInfo) {
141 this.adapterInfo_ = adapterInfo;
142 },
143 setTestDevices: function(devices) {
144 this.devices_ = devices;
145 }
146 };
147
148
149 frameInterfaces.addInterfaceOverrideForTesting(
150 adapter.AdapterFactory.name,
151 function(handle) {
152 var stub = connection.bindHandleToStub(
153 handle, adapter.AdapterFactory);
dpapad 2016/11/02 23:19:15 Indent off by 2.
mbrunson 2016/11/03 20:55:10 Done.
154 this.adapterFactory = new TestAdapterFactoryProxy();
155 bindings.StubBindings(stub).delegate = this.adapterFactory;
156
157 this.setupResolver.resolve();
158 }.bind(this));
159
dpapad 2016/11/02 23:19:15 Nit: Remove \n
mbrunson 2016/11/03 20:55:10 Done.
160 }.bind(this));
161 }.bind(this);
162 },
163 };
164
165 TEST_F('BluetoothInternalsTest', 'Startup_BluetoothInternals', function() {
166 var fakeAdapterInfo = {
167 address: '02:1C:7E:6A:11:5A',
168 discoverable: false,
169 discovering: false,
170 initialized: true,
171 name: 'computer.example.com-0',
172 powered: true,
173 present: true,
174 };
175
176 var fakeDeviceInfo1 = {
177 address: "AA:AA:84:96:92:84",
178 name: "AAA",
179 name_for_display: "AAA",
180 rssi: {value: -40},
181 services: []
182 };
183
184 var fakeDeviceInfo2 = {
185 address: "BB:BB:84:96:92:84",
186 name: "BBB",
187 name_for_display: "BBB",
188 rssi: null,
189 services: []
190 };
191
192 var fakeDeviceInfo3 = {
193 address: "CC:CC:84:96:92:84",
194 name: "CCC",
195 name_for_display: "CCC",
196 };
197
198 var adapterFactory = null;
199
200 // Before tests are run, make sure setup completes.
201 var setupPromise = this.setupResolver.promise.then(function() {
202 adapterFactory = this.adapterFactory;
203 }.bind(this));
204
205
206 suite('BluetoothInternalsUITest', function() {
207 var EXPECTED_DEVICES = 2;
208
209 suiteSetup(function() {
210 return setupPromise.then(function() {
211 adapterFactory.adapter.proxy.setTestDevices([
212 fakeDeviceInfo1,
213 fakeDeviceInfo2
214 ]);
215 adapterFactory.adapter.proxy.setTestAdapter(fakeAdapterInfo);
216
217 return Promise.all([
218 adapterFactory.whenCalled('getAdapter'),
219 adapterFactory.adapter.proxy.whenCalled('getInfo'),
220 adapterFactory.adapter.proxy.whenCalled('getDevices'),
221 ]);
222 });
223 });
224
225 setup(function() {
226 var devices = new device_collection.DeviceCollection([]);
227 adapterClient.devices = devices;
228 deviceTable.setDevices(devices);
229 adapterClient.deviceAdded(fakeDeviceInfo1);
230 adapterClient.deviceAdded(fakeDeviceInfo2);
231 });
232
233 teardown(function() {
234 adapterFactory.reset();
235 });
236
237 /**
238 * Updates device info and verifies the contents of the device table.
239 * @param {!device_collection.DeviceInfo} deviceInfo
240 */
241 function changeDevice(deviceInfo) {
242 var deviceRow = document.querySelector('#' + escapeDeviceAddress(
243 deviceInfo.address));
244 var nameForDisplayColumn = deviceRow.children[0];
245 var addressColumn = deviceRow.children[1];
246 var rssiColumn = deviceRow.children[2];
247 var servicesColumn = deviceRow.children[3];
248
249 expectTrue(!!nameForDisplayColumn);
250 expectTrue(!!addressColumn);
251 expectTrue(!!rssiColumn);
252 expectTrue(!!servicesColumn);
253
254 adapterClient.deviceChanged(deviceInfo);
255
256 expectEquals(deviceInfo.name_for_display,
257 nameForDisplayColumn.textContent);
258 expectEquals(deviceInfo.address, addressColumn.textContent);
259
260 expectEquals(String(deviceInfo.rssi.value), rssiColumn.textContent);
261
262 if (deviceInfo.services) {
263 expectEquals(String(deviceInfo.services.length),
264 servicesColumn.textContent);
265 } else {
266 expectEquals('Unknown', servicesColumn.textContent);
267 }
268 }
269
270 /**
271 * Escapes colons in a device address for CSS formatting.
272 * @param {!string} address
dpapad 2016/11/02 23:19:15 "!" is implied for number,boolean,string, so not n
mbrunson 2016/11/03 20:55:10 Done.
273 */
274 function escapeDeviceAddress(address) {
275 return address.replace(/:/g, '\\:');
276 }
277
278 /**
279 * Expects whether device with |address| is removed.
280 * @param {!string} address
281 * @param {!boolean} expectRemoved
282 */
283 function expectDeviceRemoved(address, expectRemoved) {
284 var removedRow = document.querySelector('#' + escapeDeviceAddress(
285 address));
286
287 expectEquals(expectRemoved, removedRow.classList.contains('removed'));
288 }
289
290 /**
291 * Tests whether a device is added successfully and not duplicated.
292 */
293 test('DeviceAdded', function() {
294 var devices = document.querySelectorAll('#device-table tbody tr');
295 expectEquals(EXPECTED_DEVICES, devices.length);
296
297 adapterClient.deviceAdded(fakeDeviceInfo3);
298
299 // Same device shouldn't appear twice.
300 adapterClient.deviceAdded(fakeDeviceInfo3);
301
302 devices = document.querySelectorAll('#device-table tbody tr');
303 expectEquals(EXPECTED_DEVICES + 1, devices.length);
304 });
305
306 /**
307 * Tests whether a device is marked properly as removed.
308 */
309 test('DeviceSetToRemoved', function() {
310 var devices = document.querySelectorAll('#device-table tbody tr');
311 expectEquals(EXPECTED_DEVICES, devices.length);
312 adapterClient.deviceRemoved(fakeDeviceInfo2);
313
314 // The number of rows shouldn't change.
315 devices = document.querySelectorAll('#device-table tbody tr');
316 expectEquals(EXPECTED_DEVICES, devices.length);
317
318 expectDeviceRemoved(fakeDeviceInfo2.address, true);
319 });
320
321 /**
322 * Tests whether a changed device updates the device table properly.
323 */
324 test('DeviceChanged', function() {
325 var devices = document.querySelectorAll('#device-table tbody tr');
326 expectEquals(EXPECTED_DEVICES, devices.length);
327
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 adapterClient.deviceAdded(fakeDeviceInfo3);
344
345 var newDeviceInfo = Object.assign({}, fakeDeviceInfo3);
346 newDeviceInfo.name_for_display = 'DDDD';
347 newDeviceInfo.rssi = { value: -20 };
348 newDeviceInfo.services = ['service1', 'service2', 'service3'];
349
350 changeDevice(newDeviceInfo);
351 changeDevice(fakeDeviceInfo3);
352
353 adapterClient.deviceRemoved(fakeDeviceInfo3);
354 expectDeviceRemoved(fakeDeviceInfo3.address, true);
355
356 adapterClient.deviceAdded(fakeDeviceInfo3);
357 expectDeviceRemoved(fakeDeviceInfo3.address, false);
358 });
359 });
360
361 // Run all registered tests.
362 mocha.run();
363 });
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