PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/chrome/test/data/webui/settings/settings_main_test.js

https://github.com/chromium/chromium
JavaScript | 365 lines | 247 code | 59 blank | 59 comment | 5 complexity | e6de1133a031d962952781b9db1d8947 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, BSD-3-Clause
  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. // clang-format off
  5. import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
  6. import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
  7. import {CrSettingsPrefs, pageVisibility, Router, routes, SearchRequest, setSearchManagerForTesting} from 'chrome://settings/settings.js';
  8. import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
  9. import {eventToPromise, whenAttributeIs} from 'chrome://webui-test/test_util.js';
  10. // clang-format on
  11. /**
  12. * Extending TestBrowserProxy even though SearchManager is not a browser proxy
  13. * itself. Essentially TestBrowserProxy can act as a "proxy" for any external
  14. * dependency, not just "browser proxies" (and maybe should be renamed to
  15. * TestProxy).
  16. *
  17. * @implements {SearchManager}
  18. */
  19. class TestSearchManager extends TestBrowserProxy {
  20. constructor() {
  21. super([
  22. 'search',
  23. ]);
  24. /** @private {boolean} */
  25. this.matchesFound_ = true;
  26. /** @private {?SearchRequest} */
  27. this.searchRequest_ = null;
  28. }
  29. /**
  30. * @param {boolean} matchesFound
  31. */
  32. setMatchesFound(matchesFound) {
  33. this.matchesFound_ = matchesFound;
  34. }
  35. /** @override */
  36. search(text, page) {
  37. this.methodCalled('search', text);
  38. if (this.searchRequest_ == null || !this.searchRequest_.isSame(text)) {
  39. this.searchRequest_ = new SearchRequest(text);
  40. this.searchRequest_.finished = true;
  41. this.searchRequest_.updateMatches(this.matchesFound_);
  42. this.searchRequest_.resolver.resolve(this.searchRequest_);
  43. }
  44. return this.searchRequest_.resolver.promise;
  45. }
  46. }
  47. let settingsPrefs = null;
  48. suiteSetup(function() {
  49. settingsPrefs = document.createElement('settings-prefs');
  50. return CrSettingsPrefs.initialized;
  51. });
  52. suite('MainPageTests', function() {
  53. /** @type {?TestSearchManager} */
  54. let searchManager = null;
  55. /** @type {?SettingsMainElement} */
  56. let settingsMain = null;
  57. setup(function() {
  58. Router.getInstance().navigateTo(routes.BASIC);
  59. searchManager = new TestSearchManager();
  60. setSearchManagerForTesting(searchManager);
  61. PolymerTest.clearBody();
  62. settingsMain = document.createElement('settings-main');
  63. settingsMain.prefs = settingsPrefs.prefs;
  64. settingsMain.toolbarSpinnerActive = false;
  65. settingsMain.pageVisibility = pageVisibility;
  66. document.body.appendChild(settingsMain);
  67. });
  68. teardown(function() {
  69. settingsMain.remove();
  70. });
  71. test('searchContents() triggers SearchManager', function() {
  72. flush();
  73. const expectedQuery1 = 'foo';
  74. const expectedQuery2 = 'bar';
  75. const expectedQuery3 = '';
  76. return settingsMain.searchContents(expectedQuery1)
  77. .then(function() {
  78. return searchManager.whenCalled('search');
  79. })
  80. .then(function(query) {
  81. assertEquals(expectedQuery1, query);
  82. searchManager.resetResolver('search');
  83. return settingsMain.searchContents(expectedQuery2);
  84. })
  85. .then(function() {
  86. return searchManager.whenCalled('search');
  87. })
  88. .then(function(query) {
  89. assertEquals(expectedQuery2, query);
  90. searchManager.resetResolver('search');
  91. return settingsMain.searchContents(expectedQuery3);
  92. })
  93. .then(function() {
  94. return searchManager.whenCalled('search');
  95. })
  96. .then(function(query) {
  97. assertEquals(expectedQuery3, query);
  98. });
  99. });
  100. function showManagedHeader() {
  101. return settingsMain.showManagedHeader_(
  102. settingsMain.inSearchMode_, settingsMain.showingSubpage_,
  103. settingsMain.showPages_.about);
  104. }
  105. test('managed header hides when searching', function() {
  106. flush();
  107. assertTrue(showManagedHeader());
  108. searchManager.setMatchesFound(false);
  109. return settingsMain.searchContents('Query1')
  110. .then(() => {
  111. assertFalse(showManagedHeader());
  112. searchManager.setMatchesFound(true);
  113. return settingsMain.searchContents('Query2');
  114. })
  115. .then(() => {
  116. assertFalse(showManagedHeader());
  117. });
  118. });
  119. test('managed header hides when showing subpage', function() {
  120. flush();
  121. assertTrue(showManagedHeader());
  122. const basicPage = settingsMain.$$('settings-basic-page');
  123. basicPage.fire('subpage-expand', {});
  124. assertFalse(showManagedHeader());
  125. });
  126. test('managed header hides when showing about page', function() {
  127. flush();
  128. assertTrue(showManagedHeader());
  129. Router.getInstance().navigateTo(routes.ABOUT);
  130. assertFalse(showManagedHeader());
  131. });
  132. /** @return {!HTMLElement} */
  133. function getToggleContainer() {
  134. const page = settingsMain.$$('settings-basic-page');
  135. assertTrue(!!page);
  136. const toggleContainer = page.$$('#toggleContainer');
  137. assertTrue(!!toggleContainer);
  138. return toggleContainer;
  139. }
  140. /**
  141. * Asserts that the Advanced toggle container exists in the combined
  142. * settings page and asserts whether it should be visible.
  143. * @param {boolean} expectedVisible
  144. */
  145. function assertToggleContainerVisible(expectedVisible) {
  146. const toggleContainer = getToggleContainer();
  147. if (expectedVisible) {
  148. assertNotEquals('none', toggleContainer.style.display);
  149. } else {
  150. assertEquals('none', toggleContainer.style.display);
  151. }
  152. }
  153. test('no results page shows and hides', function() {
  154. flush();
  155. const noSearchResults = settingsMain.$.noSearchResults;
  156. assertTrue(!!noSearchResults);
  157. assertTrue(noSearchResults.hidden);
  158. assertToggleContainerVisible(true);
  159. searchManager.setMatchesFound(false);
  160. return settingsMain.searchContents('Query1')
  161. .then(function() {
  162. assertFalse(noSearchResults.hidden);
  163. assertToggleContainerVisible(false);
  164. searchManager.setMatchesFound(true);
  165. return settingsMain.searchContents('Query2');
  166. })
  167. .then(function() {
  168. assertTrue(noSearchResults.hidden);
  169. });
  170. });
  171. // Ensure that when the user clears the search box, the "no results" page
  172. // is hidden and the "advanced page toggle" is visible again.
  173. test('no results page hides on clear', function() {
  174. flush();
  175. const noSearchResults = settingsMain.$.noSearchResults;
  176. assertTrue(!!noSearchResults);
  177. assertTrue(noSearchResults.hidden);
  178. assertToggleContainerVisible(true);
  179. searchManager.setMatchesFound(false);
  180. // Clearing the search box is effectively a search for the empty string.
  181. return settingsMain.searchContents('').then(function() {
  182. flush();
  183. assertTrue(noSearchResults.hidden);
  184. assertToggleContainerVisible(true);
  185. });
  186. });
  187. /**
  188. * Asserts the visibility of the basic and advanced pages.
  189. * @param {string} Expected 'display' value for the basic page.
  190. * @param {string} Expected 'display' value for the advanced page.
  191. * @return {!Promise}
  192. */
  193. function assertPageVisibility(expectedBasic, expectedAdvanced) {
  194. flush();
  195. const page = settingsMain.$$('settings-basic-page');
  196. assertEquals(
  197. expectedBasic, getComputedStyle(page.$$('#basicPage')).display);
  198. return page.$$('#advancedPageTemplate').get().then(function(advancedPage) {
  199. assertEquals(expectedAdvanced, getComputedStyle(advancedPage).display);
  200. });
  201. }
  202. // TODO(michaelpg): It would be better not to drill into
  203. // settings-basic-page. If search should indeed only work in Settings
  204. // (as opposed to Advanced), perhaps some of this logic should be
  205. // delegated to settings-basic-page now instead of settings-main.
  206. /**
  207. * Asserts the visibility of the basic and advanced pages after exiting
  208. * search mode.
  209. * @param {string} Expected 'display' value for the advanced page.
  210. * @return {!Promise}
  211. */
  212. function assertAdvancedVisibilityAfterSearch(expectedAdvanced) {
  213. searchManager.setMatchesFound(true);
  214. return settingsMain.searchContents('Query1')
  215. .then(function() {
  216. searchManager.setMatchesFound(false);
  217. return settingsMain.searchContents('');
  218. })
  219. .then(function() {
  220. // Imitate behavior of clearing search.
  221. Router.getInstance().navigateTo(routes.BASIC);
  222. flush();
  223. return assertPageVisibility('block', expectedAdvanced);
  224. });
  225. }
  226. test('exiting search mode, advanced collapsed', function() {
  227. // Simulating searching while the advanced page is collapsed.
  228. settingsMain.currentRouteChanged(routes.BASIC);
  229. flush();
  230. return assertAdvancedVisibilityAfterSearch('none');
  231. });
  232. // Ensure that clearing the search results restores both "basic" and
  233. // "advanced" page, when the search has been initiated from a subpage
  234. // whose parent is the "advanced" page.
  235. test('exiting search mode, advanced expanded', function() {
  236. // Trigger basic page to be rendered once.
  237. Router.getInstance().navigateTo(routes.APPEARANCE);
  238. flush();
  239. // Navigate to an "advanced" subpage.
  240. Router.getInstance().navigateTo(routes.LANGUAGES);
  241. flush();
  242. return assertAdvancedVisibilityAfterSearch('block');
  243. });
  244. // Ensure that searching, then entering a subpage, then going back
  245. // lands the user in a page where both basic and advanced sections are
  246. // visible, because the page is still in search mode.
  247. test('returning from subpage to search results', function() {
  248. Router.getInstance().navigateTo(routes.BASIC);
  249. flush();
  250. searchManager.setMatchesFound(true);
  251. return settingsMain.searchContents('Query1').then(function() {
  252. // Simulate navigating into a subpage.
  253. Router.getInstance().navigateTo(routes.SEARCH_ENGINES);
  254. settingsMain.$$('settings-basic-page').fire('subpage-expand');
  255. flush();
  256. // Simulate clicking the left arrow to go back to the search results.
  257. Router.getInstance().navigateTo(routes.BASIC);
  258. return assertPageVisibility('block', 'block');
  259. });
  260. });
  261. // TODO(michaelpg): Move these to a new test for settings-basic-page.
  262. test('can collapse advanced on advanced section route', function() {
  263. Router.getInstance().navigateTo(routes.LANGUAGES);
  264. flush();
  265. const basicPage = settingsMain.$$('settings-basic-page');
  266. let advancedPage = null;
  267. return eventToPromise('showing-section', settingsMain)
  268. .then(() => {
  269. return basicPage.$$('#advancedPageTemplate').get();
  270. })
  271. .then(function(advanced) {
  272. advancedPage = advanced;
  273. return assertPageVisibility('block', 'block');
  274. })
  275. .then(function() {
  276. const whenHidden = whenAttributeIs(advancedPage, 'hidden', '');
  277. eventToPromise('scroll-to-bottom', basicPage)
  278. .then(event => event.detail.callback());
  279. const advancedToggle =
  280. getToggleContainer().querySelector('#advancedToggle');
  281. assertTrue(!!advancedToggle);
  282. advancedToggle.click();
  283. return whenHidden;
  284. })
  285. .then(function() {
  286. return assertPageVisibility('block', 'none');
  287. });
  288. });
  289. test('navigating to a basic page does not collapse advanced', function() {
  290. Router.getInstance().navigateTo(routes.LANGUAGES);
  291. flush();
  292. assertToggleContainerVisible(true);
  293. Router.getInstance().navigateTo(routes.PEOPLE);
  294. flush();
  295. return assertPageVisibility('block', 'block');
  296. });
  297. test('updates the title based on current route', function() {
  298. Router.getInstance().navigateTo(routes.BASIC);
  299. assertEquals(document.title, loadTimeData.getString('settings'));
  300. Router.getInstance().navigateTo(routes.ABOUT);
  301. assertEquals(
  302. document.title,
  303. loadTimeData.getStringF(
  304. 'settingsAltPageTitle', loadTimeData.getString('aboutPageTitle')));
  305. });
  306. });