Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 // -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 "use strict";
8 var gEdit = null;
10 /*=============================================================================
11 Search engine mocking utilities
12 =============================================================================*/
14 var gEngine = null;
16 const kSearchEngineName = "Foo";
17 const kSearchEngineURI = chromeRoot + "res/testEngine.xml";
19 /*
20 * addMockSearchDefault - adds a mock search engine to the top of the engine list.
21 */
22 function addMockSearchDefault(aTimeoutMs) {
23 let deferred = Promise.defer();
24 let timeoutMs = aTimeoutMs || kDefaultWait;
25 let timerID = 0;
27 function engineAddObserver(aSubject, aTopic, aData) {
28 if (aData != "engine-added")
29 return;
31 gEngine = Services.search.getEngineByName(kSearchEngineName);
32 Services.obs.removeObserver(engineAddObserver, "browser-search-engine-modified");
33 clearTimeout(timerID);
34 gEngine.hidden = false;
35 ok(gEngine, "mock engine was added");
36 deferred.resolve();
37 }
39 if (gEngine) {
40 deferred.resolve();
41 return deferred.promise;
42 }
44 timerID = setTimeout(function ids_canceller() {
45 Services.obs.removeObserver(engineAddObserver, "browser-search-engine-modified");
46 deferred.reject(new Error("search add timeout"));
47 }, timeoutMs);
49 Services.obs.addObserver(engineAddObserver, "browser-search-engine-modified", false);
50 Services.search.addEngine(kSearchEngineURI, Ci.nsISearchEngine.DATA_XML,
51 "data:image/x-icon,%00", false);
52 return deferred.promise;
53 }
55 /*
56 * removeMockSearchDefault - removes mock "Foo" search engine.
57 */
59 function removeMockSearchDefault(aTimeoutMs) {
60 let deferred = Promise.defer();
61 let timeoutMs = aTimeoutMs || kDefaultWait;
62 let timerID = 0;
64 function engineRemoveObserver(aSubject, aTopic, aData) {
65 if (aData != "engine-removed")
66 return;
68 clearTimeout(timerID);
69 gEngine = null;
70 Services.obs.removeObserver(engineRemoveObserver, "browser-search-engine-modified");
71 deferred.resolve();
72 }
74 if (!gEngine) {
75 deferred.resolve();
76 return deferred.promise;
77 }
79 timerID = setTimeout(function ids_canceller() {
80 Services.obs.removeObserver(engineRemoveObserver, "browser-search-engine-modified");
81 deferred.reject(new Error("search remove timeout"));
82 }, timeoutMs);
84 Services.obs.addObserver(engineRemoveObserver, "browser-search-engine-modified", false);
85 Services.search.removeEngine(gEngine);
86 return deferred.promise;
87 }
89 /*=============================================================================
90 Test cases
91 =============================================================================*/
93 function test() {
94 waitForExplicitFinish();
95 runTests();
96 }
98 function setUp() {
99 if (!gEdit)
100 gEdit = document.getElementById("urlbar-edit");
102 yield addTab("about:blank");
103 yield showNavBar();
104 }
106 function tearDown() {
107 Browser.closeTab(Browser.selectedTab, { forceClose: true });
108 }
110 gTests.push({
111 desc: "search engines update",
112 setUp: setUp,
113 tearDown: tearDown,
114 run: function testSearchEngine() {
115 // If the XBL hasn't initialized yet, open the popup so that it will.
116 if (gEdit.popup._searches == undefined) {
117 gEdit.openPopup();
118 gEdit.closePopup();
119 }
120 yield waitForCondition(() => gEdit.popup._searches.itemCount);
122 let numSearches = gEdit.popup._searches.itemCount;
123 function getEngineItem() {
124 return gEdit.popup._searches.querySelector("richgriditem[value="+kSearchEngineName+"]");
125 }
127 yield addMockSearchDefault();
128 is(gEdit.popup._searches.itemCount, numSearches + 1, "added search engine count");
129 ok(getEngineItem(), "added search engine item");
131 yield removeMockSearchDefault();
132 is(gEdit.popup._searches.itemCount, numSearches, "normal search engine count");
133 ok(!getEngineItem(), "added search engine item");
134 }
135 });
137 gTests.push({
138 desc: "display autocomplete while typing, handle enter",
139 setUp: setUp,
140 tearDown: tearDown,
141 run: function testUrlbarTyping() {
142 sendElementTap(window, gEdit);
143 ok(gEdit.isEditing, "focus urlbar: in editing mode");
144 ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
146 EventUtils.sendString("about:blank", window);
147 let opened = yield waitForCondition(() => gEdit.popup.popupOpen);
148 ok(opened, "type in urlbar: popup opens");
150 EventUtils.synthesizeKey("VK_RETURN", {}, window);
151 let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
152 ok(closed, "hit enter in urlbar: popup closes, page loads");
153 ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
154 }
155 });
157 gTests.push({
158 desc: "Control-Enter in urlbar",
159 setUp: setUp,
160 tearDown: tearDown,
161 run: function () {
162 sendElementTap(window, gEdit);
163 ok(gEdit.isEditing, "focus urlbar: in editing mode");
165 EventUtils.sendString("example", window);
166 EventUtils.synthesizeKey("VK_RETURN", { accelKey: true }, window);
167 is(gEdit.value, "www.example.com", "Control-enter adds www. and .com");
168 ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
169 }
170 });
172 gTests.push({
173 desc: "Shift-Enter in urlbar",
174 setUp: setUp,
175 tearDown: tearDown,
176 run: function () {
177 sendElementTap(window, gEdit);
178 ok(gEdit.isEditing, "focus urlbar: in editing mode");
180 EventUtils.sendString("example", window);
181 EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true }, window);
182 is(gEdit.value, "www.example.net", "Shift-enter adds www. and .net");
183 ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
184 }
185 });
187 gTests.push({
188 desc: "Control-Shift-Enter in urlbar",
189 setUp: setUp,
190 tearDown: tearDown,
191 run: function () {
192 sendElementTap(window, gEdit);
193 ok(gEdit.isEditing, "focus urlbar: in editing mode");
195 EventUtils.sendString("example", window);
196 EventUtils.synthesizeKey("VK_RETURN", { accelKey: true, shiftKey: true }, window);
197 is(gEdit.value, "www.example.org", "Shift-enter adds www. and .org");
198 ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
199 }
200 });
202 gTests.push({
203 desc: "display and select a search with keyboard",
204 setUp: setUp,
205 tearDown: tearDown,
206 run: function testSearchKeyboard() {
207 yield addMockSearchDefault();
209 yield waitForCondition(() => !Browser.selectedTab.isLoading());
211 sendElementTap(window, gEdit);
212 ok(gEdit.isEditing, "focus urlbar: in editing mode");
213 ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
215 let search = "mozilla";
216 EventUtils.sendString(search, window);
217 yield waitForCondition(() => gEdit.popup.popupOpen);
219 // XXX We should probably change the keyboard selection behavior entirely,
220 // given that it makes little to no sense, but that's a job for a later patch.
222 EventUtils.synthesizeKey("VK_DOWN", {}, window);
223 is(gEdit.popup.selectedIndex, -1, "key select search: no result selected");
224 is(gEdit.popup._searches.selectedIndex, 0, "key select search: first search selected");
226 let engines = Services.search.getVisibleEngines();
227 for (let i = 0, max = engines.length - 1; i < max; i++) {
228 is(gEdit.popup._searches.selectedIndex, i, "key select search: next index");
229 EventUtils.synthesizeKey("VK_DOWN", {}, window);
230 }
232 let existingValue = gEdit.value;
233 EventUtils.synthesizeKey("VK_RETURN", {}, window);
235 yield waitForCondition(() => gEdit.value != existingValue);
237 let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
238 ok(closed, "hit enter in urlbar: popup closes, page loads");
239 ok(!gEdit.isEditing, "hit enter in urlbar: not in editing mode");
241 let searchSubmission = gEngine.getSubmission(search, null);
242 let trimmedSubmission = gEdit.trimValue(searchSubmission.uri.spec);
243 is(gEdit.value, trimmedSubmission, "hit enter in urlbar: search conducted");
245 yield removeMockSearchDefault();
246 }
247 });
249 gTests.push({
250 desc: "display and select a search with touch",
251 setUp: setUp,
252 tearDown: tearDown,
253 run: function testUrlbarSearchesTouch() {
254 yield addMockSearchDefault();
256 yield waitForCondition(() => !Browser.selectedTab.isLoading());
258 sendElementTap(window, gEdit);
259 ok(gEdit.isEditing, "focus urlbar: in editing mode");
260 ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
262 let search = "mozilla";
263 EventUtils.sendString(search, window);
264 yield waitForCondition(() => gEdit.popup.popupOpen);
266 sendElementTap(window, gEdit.popup._searches.lastChild);
268 let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
269 ok(closed, "tap search option: popup closes, page loads");
270 ok(!gEdit.isEditing, "tap search option: not in editing mode");
272 let searchSubmission = gEngine.getSubmission(search, null);
273 let trimmedSubmission = gEdit.trimValue(searchSubmission.uri.spec);
274 is(gEdit.value, trimmedSubmission, "tap search option: search conducted");
276 yield removeMockSearchDefault();
277 }
278 });
280 gTests.push({
281 desc: "bug 897131 - url bar update after content tap + edge swipe",
282 tearDown: tearDown,
283 run: function testUrlbarTyping() {
284 let tab = yield addTab("about:mozilla");
285 yield showNavBar();
287 sendElementTap(window, gEdit);
288 ok(gEdit.isEditing, "focus urlbar: in editing mode");
289 ok(!gEdit.popup.popupOpen, "focus urlbar: popup not open yet");
291 EventUtils.sendString("about:blank", window);
292 let opened = yield waitForCondition(() => gEdit.popup.popupOpen);
293 ok(opened, "type in urlbar: popup opens");
295 sendElementTap(window, tab.browser);
297 let closed = yield waitForCondition(() => !gEdit.popup.popupOpen);
298 ok(closed, "autocomplete closed after tap on content");
299 ok(!ContextUI.navbarVisible, "navbar closed");
301 let event = document.createEvent("Events");
302 event.initEvent("MozEdgeUICompleted", true, false);
303 window.dispatchEvent(event);
305 ok(ContextUI.navbarVisible, "navbar visible");
306 is(gEdit.value, "about:mozilla", "url bar text refreshed");
307 }
308 });
310 gTests.push({
311 desc: "Bug 916383 - Invisible autocomplete items selectable by keyboard when 'your results' not shown",
312 tearDown: tearDown,
313 run: function testBug916383() {
314 yield addTab("about:start");
315 yield showNavBar();
317 sendElementTap(window, gEdit);
319 let bookmarkItem = Browser.selectedBrowser.contentWindow.BookmarksStartView._grid.querySelector("richgriditem");
320 // Get the first bookmark item label to make sure it will show up in 'your results'
321 let label = bookmarkItem.getAttribute("label");
323 EventUtils.sendString(label, window);
325 let opened = yield waitForCondition(() => gEdit.popup.popupOpen);
326 yield waitForCondition(() => gEdit.popup._results.itemCount > 0);
328 ok(!gEdit.popup.hasAttribute("nomatch"), "'Popup doesnt have nomatch attribute when there are results");
329 ok(gEdit.popup._resultsContainer.getBoundingClientRect().width, "'Your results' are visible");
330 ok(gEdit.popup._results.itemCount > 0, "'Your results' are populated");
332 // Append a string to make sure it doesn't match anything in 'your results'
333 EventUtils.sendString("zzzzzzzzzzzzzzzzzz", window);
335 yield waitForCondition(() => gEdit.popup.hasAttribute("nomatch"));
337 is(gEdit.popup._resultsContainer.getBoundingClientRect().width, 0, "'Your results' are hidden");
338 ok(gEdit.popup._results.itemCount === 0, "'Your results' are empty");
340 EventUtils.synthesizeKey("VK_DOWN", {}, window);
341 is(gEdit.popup._searches.selectedIndex, 0, "key select search: first search selected");
343 EventUtils.synthesizeKey("VK_TAB", {}, window);
344 is(gEdit.popup._searches.selectedIndex, 1, "tab key: second search selected");
346 EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, window);
347 is(gEdit.popup._searches.selectedIndex, 0, "shift-tab: first search selected");
348 }
349 });
351 gTests.push({
352 desc: "Bug 891667 - Use up arrow too",
353 tearDown: tearDown,
354 run: function testBug891667() {
355 yield addTab("about:start");
356 yield showNavBar();
358 sendElementTap(window, gEdit);
360 let bookmarkItem = Browser.selectedBrowser.contentWindow.BookmarksStartView._grid.querySelector("richgriditem");
361 // Get the first bookmark item label to make sure it will show up in 'your results'
362 let label = bookmarkItem.getAttribute("label");
364 EventUtils.sendString(label, window);
366 yield waitForCondition(() => gEdit.popup.popupOpen);
367 yield waitForCondition(() => gEdit.popup._results.itemCount > 0);
369 ok(gEdit.popup._results.itemCount > 0, "'Your results' populated");
371 EventUtils.synthesizeKey("VK_UP", {}, window);
372 is(gEdit.popup._results.selectedIndex, 0, "Pressing arrow up selects first item.");
374 EventUtils.synthesizeKey("VK_BACK_SPACE", {}, window);
375 yield waitForEvent(document.getElementById("urlbar-edit"), "input");
376 is(gEdit.popup._results.selectedIndex, -1, "backspace: autocomplete de-selected");
377 }
378 });