Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / webui / sync_internals_browsertest.js
blob3f52e2e1241cad79c3c68240b2ca1b2a859c1ba3
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.
5 /**
6  * Test fixture for sync internals WebUI testing.
7  * @constructor
8  * @extends {testing.Test}
9  */
10 function SyncInternalsWebUITest() {}
12 SyncInternalsWebUITest.prototype = {
13   __proto__: testing.Test.prototype,
15   /**
16    * Browse to the sync internals page.
17    * @override
18    */
19   browsePreload: 'chrome://sync-internals',
21   /**
22    * Disable accessibility testing for this page.
23    * @override
24    */
25   runAccessibilityChecks: false,
27   /** @override */
28   preLoad: function() {
29     this.makeAndRegisterMockHandler([
30         'getAllNodes',
31     ]);
32   },
34   /**
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.
40    * @protected
41    */
42   hasInDetails: function(isValid, key, value) {
43     var details = chrome.sync.aboutInfo.details;
44     if (!details)
45       return false;
46     for (var i = 0; i < details.length; ++i) {
47       if (!details[i].data)
48         continue;
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;
53       }
54     }
55     return false;
56   }
59 /**
60  * Constant hard-coded value to return from mock getAllNodes.
61  * @const
62  */
63 var HARD_CODED_ALL_NODES = [{
64   'nodes': [{
65     'ATTACHMENT_METADATA': '',
66     'BASE_SERVER_SPECIFICS': {},
67     'BASE_VERSION': '1396470970810000',
68     'CTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
69     'ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1SkJwpp1YL' +
70       '6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
71     'IS_DEL': false,
72     'IS_DIR': true,
73     'IS_UNAPPLIED_UPDATE': false,
74     'IS_UNSYNCED': false,
75     'LOCAL_EXTERNAL_ID': '0',
76     'META_HANDLE': '387',
77     'MTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
78     'NON_UNIQUE_NAME': 'Autofill',
79     'PARENT_ID': 'r',
80     'SERVER_CTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
81     'SERVER_IS_DEL': false,
82     'SERVER_IS_DIR': true,
83     'SERVER_MTIME': 'Wednesday, December 31, 1969 4:00:00 PM',
84     'SERVER_NON_UNIQUE_NAME': 'Autofill',
85     'SERVER_PARENT_ID': 'r',
86     'SERVER_SPECIFICS': {
87       'autofill': {
88         'usage_timestamp': []
89       }
90     },
91     'SERVER_UNIQUE_POSITION': 'INVALID[]',
92     'SERVER_VERSION': '1396470970810000',
93     'SPECIFICS': {
94       'autofill': {
95         'usage_timestamp': []
96       }
97     },
98     'SYNCING': false,
99     'TRANSACTION_VERSION': '1',
100     'UNIQUE_BOOKMARK_TAG': '',
101     'UNIQUE_CLIENT_TAG': '',
102     'UNIQUE_POSITION': 'INVALID[]',
103     'UNIQUE_SERVER_TAG': 'google_chrome_autofill',
104     'isDirty': false,
105     'modelType': 'Autofill'
106   }, {
107     'ATTACHMENT_METADATA': '',
108     'BASE_SERVER_SPECIFICS': {},
109     'BASE_VERSION': '1394241139528639',
110     'CTIME': 'Friday, March 7, 2014 5:12:19 PM',
111     'ID': 'sZ:ADqtAZwzc/ol1iaz+yNLjjWak9PBE0o/hATzpqJsyq/HX2xzV2f88' +
112       'FaOrT7HDE4tyn7zx2LWgkAFvZfCA5mOy4p0XFgiY0L+mw==',
113     'IS_DEL': false,
114     'IS_DIR': false,
115     'IS_UNAPPLIED_UPDATE': false,
116     'IS_UNSYNCED': false,
117     'LOCAL_EXTERNAL_ID': '0',
118     'META_HANDLE': '2989',
119     'MTIME': 'Friday, March 7, 2014 5:12:19 PM',
120     'NON_UNIQUE_NAME': 'autofill_entry|Email|rlsynctet2',
121     'PARENT_ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf7yXJ1Sk' +
122       'Jwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
123     'SERVER_CTIME': 'Friday, March 7, 2014 5:12:19 PM',
124     'SERVER_IS_DEL': false,
125     'SERVER_IS_DIR': false,
126     'SERVER_MTIME': 'Friday, March 7, 2014 5:12:19 PM',
127     'SERVER_NON_UNIQUE_NAME': 'autofill_entry|Email|rlsynctet2',
128     'SERVER_PARENT_ID': 'sZ:ADqtAZwzF4GOIyvkI2enSI62AU5p/7MNmvuSSyf' +
129       '7yXJ1SkJwpp1YL6bbMkF8inzqW+EO6n2aPJ/uXccW9GHxorBlnKoZAWHVzg==',
130     'SERVER_SPECIFICS': {
131       'autofill': {
132         'name': 'Email',
133         'usage_timestamp': ['13038713887000000', '13038713890000000'],
134         'value': 'rlsynctet2'
135       }
136     },
137     'SERVER_UNIQUE_POSITION': 'INVALID[]',
138     'SERVER_VERSION': '1394241139528639',
139     'SPECIFICS': {
140       'autofill': {
141         'name': 'Email',
142         'usage_timestamp': ['13038713887000000', '13038713890000000'],
143         'value': 'rlsynctet2'
144       }
145     },
146     'SYNCING': false,
147     'TRANSACTION_VERSION': '1',
148     'UNIQUE_BOOKMARK_TAG': '',
149     'UNIQUE_CLIENT_TAG': 'EvliorKUf1rLjT+BGkNZp586Tsk=',
150     'UNIQUE_POSITION': 'INVALID[]',
151     'UNIQUE_SERVER_TAG': '',
152     'isDirty': false,
153     'modelType': 'Autofill'
154   }],
155   'type': 'Autofill'
159  * A value to return in mock onReceivedUpdatedAboutInfo event.
160  * @const
161  */
162 HARD_CODED_ABOUT_INFO = {
163   'actionable_error': [
164     {
165       'is_valid': false,
166       'stat_name': 'Error Type',
167       'stat_value': 'Uninitialized'
168     },
169     {
170       'is_valid': false,
171       'stat_name': 'Action',
172       'stat_value': 'Uninitialized'
173     },
174     {
175       'is_valid': false,
176       'stat_name': 'URL',
177       'stat_value': 'Uninitialized'
178     },
179     {
180       'is_valid': false,
181       'stat_name': 'Error Description',
182       'stat_value': 'Uninitialized'
183     }
184   ],
185   'actionable_error_detected': false,
186   'details': [
187     {
188       'data': [
189         {
190           'is_valid': true,
191           'stat_name': 'Summary',
192           'stat_value': 'Sync service initialized'
193         }
194       ],
195       'is_sensitive': false,
196       'title': 'Summary'
197     },
198   ],
199   'type_status': [
200     {
201       'name': 'Model Type',
202       'num_entries': 'Total Entries',
203       'num_live': 'Live Entries',
204       'status': 'header',
205       'value': 'Group Type'
206     },
207     {
208       'name': 'Bookmarks',
209       'num_entries': 2793,
210       'num_live': 2793,
211       'status': 'ok',
212       'value': 'Active: GROUP_UI'
213     },
214   ],
215   'unrecoverable_error_detected': false
218 NETWORK_EVENT_DETAILS_1 = {
219   'details': 'Notified types: Bookmarks, Autofill',
220   'proto': {},
221   'time': 1395874542192.407,
222   'type': 'Normal GetUpdate request',
225 NETWORK_EVENT_DETAILS_2 = {
226   'details': 'Received error: SYNC_AUTH_ERROR',
227   'proto': {},
228   'time': 1395874542192.837,
229   'type': 'GetUpdates Response',
232 TEST_F('SyncInternalsWebUITest', 'Uninitialized', function() {
233   assertNotEquals(null, chrome.sync.aboutInfo);
234   expectTrue(this.hasInDetails(false, 'Summary', 'Uninitialized'));
237 // Test that username is set correctly when the user is signed in or not.
238 // On chromeos, browser tests are signed in by default.  On other platforms,
239 // browser tests are signed out.
240 GEN('#if defined(OS_CHROMEOS)');
241 TEST_F('SyncInternalsWebUITest', 'SignedIn', function() {
242   assertNotEquals(null, chrome.sync.aboutInfo);
243   expectTrue(this.hasInDetails(true, 'Username', 'stub-user@example.com'));
245 GEN('#else');
246 TEST_F('SyncInternalsWebUITest', 'SignedOut', function() {
247   assertNotEquals(null, chrome.sync.aboutInfo);
248   expectTrue(this.hasInDetails(true, 'Username', ''));
250 GEN('#endif  // defined(OS_CHROMEOS)');
252 TEST_F('SyncInternalsWebUITest', 'LoadPastedAboutInfo', function() {
253   // Expose the text field.
254   $('import-status').click();
256   // Fill it with fake data.
257   $('status-text').value = JSON.stringify(HARD_CODED_ABOUT_INFO);
259   // Trigger the import.
260   $('import-status').click();
262   expectTrue(this.hasInDetails(true, 'Summary', 'Sync service initialized'));
265 TEST_F('SyncInternalsWebUITest', 'NetworkEventsTest', function() {
266   networkEvent1 = new Event('onProtocolEvent');
267   networkEvent1.details = NETWORK_EVENT_DETAILS_1;
268   networkEvent2 = new Event('onProtocolEvent');
269   networkEvent2.details = NETWORK_EVENT_DETAILS_2;
271   chrome.sync.events.dispatchEvent(networkEvent1);
272   chrome.sync.events.dispatchEvent(networkEvent2);
274   expectEquals(2, $('traffic-event-container').children.length);
276   // Test that repeated events are not re-displayed.
277   chrome.sync.events.dispatchEvent(networkEvent1);
278   expectEquals(2, $('traffic-event-container').children.length);
281 TEST_F('SyncInternalsWebUITest', 'SearchTabDoesntChangeOnItemSelect',
282        function() {
283   // Select the search tab.
284   $('sync-search-tab').selected = true;
285   expectTrue($('sync-search-tab').selected);
287   // Build the data model and attach to result list.
288   cr.ui.List.decorate($('sync-results-list'));
289   $('sync-results-list').dataModel = new cr.ui.ArrayDataModel([
290     {
291       value: 'value 0',
292       toString: function() { return 'node 0'; },
293     },
294     {
295       value: 'value 1',
296       toString: function() { return 'node 1'; },
297     }
298   ]);
300   // Select the first list item and verify the search tab remains selected.
301   $('sync-results-list').getListItemByIndex(0).selected = true;
302   expectTrue($('sync-search-tab').selected);
305 TEST_F('SyncInternalsWebUITest', 'NodeBrowserTest', function() {
306   var getAllNodesSavedArgs = new SaveMockArguments();
307   this.mockHandler.expects(once()).
308       getAllNodes(getAllNodesSavedArgs.match(ANYTHING)).
309       will(callFunctionWithSavedArgs(getAllNodesSavedArgs,
310                                      chrome.sync.getAllNodesCallback,
311                                      HARD_CODED_ALL_NODES));
313   // Hit the refresh button.
314   $('node-browser-refresh-button').click();
316   // Check that the refresh time was updated.
317   expectNotEquals($('node-browser-refresh-time').textContent, 'Never');
319   // Verify some hard-coded assumptions.  These depend on the vaue of the
320   // hard-coded nodes, specified elsewhere in this file.
322   // Start with the tree itself.
323   var tree = $('sync-node-tree');
324   assertEquals(1, tree.items.length);
326   // Check the type root and expand it.
327   var typeRoot = tree.items[0];
328   expectFalse(typeRoot.expanded);
329   typeRoot.expanded = true;
330   assertEquals(1, typeRoot.items.length);
332   // An actual sync node.  The child of the type root.
333   var leaf = typeRoot.items[0];
335   // Verify that selecting it affects the details view.
336   expectTrue($('node-details').hasAttribute('hidden'));
337   leaf.selected = true;
338   expectFalse($('node-details').hasAttribute('hidden'));
341 TEST_F('SyncInternalsWebUITest', 'NodeBrowserRefreshOnTabSelect', function() {
342   var getAllNodesSavedArgs = new SaveMockArguments();
343   this.mockHandler.expects(once()).
344       getAllNodes(getAllNodesSavedArgs.match(ANYTHING)).
345       will(callFunctionWithSavedArgs(getAllNodesSavedArgs,
346                                      chrome.sync.getAllNodesCallback,
347                                      HARD_CODED_ALL_NODES));
349   // Should start with non-refreshed node browser.
350   expectEquals($('node-browser-refresh-time').textContent, 'Never');
352   // Selecting the tab will refresh it.
353   $('sync-browser-tab').selected = true;
354   expectNotEquals($('node-browser-refresh-time').textContent, 'Never');
356   // Re-selecting the tab shouldn't re-refresh.
357   $('node-browser-refresh-time').textContent = 'TestCanary';
358   $('sync-browser-tab').selected = false;
359   $('sync-browser-tab').selected = true;
360   expectEquals($('node-browser-refresh-time').textContent, 'TestCanary');
363 // Tests that the events log page correctly receives and displays an event.
364 TEST_F('SyncInternalsWebUITest', 'EventLogTest', function() {
365   // Dispatch an event.
366   var connectionEvent = new Event('onConnectionStatusChange');
367   connectionEvent.details = {'status': 'CONNECTION_OK'};
368   chrome.sync.events.dispatchEvent(connectionEvent);
370   // Verify that it is displayed in the events log.
371   var syncEventsTable = $('sync-events');
372   var firstRow = syncEventsTable.children[0];
374   // Makes some assumptions about column ordering.  We'll need re-think this if
375   // it turns out to be a maintenance burden.
376   assertEquals(4, firstRow.children.length);
377   var detailsText = firstRow.children[0].textContent;
378   var submoduleName = firstRow.children[1].textContent;
379   var eventName = firstRow.children[2].textContent;
381   expectGE(submoduleName.indexOf('manager'), 0,
382       'submoduleName=' + submoduleName);
383   expectGE(eventName.indexOf('onConnectionStatusChange'), 0,
384       'eventName=' + eventName);
385   expectGE(detailsText.indexOf('CONNECTION_OK'), 0,
386       'detailsText=' + detailsText);
389 TEST_F('SyncInternalsWebUITest', 'DumpSyncEventsToText', function() {
390   // Dispatch an event.
391   var connectionEvent = new Event('onConnectionStatusChange');
392   connectionEvent.details = {'status': 'CONNECTION_OK'};
393   chrome.sync.events.dispatchEvent(connectionEvent);
395   // Click the dump-to-text button.
396   $('dump-to-text').click();
398   // Verify our event is among the results.
399   var eventDumpText = $('data-dump').textContent;
401   expectGE(eventDumpText.indexOf('onConnectionStatusChange'), 0);
402   expectGE(eventDumpText.indexOf('CONNECTION_OK'), 0);