1 // Copyright 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.
6 * Test fixture for sync internals WebUI testing.
8 * @extends {testing.Test}
10 function SyncInternalsWebUITest() {}
12 SyncInternalsWebUITest.prototype = {
13 __proto__: testing.Test.prototype,
16 * Browse to the sync internals page.
19 browsePreload: 'chrome://sync-internals',
22 * Disable accessibility testing for this page.
25 runAccessibilityChecks: false,
29 this.makeAndRegisterMockHandler([
35 * Checks aboutInfo's details section for the specified field.
36 * @param {boolean} isValid Whether the field is valid.
37 * @param {string} key The name of the key to search for in details.
38 * @param {string} value The expected value if |key| is found.
39 * @return {boolean} whether the field was found in the details.
42 hasInDetails: function(isValid, key, value) {
43 var details = chrome.sync.aboutInfo.details;
46 for (var i = 0; i < details.length; ++i) {
49 for (var j = 0; j < details[i].data.length; ++j) {
50 var obj = details[i].data[j];
51 if (obj.stat_name == key)
52 return obj.is_valid == isValid && obj.stat_value == value;
60 * Constant hard-coded value to return from mock getAllNodes.
63 var HARD_CODED_ALL_NODES = [
65 "BASE_SERVER_SPECIFICS": {},
66 "BASE_VERSION": "1388699799780000",
67 "CTIME": "Wednesday, December 31, 1969 4:00:00 PM",
68 "ID": "sZ:ADqtAZw5kjSwSkukraMoMX6z0OlFXENzhA+1HZNcO6LbATQrkVenHJS5" +
69 "AgICYfj8/6KcvwlCw3FIvcRFtOEP3zSP5YJ1VH53/Q==",
72 "IS_UNAPPLIED_UPDATE": false,
74 "LOCAL_EXTERNAL_ID": "0",
76 "MTIME": "Wednesday, December 31, 1969 4:00:00 PM",
77 "NON_UNIQUE_NAME": "Typed URLs",
79 "SERVER_CTIME": "Wednesday, December 31, 1969 4:00:00 PM",
80 "SERVER_IS_DEL": false,
81 "SERVER_IS_DIR": true,
82 "SERVER_MTIME": "Wednesday, December 31, 1969 4:00:00 PM",
83 "SERVER_NON_UNIQUE_NAME": "Typed URLs",
84 "SERVER_PARENT_ID": "r",
87 "visit_transitions": [],
91 "SERVER_UNIQUE_POSITION": "INVALID[]",
92 "SERVER_VERSION": "1388699799780000",
95 "visit_transitions": [],
100 "TRANSACTION_VERSION": "1",
101 "UNIQUE_BOOKMARK_TAG": "",
102 "UNIQUE_CLIENT_TAG": "",
103 "UNIQUE_POSITION": "INVALID[]",
104 "UNIQUE_SERVER_TAG": "google_chrome_typed_urls",
106 "serverModelType": "Typed URLs"
109 "BASE_SERVER_SPECIFICS": {},
110 "BASE_VERSION": "1372291923970334",
111 "CTIME": "Wednesday, June 26, 2013 5:12:03 PM",
112 "ID": "sZ:ADqtAZyz70DhOIusPT1v2XCd/8YT8Fy43WlqdRyH6UwoBAqMkX5Pnkl/sW9A" +
113 "+AVrmzAPWFTrRBf0AWD57HyN4GcYXwSR9q4lYA==",
116 "IS_UNAPPLIED_UPDATE": false,
117 "IS_UNSYNCED": false,
118 "LOCAL_EXTERNAL_ID": "0",
119 "META_HANDLE": "3011",
120 "MTIME": "Wednesday, June 26, 2013 5:12:03 PM",
121 "NON_UNIQUE_NAME": "http://chrome.com/",
122 "PARENT_ID": "sZ:ADqtAZw5kjSwSkukraMoMX6z0OlFXENzhA+1HZNcO6LbATQrkVen" +
123 "HJS5AgICYfj8/6KcvwlCw3FIvcRFtOEP3zSP5YJ1VH53/Q==",
124 "SERVER_CTIME": "Wednesday, June 26, 2013 5:12:03 PM",
125 "SERVER_IS_DEL": false,
126 "SERVER_IS_DIR": false,
127 "SERVER_MTIME": "Wednesday, June 26, 2013 5:12:03 PM",
128 "SERVER_NON_UNIQUE_NAME": "http://chrome.com/",
129 "SERVER_PARENT_ID": "sZ:ADqtAZw5kjSwSkukraMoMX6z0OlFXENzhA+1HZNcO6LbAT" +
130 "QrkVenHJS5AgICYfj8/6KcvwlCw3FIvcRFtOEP3zSP5YJ1VH53/Q==",
131 "SERVER_SPECIFICS": {
135 "url": "http://chrome.com/",
136 "visit_transitions": [
144 "SERVER_UNIQUE_POSITION": "INVALID[]",
145 "SERVER_VERSION": "1372291923970334",
150 "url": "http://chrome.com/",
151 "visit_transitions": [
160 "TRANSACTION_VERSION": "1",
161 "UNIQUE_BOOKMARK_TAG": "",
162 "UNIQUE_CLIENT_TAG": "J28uWKpXPuQwR3SJKbuLqzYGOcM=",
163 "UNIQUE_POSITION": "INVALID[]",
164 "UNIQUE_SERVER_TAG": "",
166 "serverModelType": "Typed URLs"
171 * Constant hard-coded value to return from mock getAboutInfo.
174 HARD_CODED_ABOUT_INFO = {
175 "actionable_error": [
178 "stat_name": "Error Type",
179 "stat_value": "Uninitialized"
183 "stat_name": "Action",
184 "stat_value": "Uninitialized"
189 "stat_value": "Uninitialized"
193 "stat_name": "Error Description",
194 "stat_value": "Uninitialized"
197 "actionable_error_detected": false,
203 "stat_name": "Summary",
204 "stat_value": "Sync service initialized"
207 "is_sensitive": false,
213 "name": "Model Type",
214 "num_entries": "Total Entries",
215 "num_live": "Live Entries",
217 "value": "Group Type"
224 "value": "Active: GROUP_UI"
227 "unrecoverable_error_detected": false
230 TEST_F('SyncInternalsWebUITest', 'Uninitialized', function() {
231 assertNotEquals(null, chrome.sync.aboutInfo);
232 expectTrue(this.hasInDetails(true, 'Username', ''));
233 expectTrue(this.hasInDetails(false, 'Summary', 'Uninitialized'));
236 TEST_F('SyncInternalsWebUITest', 'LoadPastedAboutInfo', function() {
237 // Expose the text field.
238 $('import-status').click();
240 // Fill it with fake data.
241 $('status-text').value = JSON.stringify(HARD_CODED_ABOUT_INFO);
243 // Trigger the import.
244 $('import-status').click();
246 expectTrue(this.hasInDetails(true, 'Summary', 'Sync service initialized'));
249 TEST_F('SyncInternalsWebUITest', 'SearchTabDoesntChangeOnItemSelect',
251 // Select the search tab.
252 $('sync-search-tab').selected = true;
253 expectTrue($('sync-search-tab').selected);
255 // Build the data model and attach to result list.
256 cr.ui.List.decorate($('sync-results-list'));
257 $('sync-results-list').dataModel = new cr.ui.ArrayDataModel([
260 toString: function() { return 'node 0'; },
264 toString: function() { return 'node 1'; },
268 // Select the first list item and verify the search tab remains selected.
269 $('sync-results-list').getListItemByIndex(0).selected = true;
270 expectTrue($('sync-search-tab').selected);
273 TEST_F('SyncInternalsWebUITest', 'NodeBrowserTest', function() {
274 this.mockHandler.expects(once()).getAllNodes([]).will(
275 callFunction(function() {
276 chrome.sync.getAllNodes.handleReply(HARD_CODED_ALL_NODES);
279 // Hit the refresh button.
280 $('node-browser-refresh-button').click();
282 // Check that the refresh time was updated.
283 expectNotEquals($('node-browser-refresh-time').textContent, 'Never');
285 // Verify some hard-coded assumptions. These depend on the vaue of the
286 // hard-coded nodes, specified elsewhere in this file.
288 // Start with the tree itself.
289 var tree = $('sync-node-tree');
290 assertEquals(1, tree.items.length);
292 // Check the type root and expand it.
293 var typeRoot = tree.items[0];
294 expectFalse(typeRoot.expanded);
295 typeRoot.expanded = true;
296 assertEquals(1, typeRoot.items.length);
298 // An actual sync node. The child of the type root.
299 var leaf = typeRoot.items[0];
301 // Verify that selecting it affects the details view.
302 expectTrue($('node-details').hasAttribute('hidden'));
303 leaf.selected = true;
304 expectFalse($('node-details').hasAttribute('hidden'));
307 TEST_F('SyncInternalsWebUITest', 'NodeBrowserRefreshOnTabSelect', function() {
308 this.mockHandler.expects(once()).getAllNodes([]).will(
309 callFunction(function() {
310 chrome.sync.getAllNodes.handleReply(HARD_CODED_ALL_NODES);
313 // Should start with non-refreshed node browser.
314 expectEquals($('node-browser-refresh-time').textContent, 'Never');
316 // Selecting the tab will refresh it.
317 $('sync-browser-tab').selected = true;
318 expectNotEquals($('node-browser-refresh-time').textContent, 'Never');
320 // Re-selecting the tab shouldn't re-refresh.
321 $('node-browser-refresh-time').textContent = 'TestCanary';
322 $('sync-browser-tab').selected = false;
323 $('sync-browser-tab').selected = true;
324 expectEquals($('node-browser-refresh-time').textContent, 'TestCanary');
327 // Tests that the events log page correctly receives and displays an event.
328 TEST_F('SyncInternalsWebUITest', 'EventLogTest', function() {
329 // Dispatch an event.
330 var connectionEvent = new Event('onConnectionStatusChange');
331 connectionEvent.details = {'status': 'CONNECTION_OK'};
332 chrome.sync.events.dispatchEvent(connectionEvent);
334 // Verify that it is displayed in the events log.
335 var syncEventsTable = $('sync-events');
336 var firstRow = syncEventsTable.children[0];
338 // Makes some assumptions about column ordering. We'll need re-think this if
339 // it turns out to be a maintenance burden.
340 assertEquals(4, firstRow.children.length);
341 var submoduleName = firstRow.children[1].textContent;
342 var eventName = firstRow.children[2].textContent;
343 var detailsText = firstRow.children[3].textContent;
345 expectGE(submoduleName.indexOf('manager'), 0,
346 'submoduleName=' + submoduleName);
347 expectGE(eventName.indexOf('onConnectionStatusChange'), 0,
348 'eventName=' + eventName);
349 expectGE(detailsText.indexOf('CONNECTION_OK'), 0,
350 'detailsText=' + detailsText);
353 TEST_F('SyncInternalsWebUITest', 'DumpSyncEventsToText', function() {
354 // Dispatch an event.
355 var connectionEvent = new Event('onConnectionStatusChange');
356 connectionEvent.details = {'status': 'CONNECTION_OK'}
357 chrome.sync.events.dispatchEvent(connectionEvent);
359 // Click the dump-to-text button.
360 $('dump-to-text').click();
362 // Verify our event is among the results.
363 var eventDumpText = $('data-dump').textContent;
365 expectGE(eventDumpText.indexOf('onConnectionStatusChange'), 0);
366 expectGE(eventDumpText.indexOf('CONNECTION_OK'), 0);