|
1 // Instead of loading ChromeUtils.js into the test scope in browser-test.js for all tests, |
|
2 // we only need ChromeUtils.js for a few files which is why we are using loadSubScript. |
|
3 var ChromeUtils = {}; |
|
4 this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. |
|
5 getService(Ci.mozIJSSubScriptLoader); |
|
6 this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); |
|
7 |
|
8 XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", |
|
9 "resource://gre/modules/FormHistory.jsm"); |
|
10 XPCOMUtils.defineLazyModuleGetter(this, "Promise", |
|
11 "resource://gre/modules/Promise.jsm"); |
|
12 |
|
13 function expectedURL(aSearchTerms) { |
|
14 const ENGINE_HTML_BASE = "http://mochi.test:8888/browser/browser/components/search/test/test.html"; |
|
15 var textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"]. |
|
16 getService(Ci.nsITextToSubURI); |
|
17 var searchArg = textToSubURI.ConvertAndEscape("utf-8", aSearchTerms); |
|
18 return ENGINE_HTML_BASE + "?test=" + searchArg; |
|
19 } |
|
20 |
|
21 function simulateClick(aEvent, aTarget) { |
|
22 var event = document.createEvent("MouseEvent"); |
|
23 var ctrlKeyArg = aEvent.ctrlKey || false; |
|
24 var altKeyArg = aEvent.altKey || false; |
|
25 var shiftKeyArg = aEvent.shiftKey || false; |
|
26 var metaKeyArg = aEvent.metaKey || false; |
|
27 var buttonArg = aEvent.button || 0; |
|
28 event.initMouseEvent("click", true, true, window, |
|
29 0, 0, 0, 0, 0, |
|
30 ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, |
|
31 buttonArg, null); |
|
32 aTarget.dispatchEvent(event); |
|
33 } |
|
34 |
|
35 // modified from toolkit/components/satchel/test/test_form_autocomplete.html |
|
36 function checkMenuEntries(expectedValues) { |
|
37 var actualValues = getMenuEntries(); |
|
38 is(actualValues.length, expectedValues.length, "Checking length of expected menu"); |
|
39 for (var i = 0; i < expectedValues.length; i++) |
|
40 is(actualValues[i], expectedValues[i], "Checking menu entry #" + i); |
|
41 } |
|
42 |
|
43 function getMenuEntries() { |
|
44 var entries = []; |
|
45 var autocompleteMenu = searchBar.textbox.popup; |
|
46 // Could perhaps pull values directly from the controller, but it seems |
|
47 // more reliable to test the values that are actually in the tree? |
|
48 var column = autocompleteMenu.tree.columns[0]; |
|
49 var numRows = autocompleteMenu.tree.view.rowCount; |
|
50 for (var i = 0; i < numRows; i++) { |
|
51 entries.push(autocompleteMenu.tree.view.getValueAt(i, column)); |
|
52 } |
|
53 return entries; |
|
54 } |
|
55 |
|
56 function* countEntries(name, value) { |
|
57 let deferred = Promise.defer(); |
|
58 let count = 0; |
|
59 let obj = name && value ? {fieldname: name, value: value} : {}; |
|
60 FormHistory.count(obj, |
|
61 { handleResult: function(result) { count = result; }, |
|
62 handleError: function(error) { throw error; }, |
|
63 handleCompletion: function(reason) { |
|
64 if (!reason) { |
|
65 deferred.resolve(count); |
|
66 } |
|
67 } |
|
68 }); |
|
69 return deferred.promise; |
|
70 } |
|
71 |
|
72 var searchBar; |
|
73 var searchButton; |
|
74 var searchEntries = ["test", "More Text", "Some Text"]; |
|
75 function* promiseSetEngine() { |
|
76 let deferred = Promise.defer(); |
|
77 var ss = Services.search; |
|
78 |
|
79 function observer(aSub, aTopic, aData) { |
|
80 switch (aData) { |
|
81 case "engine-added": |
|
82 var engine = ss.getEngineByName("Bug 426329"); |
|
83 ok(engine, "Engine was added."); |
|
84 ss.currentEngine = engine; |
|
85 break; |
|
86 case "engine-current": |
|
87 ok(ss.currentEngine.name == "Bug 426329", "currentEngine set"); |
|
88 searchBar = BrowserSearch.searchBar; |
|
89 searchButton = document.getAnonymousElementByAttribute(searchBar, |
|
90 "anonid", "search-go-button"); |
|
91 ok(searchButton, "got search-go-button"); |
|
92 searchBar.value = "test"; |
|
93 |
|
94 Services.obs.removeObserver(observer, "browser-search-engine-modified"); |
|
95 deferred.resolve(); |
|
96 break; |
|
97 } |
|
98 }; |
|
99 |
|
100 Services.obs.addObserver(observer, "browser-search-engine-modified", false); |
|
101 ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/426329.xml", |
|
102 Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00", |
|
103 false); |
|
104 |
|
105 return deferred.promise; |
|
106 } |
|
107 |
|
108 function* promiseRemoveEngine() { |
|
109 let deferred = Promise.defer(); |
|
110 var ss = Services.search; |
|
111 |
|
112 function observer(aSub, aTopic, aData) { |
|
113 if (aData == "engine-removed") { |
|
114 Services.obs.removeObserver(observer, "browser-search-engine-modified"); |
|
115 deferred.resolve(); |
|
116 } |
|
117 }; |
|
118 |
|
119 Services.obs.addObserver(observer, "browser-search-engine-modified", false); |
|
120 var engine = ss.getEngineByName("Bug 426329"); |
|
121 ss.removeEngine(engine); |
|
122 |
|
123 return deferred.promise; |
|
124 } |
|
125 |
|
126 |
|
127 var preSelectedBrowser; |
|
128 var preTabNo; |
|
129 function* prepareTest() { |
|
130 preSelectedBrowser = gBrowser.selectedBrowser; |
|
131 preTabNo = gBrowser.tabs.length; |
|
132 searchBar = BrowserSearch.searchBar; |
|
133 |
|
134 let windowFocused = Promise.defer(); |
|
135 SimpleTest.waitForFocus(windowFocused.resolve, window); |
|
136 yield windowFocused.promise; |
|
137 |
|
138 let deferred = Promise.defer(); |
|
139 if (document.activeElement != searchBar) { |
|
140 searchBar.addEventListener("focus", function onFocus() { |
|
141 searchBar.removeEventListener("focus", onFocus); |
|
142 deferred.resolve(); |
|
143 }); |
|
144 searchBar.focus(); |
|
145 } else { |
|
146 deferred.resolve(); |
|
147 } |
|
148 return deferred.promise; |
|
149 } |
|
150 |
|
151 add_task(function testSetupEngine() { |
|
152 yield promiseSetEngine(); |
|
153 }); |
|
154 |
|
155 add_task(function testReturn() { |
|
156 yield prepareTest(); |
|
157 EventUtils.synthesizeKey("VK_RETURN", {}); |
|
158 let event = yield promiseOnLoad(); |
|
159 |
|
160 is(gBrowser.tabs.length, preTabNo, "Return key did not open new tab"); |
|
161 is(event.originalTarget, preSelectedBrowser.contentDocument, |
|
162 "Return key loaded results in current tab"); |
|
163 is(event.originalTarget.URL, expectedURL(searchBar.value), "testReturn opened correct search page"); |
|
164 }); |
|
165 |
|
166 add_task(function testAltReturn() { |
|
167 yield prepareTest(); |
|
168 EventUtils.synthesizeKey("VK_RETURN", { altKey: true }); |
|
169 let event = yield promiseOnLoad(); |
|
170 |
|
171 is(gBrowser.tabs.length, preTabNo + 1, "Alt+Return key added new tab"); |
|
172 isnot(event.originalTarget, preSelectedBrowser.contentDocument, |
|
173 "Alt+Return key loaded results in new tab"); |
|
174 is(event.originalTarget, gBrowser.contentDocument, |
|
175 "Alt+Return key loaded results in foreground tab"); |
|
176 is(event.originalTarget.URL, expectedURL(searchBar.value), "testAltReturn opened correct search page"); |
|
177 }); |
|
178 |
|
179 //Shift key has no effect for now, so skip it |
|
180 add_task(function testShiftAltReturn() { |
|
181 return; |
|
182 |
|
183 yield prepareTest(); |
|
184 EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true, altKey: true }); |
|
185 let event = yield promiseOnLoad(); |
|
186 |
|
187 is(gBrowser.tabs.length, preTabNo + 1, "Shift+Alt+Return key added new tab"); |
|
188 isnot(event.originalTarget, preSelectedBrowser.contentDocument, |
|
189 "Shift+Alt+Return key loaded results in new tab"); |
|
190 isnot(event.originalTarget, gBrowser.contentDocument, |
|
191 "Shift+Alt+Return key loaded results in background tab"); |
|
192 is(event.originalTarget.URL, expectedURL(searchBar.value), "testShiftAltReturn opened correct search page"); |
|
193 }); |
|
194 |
|
195 add_task(function testLeftClick() { |
|
196 yield prepareTest(); |
|
197 simulateClick({ button: 0 }, searchButton); |
|
198 let event = yield promiseOnLoad(); |
|
199 is(gBrowser.tabs.length, preTabNo, "LeftClick did not open new tab"); |
|
200 is(event.originalTarget, preSelectedBrowser.contentDocument, |
|
201 "LeftClick loaded results in current tab"); |
|
202 is(event.originalTarget.URL, expectedURL(searchBar.value), "testLeftClick opened correct search page"); |
|
203 }); |
|
204 |
|
205 add_task(function testMiddleClick() { |
|
206 yield prepareTest(); |
|
207 simulateClick({ button: 1 }, searchButton); |
|
208 let event = yield promiseOnLoad(); |
|
209 is(gBrowser.tabs.length, preTabNo + 1, "MiddleClick added new tab"); |
|
210 isnot(event.originalTarget, preSelectedBrowser.contentDocument, |
|
211 "MiddleClick loaded results in new tab"); |
|
212 is(event.originalTarget, gBrowser.contentDocument, |
|
213 "MiddleClick loaded results in foreground tab"); |
|
214 is(event.originalTarget.URL, expectedURL(searchBar.value), "testMiddleClick opened correct search page"); |
|
215 }); |
|
216 |
|
217 add_task(function testShiftMiddleClick() { |
|
218 yield prepareTest(); |
|
219 simulateClick({ button: 1, shiftKey: true }, searchButton); |
|
220 let event = yield promiseOnLoad(); |
|
221 is(gBrowser.tabs.length, preTabNo + 1, "Shift+MiddleClick added new tab"); |
|
222 isnot(event.originalTarget, preSelectedBrowser.contentDocument, |
|
223 "Shift+MiddleClick loaded results in new tab"); |
|
224 isnot(event.originalTarget, gBrowser.contentDocument, |
|
225 "Shift+MiddleClick loaded results in background tab"); |
|
226 is(event.originalTarget.URL, expectedURL(searchBar.value), "testShiftMiddleClick opened correct search page"); |
|
227 }); |
|
228 |
|
229 add_task(function testDropText() { |
|
230 yield prepareTest(); |
|
231 let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); |
|
232 // drop on the search button so that we don't need to worry about the |
|
233 // default handlers for textboxes. |
|
234 ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/plain", data: "Some Text" } ]], "copy", window); |
|
235 yield promisePreventPopup; |
|
236 let event = yield promiseOnLoad(); |
|
237 is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropText opened correct search page"); |
|
238 is(searchBar.value, "Some Text", "drop text/plain on searchbar"); |
|
239 }); |
|
240 |
|
241 add_task(function testDropInternalText() { |
|
242 yield prepareTest(); |
|
243 let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); |
|
244 ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/x-moz-text-internal", data: "More Text" } ]], "copy", window); |
|
245 yield promisePreventPopup; |
|
246 let event = yield promiseOnLoad(); |
|
247 is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropInternalText opened correct search page"); |
|
248 is(searchBar.value, "More Text", "drop text/x-moz-text-internal on searchbar"); |
|
249 |
|
250 // testDropLink implicitly depended on testDropInternalText, so these two tests |
|
251 // were merged so that if testDropInternalText failed it wouldn't cause testDropLink |
|
252 // to fail unexplainably. |
|
253 yield prepareTest(); |
|
254 let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); |
|
255 ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/uri-list", data: "http://www.mozilla.org" } ]], "copy", window); |
|
256 yield promisePreventPopup; |
|
257 is(searchBar.value, "More Text", "drop text/uri-list on searchbar shouldn't change anything"); |
|
258 }); |
|
259 |
|
260 add_task(function testRightClick() { |
|
261 preTabNo = gBrowser.tabs.length; |
|
262 content.location.href = "about:blank"; |
|
263 simulateClick({ button: 2 }, searchButton); |
|
264 let deferred = Promise.defer(); |
|
265 setTimeout(function() { |
|
266 is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab"); |
|
267 is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing"); |
|
268 deferred.resolve(); |
|
269 }, 5000); |
|
270 yield deferred.promise; |
|
271 }); |
|
272 |
|
273 add_task(function testSearchHistory() { |
|
274 var textbox = searchBar._textbox; |
|
275 for (var i = 0; i < searchEntries.length; i++) { |
|
276 let count = yield countEntries(textbox.getAttribute("autocompletesearchparam"), searchEntries[i]); |
|
277 ok(count > 0, "form history entry '" + searchEntries[i] + "' should exist"); |
|
278 } |
|
279 }); |
|
280 |
|
281 add_task(function testAutocomplete() { |
|
282 var popup = searchBar.textbox.popup; |
|
283 let popupShownPromise = promiseEvent(popup, "popupshown"); |
|
284 searchBar.textbox.showHistoryPopup(); |
|
285 yield popupShownPromise; |
|
286 checkMenuEntries(searchEntries); |
|
287 }); |
|
288 |
|
289 add_task(function testClearHistory() { |
|
290 let controller = searchBar.textbox.controllers.getControllerForCommand("cmd_clearhistory") |
|
291 ok(controller.isCommandEnabled("cmd_clearhistory"), "Clear history command enabled"); |
|
292 controller.doCommand("cmd_clearhistory"); |
|
293 let count = yield countEntries(); |
|
294 ok(count == 0, "History cleared"); |
|
295 }); |
|
296 |
|
297 add_task(function asyncCleanup() { |
|
298 searchBar.value = ""; |
|
299 while (gBrowser.tabs.length != 1) { |
|
300 gBrowser.removeTab(gBrowser.tabs[0], {animate: false}); |
|
301 } |
|
302 content.location.href = "about:blank"; |
|
303 yield promiseRemoveEngine(); |
|
304 }); |
|
305 |