michael@0: // Instead of loading ChromeUtils.js into the test scope in browser-test.js for all tests, michael@0: // we only need ChromeUtils.js for a few files which is why we are using loadSubScript. michael@0: var ChromeUtils = {}; michael@0: this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]. michael@0: getService(Ci.mozIJSSubScriptLoader); michael@0: this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", ChromeUtils); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", michael@0: "resource://gre/modules/FormHistory.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "Promise", michael@0: "resource://gre/modules/Promise.jsm"); michael@0: michael@0: function expectedURL(aSearchTerms) { michael@0: const ENGINE_HTML_BASE = "http://mochi.test:8888/browser/browser/components/search/test/test.html"; michael@0: var textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"]. michael@0: getService(Ci.nsITextToSubURI); michael@0: var searchArg = textToSubURI.ConvertAndEscape("utf-8", aSearchTerms); michael@0: return ENGINE_HTML_BASE + "?test=" + searchArg; michael@0: } michael@0: michael@0: function simulateClick(aEvent, aTarget) { michael@0: var event = document.createEvent("MouseEvent"); michael@0: var ctrlKeyArg = aEvent.ctrlKey || false; michael@0: var altKeyArg = aEvent.altKey || false; michael@0: var shiftKeyArg = aEvent.shiftKey || false; michael@0: var metaKeyArg = aEvent.metaKey || false; michael@0: var buttonArg = aEvent.button || 0; michael@0: event.initMouseEvent("click", true, true, window, michael@0: 0, 0, 0, 0, 0, michael@0: ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, michael@0: buttonArg, null); michael@0: aTarget.dispatchEvent(event); michael@0: } michael@0: michael@0: // modified from toolkit/components/satchel/test/test_form_autocomplete.html michael@0: function checkMenuEntries(expectedValues) { michael@0: var actualValues = getMenuEntries(); michael@0: is(actualValues.length, expectedValues.length, "Checking length of expected menu"); michael@0: for (var i = 0; i < expectedValues.length; i++) michael@0: is(actualValues[i], expectedValues[i], "Checking menu entry #" + i); michael@0: } michael@0: michael@0: function getMenuEntries() { michael@0: var entries = []; michael@0: var autocompleteMenu = searchBar.textbox.popup; michael@0: // Could perhaps pull values directly from the controller, but it seems michael@0: // more reliable to test the values that are actually in the tree? michael@0: var column = autocompleteMenu.tree.columns[0]; michael@0: var numRows = autocompleteMenu.tree.view.rowCount; michael@0: for (var i = 0; i < numRows; i++) { michael@0: entries.push(autocompleteMenu.tree.view.getValueAt(i, column)); michael@0: } michael@0: return entries; michael@0: } michael@0: michael@0: function* countEntries(name, value) { michael@0: let deferred = Promise.defer(); michael@0: let count = 0; michael@0: let obj = name && value ? {fieldname: name, value: value} : {}; michael@0: FormHistory.count(obj, michael@0: { handleResult: function(result) { count = result; }, michael@0: handleError: function(error) { throw error; }, michael@0: handleCompletion: function(reason) { michael@0: if (!reason) { michael@0: deferred.resolve(count); michael@0: } michael@0: } michael@0: }); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: var searchBar; michael@0: var searchButton; michael@0: var searchEntries = ["test", "More Text", "Some Text"]; michael@0: function* promiseSetEngine() { michael@0: let deferred = Promise.defer(); michael@0: var ss = Services.search; michael@0: michael@0: function observer(aSub, aTopic, aData) { michael@0: switch (aData) { michael@0: case "engine-added": michael@0: var engine = ss.getEngineByName("Bug 426329"); michael@0: ok(engine, "Engine was added."); michael@0: ss.currentEngine = engine; michael@0: break; michael@0: case "engine-current": michael@0: ok(ss.currentEngine.name == "Bug 426329", "currentEngine set"); michael@0: searchBar = BrowserSearch.searchBar; michael@0: searchButton = document.getAnonymousElementByAttribute(searchBar, michael@0: "anonid", "search-go-button"); michael@0: ok(searchButton, "got search-go-button"); michael@0: searchBar.value = "test"; michael@0: michael@0: Services.obs.removeObserver(observer, "browser-search-engine-modified"); michael@0: deferred.resolve(); michael@0: break; michael@0: } michael@0: }; michael@0: michael@0: Services.obs.addObserver(observer, "browser-search-engine-modified", false); michael@0: ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/426329.xml", michael@0: Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00", michael@0: false); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function* promiseRemoveEngine() { michael@0: let deferred = Promise.defer(); michael@0: var ss = Services.search; michael@0: michael@0: function observer(aSub, aTopic, aData) { michael@0: if (aData == "engine-removed") { michael@0: Services.obs.removeObserver(observer, "browser-search-engine-modified"); michael@0: deferred.resolve(); michael@0: } michael@0: }; michael@0: michael@0: Services.obs.addObserver(observer, "browser-search-engine-modified", false); michael@0: var engine = ss.getEngineByName("Bug 426329"); michael@0: ss.removeEngine(engine); michael@0: michael@0: return deferred.promise; michael@0: } michael@0: michael@0: michael@0: var preSelectedBrowser; michael@0: var preTabNo; michael@0: function* prepareTest() { michael@0: preSelectedBrowser = gBrowser.selectedBrowser; michael@0: preTabNo = gBrowser.tabs.length; michael@0: searchBar = BrowserSearch.searchBar; michael@0: michael@0: let windowFocused = Promise.defer(); michael@0: SimpleTest.waitForFocus(windowFocused.resolve, window); michael@0: yield windowFocused.promise; michael@0: michael@0: let deferred = Promise.defer(); michael@0: if (document.activeElement != searchBar) { michael@0: searchBar.addEventListener("focus", function onFocus() { michael@0: searchBar.removeEventListener("focus", onFocus); michael@0: deferred.resolve(); michael@0: }); michael@0: searchBar.focus(); michael@0: } else { michael@0: deferred.resolve(); michael@0: } michael@0: return deferred.promise; michael@0: } michael@0: michael@0: add_task(function testSetupEngine() { michael@0: yield promiseSetEngine(); michael@0: }); michael@0: michael@0: add_task(function testReturn() { michael@0: yield prepareTest(); michael@0: EventUtils.synthesizeKey("VK_RETURN", {}); michael@0: let event = yield promiseOnLoad(); michael@0: michael@0: is(gBrowser.tabs.length, preTabNo, "Return key did not open new tab"); michael@0: is(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "Return key loaded results in current tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testReturn opened correct search page"); michael@0: }); michael@0: michael@0: add_task(function testAltReturn() { michael@0: yield prepareTest(); michael@0: EventUtils.synthesizeKey("VK_RETURN", { altKey: true }); michael@0: let event = yield promiseOnLoad(); michael@0: michael@0: is(gBrowser.tabs.length, preTabNo + 1, "Alt+Return key added new tab"); michael@0: isnot(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "Alt+Return key loaded results in new tab"); michael@0: is(event.originalTarget, gBrowser.contentDocument, michael@0: "Alt+Return key loaded results in foreground tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testAltReturn opened correct search page"); michael@0: }); michael@0: michael@0: //Shift key has no effect for now, so skip it michael@0: add_task(function testShiftAltReturn() { michael@0: return; michael@0: michael@0: yield prepareTest(); michael@0: EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true, altKey: true }); michael@0: let event = yield promiseOnLoad(); michael@0: michael@0: is(gBrowser.tabs.length, preTabNo + 1, "Shift+Alt+Return key added new tab"); michael@0: isnot(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "Shift+Alt+Return key loaded results in new tab"); michael@0: isnot(event.originalTarget, gBrowser.contentDocument, michael@0: "Shift+Alt+Return key loaded results in background tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testShiftAltReturn opened correct search page"); michael@0: }); michael@0: michael@0: add_task(function testLeftClick() { michael@0: yield prepareTest(); michael@0: simulateClick({ button: 0 }, searchButton); michael@0: let event = yield promiseOnLoad(); michael@0: is(gBrowser.tabs.length, preTabNo, "LeftClick did not open new tab"); michael@0: is(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "LeftClick loaded results in current tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testLeftClick opened correct search page"); michael@0: }); michael@0: michael@0: add_task(function testMiddleClick() { michael@0: yield prepareTest(); michael@0: simulateClick({ button: 1 }, searchButton); michael@0: let event = yield promiseOnLoad(); michael@0: is(gBrowser.tabs.length, preTabNo + 1, "MiddleClick added new tab"); michael@0: isnot(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "MiddleClick loaded results in new tab"); michael@0: is(event.originalTarget, gBrowser.contentDocument, michael@0: "MiddleClick loaded results in foreground tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testMiddleClick opened correct search page"); michael@0: }); michael@0: michael@0: add_task(function testShiftMiddleClick() { michael@0: yield prepareTest(); michael@0: simulateClick({ button: 1, shiftKey: true }, searchButton); michael@0: let event = yield promiseOnLoad(); michael@0: is(gBrowser.tabs.length, preTabNo + 1, "Shift+MiddleClick added new tab"); michael@0: isnot(event.originalTarget, preSelectedBrowser.contentDocument, michael@0: "Shift+MiddleClick loaded results in new tab"); michael@0: isnot(event.originalTarget, gBrowser.contentDocument, michael@0: "Shift+MiddleClick loaded results in background tab"); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testShiftMiddleClick opened correct search page"); michael@0: }); michael@0: michael@0: add_task(function testDropText() { michael@0: yield prepareTest(); michael@0: let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); michael@0: // drop on the search button so that we don't need to worry about the michael@0: // default handlers for textboxes. michael@0: ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/plain", data: "Some Text" } ]], "copy", window); michael@0: yield promisePreventPopup; michael@0: let event = yield promiseOnLoad(); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropText opened correct search page"); michael@0: is(searchBar.value, "Some Text", "drop text/plain on searchbar"); michael@0: }); michael@0: michael@0: add_task(function testDropInternalText() { michael@0: yield prepareTest(); michael@0: let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); michael@0: ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/x-moz-text-internal", data: "More Text" } ]], "copy", window); michael@0: yield promisePreventPopup; michael@0: let event = yield promiseOnLoad(); michael@0: is(event.originalTarget.URL, expectedURL(searchBar.value), "testDropInternalText opened correct search page"); michael@0: is(searchBar.value, "More Text", "drop text/x-moz-text-internal on searchbar"); michael@0: michael@0: // testDropLink implicitly depended on testDropInternalText, so these two tests michael@0: // were merged so that if testDropInternalText failed it wouldn't cause testDropLink michael@0: // to fail unexplainably. michael@0: yield prepareTest(); michael@0: let promisePreventPopup = promiseEvent(searchBar, "popupshowing", true); michael@0: ChromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/uri-list", data: "http://www.mozilla.org" } ]], "copy", window); michael@0: yield promisePreventPopup; michael@0: is(searchBar.value, "More Text", "drop text/uri-list on searchbar shouldn't change anything"); michael@0: }); michael@0: michael@0: add_task(function testRightClick() { michael@0: preTabNo = gBrowser.tabs.length; michael@0: content.location.href = "about:blank"; michael@0: simulateClick({ button: 2 }, searchButton); michael@0: let deferred = Promise.defer(); michael@0: setTimeout(function() { michael@0: is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab"); michael@0: is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing"); michael@0: deferred.resolve(); michael@0: }, 5000); michael@0: yield deferred.promise; michael@0: }); michael@0: michael@0: add_task(function testSearchHistory() { michael@0: var textbox = searchBar._textbox; michael@0: for (var i = 0; i < searchEntries.length; i++) { michael@0: let count = yield countEntries(textbox.getAttribute("autocompletesearchparam"), searchEntries[i]); michael@0: ok(count > 0, "form history entry '" + searchEntries[i] + "' should exist"); michael@0: } michael@0: }); michael@0: michael@0: add_task(function testAutocomplete() { michael@0: var popup = searchBar.textbox.popup; michael@0: let popupShownPromise = promiseEvent(popup, "popupshown"); michael@0: searchBar.textbox.showHistoryPopup(); michael@0: yield popupShownPromise; michael@0: checkMenuEntries(searchEntries); michael@0: }); michael@0: michael@0: add_task(function testClearHistory() { michael@0: let controller = searchBar.textbox.controllers.getControllerForCommand("cmd_clearhistory") michael@0: ok(controller.isCommandEnabled("cmd_clearhistory"), "Clear history command enabled"); michael@0: controller.doCommand("cmd_clearhistory"); michael@0: let count = yield countEntries(); michael@0: ok(count == 0, "History cleared"); michael@0: }); michael@0: michael@0: add_task(function asyncCleanup() { michael@0: searchBar.value = ""; michael@0: while (gBrowser.tabs.length != 1) { michael@0: gBrowser.removeTab(gBrowser.tabs[0], {animate: false}); michael@0: } michael@0: content.location.href = "about:blank"; michael@0: yield promiseRemoveEngine(); michael@0: }); michael@0: