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

Side by Side Diff: chrome/test/data/webui/settings/search_engines_page_test.js

Issue 1666623006: MD Settings: Manage search engines 3/3, hooking up UI. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@manage_search_engines_handler
Patch Set: Nits. Created 4 years, 10 months 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
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 cr.define('settings_search_engines_page', function() {
6 /** @constructor */
7 var PromiseResolver = function() {
8 this.promise = new Promise(function(resolve, reject) {
9 this.resolve = resolve;
10 this.reject = reject;
11 }.bind(this));
12 };
13
14 // See |defineTestBrowserProxy| function below (this class can only be defined
15 // after search_engines_browser_proxy.html has been imported.
16 var TestSearchEnginesBrowserProxy = null;
17
18 /**
19 * @return {!Promise} A promise resolved after the
20 * TestSearchEnginesBrowserProxy class is defined.
21 */
22 function defineTestBrowserProxy() {
23 if (TestSearchEnginesBrowserProxy != null)
24 return Promise.resolve();
25
26 var browserProxyImportPath =
27 'chrome://md-settings/search_engines_page/search_engines_browser_proxy.h tml';
28 return PolymerTest.importHtml(browserProxyImportPath).then(function() {
29 /**
30 * A test version of SearchEnginesBrowserProxy. Provides helper methods fo r
31 * allowing tests to know when a method was called, as well as specifying
32 * mock responses.
33 *
34 * @constructor
35 * @extends {settings.SearchEnginesBrowserProxy}
36 */
37 TestSearchEnginesBrowserProxy = function() {
38 /** @private {!Map<string, !PromiseResolver>} */
39 this.resolverMap_ = this.buildResolverMap_();
40
41 /** @private {!SearchEnginesInfo} */
42 this.searchEnginesInfo_ = {};
43 };
44
45 TestSearchEnginesBrowserProxy.prototype = {
46 __proto__: settings.SearchEnginesBrowserProxy.prototype,
47
48 /**
49 * @return {!Map<string, !PromiseResolver>}
50 * @private
51 */
52 buildResolverMap_: function() {
53 var resolverMap = new Map();
54 var wrapperMethods = [
55 'getSearchEnginesList',
56 'removeSearchEngine',
57 'searchEngineEditCancelled',
58 'searchEngineEditCompleted',
59 'searchEngineEditStarted',
60 'setDefaultSearchEngine',
61 'validateSearchEngineInput',
62 ];
63 wrapperMethods.forEach(function(methodName) {
64 resolverMap.set(methodName, new PromiseResolver());
65 });
66 return resolverMap;
67 },
68
69 /**
70 * @param {string} methodName
71 * @return {!Promise} A promise that is resolved when the given method i s
72 * called.
73 */
74 whenCalled: function(methodName) {
75 return this.resolverMap_.get(methodName).promise;
76 },
77
78 /**
79 * Resets the PromiseResolver associated with the given method.
80 * @param {string} methodName
81 */
82 resetResolver: function(methodName) {
83 this.resolverMap_.set(methodName, new PromiseResolver());
84 },
85
86 /** @override */
87 setDefaultSearchEngine: function(modelIndex) {
88 this.resolverMap_.get('setDefaultSearchEngine').resolve(modelIndex);
89 },
90
91 /** @override */
92 removeSearchEngine: function(modelIndex) {
93 this.resolverMap_.get('removeSearchEngine').resolve(modelIndex);
94 },
95
96 /** @override */
97 searchEngineEditStarted: function(modelIndex) {
98 this.resolverMap_.get('searchEngineEditStarted').resolve(modelIndex);
99 },
100
101 /** @override */
102 searchEngineEditCancelled: function() {
103 this.resolverMap_.get('searchEngineEditCancelled').resolve();
104 },
105
106 /** @override */
107 searchEngineEditCompleted: function(searchEngine, keyword, queryUrl) {
108 this.resolverMap_.get('searchEngineEditCompleted').resolve();
109 },
110
111 /**
112 * Sets the response to be returned by |getSearchEnginesList|.
113 * @param {!SearchEnginesInfo}
114 */
115 setGetSearchEnginesList: function(searchEnginesInfo) {
116 this.searchEnginesInfo_ = searchEnginesInfo;
117 },
118
119 /** @override */
120 getSearchEnginesList: function() {
121 this.resolverMap_.get('getSearchEnginesList').resolve();
122 return Promise.resolve(this.searchEnginesInfo_);
123 },
124
125 /** @override */
126 validateSearchEngineInput: function(fieldName, fieldValue) {
127 this.resolverMap_.get('validateSearchEngineInput').resolve();
128 return Promise.resolve(true);
129 },
130 };
131 });
132 }
133
134 /** @return {!SearchEngine} */
135 var getSampleSearchEngine = function() {
136 return {
137 canBeDefault: false,
138 canBeEdited: true,
139 canBeRemoved: false,
140 default: false,
141 displayName: "Google",
142 iconURL: "http://www.google.com/favicon.ico",
143 isOmniboxExtension: false,
144 keyword: "google.com",
145 modelIndex: 0,
146 name: "Google",
147 url: "https://search.foo.com/search?p=%s",
148 urlLocked: false,
149 };
150 };
151
152
153 function registerDialogTests() {
154 suite('AddSearchEngineDialogTests', function() {
155 /** @type {?SettingsAddSearchEngineDialog} */
156 var dialog = null;
157 var browserProxy = null;
158
159 suiteSetup(function() {
160 return Promise.all([
161 defineTestBrowserProxy(),
162 PolymerTest.importHtml('chrome://md-settings/i18n_setup.html'),
163 PolymerTest.importHtml(
164 'chrome://md-settings/search_engines_page/search_engine_dialog.html' ),
165 ]);
166 });
167
168 setup(function() {
169 browserProxy = new TestSearchEnginesBrowserProxy();
170 settings.SearchEnginesBrowserProxy.instance_ = browserProxy;
171 PolymerTest.clearBody();
172 dialog = document.createElement('settings-search-engine-dialog');
173 document.body.appendChild(dialog);
174 });
175
176 teardown(function() {dialog.remove();});
177
178 // Tests that the dialog calls 'searchEngineEditStarted' and
179 // 'searchEngineEditCancelled' when closed from the 'x' button.
180 test('DialogOpenAndClose', function() {
181 return browserProxy.whenCalled('searchEngineEditStarted').then(
182 function() {
183 MockInteractions.tap(dialog.$['close']);
184 return browserProxy.whenCalled('searchEngineEditCancelled');
185 });
186 });
187
188 // Tests that the dialog calls 'searchEngineEditStarted' and
189 // 'searchEngineEditCancelled' when closed from the 'cancel' button.
190 test('DialogOpenAndCancel', function() {
191 return browserProxy.whenCalled('searchEngineEditStarted').then(
192 function() {
193 MockInteractions.tap(dialog.$['cancel']);
194 return browserProxy.whenCalled('searchEngineEditCancelled');
195 });
196 });
197
198 // Tests the dialog to add a new search engine. Specifically
199 // - paper-input elements are empty initially.
200 // - action button initially disabled.
201 // - validation is triggered on 'focus'. 'change' is not teted because
202 // MockInteractions does not currently provide a way to trigger such
203 // events.
204 // - action button is enabled when all fields are valid.
205 // - action button triggers appropriate browser signal when tapped.
206 test('DialogAddSearchEngine', function() {
207 /**
208 * Asserts that the given paper-input element is empty.
209 * @param {string} inputId
210 */
211 var assertInputEmpty = function(inputId) {
212 var inputElement = dialog.$[inputId];
213 assertTrue(!!inputElement);
214 assertEquals(0, inputElement.value.length);
215 };
216
217 /**
218 * Asserts that the given paper-input element triggers validation when
219 * focused.
220 * @param {string} inputId
221 * @return {!Promise} A promise firing when assertion has completed.
222 */
223 var assertInputValidation = function(inputId) {
224 browserProxy.resetResolver('validateSearchEngineInput');
225 MockInteractions.focus(dialog.$[inputId]);
226 return browserProxy.whenCalled('validateSearchEngineInput');
227 };
228 var actionButton = dialog.$['actionButton'];
229
230 assertInputEmpty('searchEngine');
231 assertInputEmpty('keyword');
232 assertInputEmpty('queryUrl');
233 assertTrue(actionButton.disabled);
234
235 return assertInputValidation('searchEngine').then(function() {
236 return assertInputValidation('keyword');
237 }).then(function() {
238 return assertInputValidation('queryUrl');
239 }).then(function() {
240 // Manually set the text to a non-empty string for all fields.
241 dialog.$['searchEngine'].value = 'foo';
242 dialog.$['keyword'].value = 'bar';
243 dialog.$['queryUrl'].value = 'baz';
244
245 // MockInteractions does not provide a way to trigger a 'change' event
246 // yet. Triggering the 'focus' event instead, to update the state of
247 // the action button.
248 return assertInputValidation('searchEngine');
249 }).then(function() {
250 // Assert that the action button has been enabled now that all input
251 // is valid and non-empty.
252 assertFalse(actionButton.disabled);
253 MockInteractions.tap(actionButton);
254 return browserProxy.whenCalled('searchEngineEditCompleted');
255 });
256 });
257
258 });
259 }
260
261 function registerEntryTests() {
262 suite('SearchEngineEntryTests', function() {
263 /** @type {?SettingsSearchEngineEntryElement} */
264 var entry = null;
265
266 var browserProxy = null;
267
268 suiteSetup(function() {
269 return Promise.all([
270 defineTestBrowserProxy(),
271 PolymerTest.importHtml(
272 'chrome://md-settings/search_engines_page/search_engine_entry.html') ,
273 ]);
274 });
275
276 setup(function() {
277 browserProxy = new TestSearchEnginesBrowserProxy();
278 settings.SearchEnginesBrowserProxy.instance_ = browserProxy;
279 PolymerTest.clearBody();
280 entry = document.createElement('settings-search-engine-entry');
281 entry.set('engine', getSampleSearchEngine());
282 document.body.appendChild(entry);
283 });
284
285 teardown(function() {entry.remove();});
286
287 test('RemoveSearchEngine', function() {
288 var deleteButton = entry.$['delete'];
289 assertTrue(!!deleteButton);
290 MockInteractions.tap(deleteButton);
291 return browserProxy.whenCalled('removeSearchEngine').then(
292 function(modelIndex) {
293 assertEquals(entry.engine.modelIndex, modelIndex);
294 });
295 });
296
297 test('MakeDefault', function() {
298 var makeDefaultButton = entry.$['makeDefault'];
299 assertTrue(!!makeDefaultButton);
300 MockInteractions.tap(makeDefaultButton);
301 return browserProxy.whenCalled('setDefaultSearchEngine').then(
302 function(modelIndex) {
303 assertEquals(entry.engine.modelIndex, modelIndex);
304 });
305 });
306
307 // Test that the "make default" and "remove" buttons are hidden for
308 // the default search engine.
309 test('DefaultSearchEngineHiddenButtons', function() {
310 /**
311 * @param {string} buttonId
312 * @param {boolean} visible
313 */
314 var assertButtonVisibility = function(buttonId, visible) {
315 var buttonEl = entry.$[buttonId];
316 assertTrue(!!buttonEl);
317 assertEquals(!visible, buttonEl.hidden);
318 };
319 assertButtonVisibility('makeDefault', true);
320 assertButtonVisibility('edit', true);
321 assertButtonVisibility('delete', true);
322
323 // Mark the engine as the "default" one.
324 var engine = getSampleSearchEngine();
325 engine.default = true;
326 entry.set('engine', engine);
327
328 assertButtonVisibility('makeDefault', false);
329 assertButtonVisibility('edit', true);
330 assertButtonVisibility('delete', false);
331 });
332
333 // Test that clicking the "edit" button brings up a dialog.
334 test('Edit', function() {
335 var engine = entry.engine;
336 var editButton = entry.$['edit'];
337 assertTrue(!!editButton);
338 MockInteractions.tap(editButton);
339 return browserProxy.whenCalled('searchEngineEditStarted').then(
340 function(modelIndex) {
341 assertEquals(engine.modelIndex, modelIndex);
342 var dialog = entry.$$('settings-search-engine-dialog');
343 assertTrue(!!dialog);
344
345 // Check that the paper-input fields are pre-populated.
346 assertEquals(engine.displayName, dialog.$['searchEngine'].value);
347 assertEquals(engine.keyword, dialog.$['keyword'].value);
348 assertEquals(engine.url, dialog.$['queryUrl'].value);
349
350 assertFalse(dialog.$['actionButton'].disabled);
351 });
352 });
353 });
354 }
355
356 function registerPageTests() {
357 suite('SearchEnginePageTests', function() {
358 /** @type {?SettingsSearchEnginesPageElement} */
359 var page = null;
360
361 var browserProxy = null;
362
363 /** @type {!SearchEnginesInfo} */
364 var searchEnginesInfo = {
365 defaults: [getSampleSearchEngine()],
366 others: [],
367 extensions: [],
368 };
369
370 suiteSetup(function() {
371 return Promise.all([
372 defineTestBrowserProxy(),
373 PolymerTest.importHtml('chrome://md-settings/i18n_setup.html'),
374 PolymerTest.importHtml(
375 'chrome://md-settings/search_engines_page/search_engines_page.html') ,
376 ]);
377 });
378
379 setup(function() {
380 browserProxy = new TestSearchEnginesBrowserProxy();
381 browserProxy.setGetSearchEnginesList(searchEnginesInfo);
382 settings.SearchEnginesBrowserProxy.instance_ = browserProxy;
383 PolymerTest.clearBody();
384 page = document.createElement('settings-search-engines-page');
385 document.body.appendChild(page);
386 });
387
388 teardown(function() {page.remove();});
389
390 // Tests that the page is querying and displaying search engine info on
391 // startup.
392 test('Initialization', function() {
393 return browserProxy.whenCalled('getSearchEnginesList').then(function() {
394 var searchEnginesLists = Polymer.dom(page.shadowRoot).
395 querySelectorAll('settings-search-engines-list');
396 assertEquals(2, searchEnginesLists.length);
397
398 Polymer.dom.flush();
399 var defaultsList = searchEnginesLists[0];
400 var defaultsEntries = Polymer.dom(defaultsList.shadowRoot).
401 querySelectorAll('settings-search-engine-entry');
402 assertEquals(
403 searchEnginesInfo.defaults.length, defaultsEntries.length);
404
405 var othersList = searchEnginesLists[1];
406 var othersEntries = Polymer.dom(othersList.shadowRoot).
407 querySelectorAll('settings-search-engine-entry');
408 assertEquals(
409 searchEnginesInfo.others.length, othersEntries.length);
410 });
411 });
412
413 // Tests that the add search engine dialog opens when the corresponding
414 // button is tapped.
415 test('AddSearchEngineDialog', function() {
416 assertFalse(!!page.$$('settings-search-engine-dialog'));
417 var addSearchEngineButton = page.$['addSearchEngine'];
418 assertTrue(!!addSearchEngineButton);
419
420 MockInteractions.tap(addSearchEngineButton);
421 Polymer.dom.flush();
422 assertTrue(!!page.$$('settings-search-engine-dialog'));
423 });
424 });
425 }
426
427 return {
428 registerDialogTests: registerDialogTests,
429 registerEntryTests: registerEntryTests,
430 registerPageTests: registerPageTests,
431 };
432 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698