michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: /* michael@0: * Test Google search plugin URLs michael@0: */ michael@0: michael@0: "use strict"; michael@0: michael@0: const BROWSER_SEARCH_PREF = "browser.search."; michael@0: michael@0: const MOZ_PARAM_LOCALE = /\{moz:locale\}/g; michael@0: const MOZ_PARAM_DIST_ID = /\{moz:distributionID\}/g; michael@0: const MOZ_PARAM_OFFICIAL = /\{moz:official\}/g; michael@0: michael@0: let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); michael@0: // Custom search parameters michael@0: const MOZ_OFFICIAL = runtime.isOfficialBranding ? "official" : "unofficial"; michael@0: michael@0: var google_client; michael@0: switch (runtime.defaultUpdateChannel) { michael@0: case "beta": michael@0: google_client = "firefox-beta"; michael@0: break; michael@0: case "aurora": michael@0: google_client = "firefox-aurora"; michael@0: break; michael@0: case "nightly": michael@0: google_client = "firefox-nightly"; michael@0: break; michael@0: default: michael@0: google_client = "firefox-a"; michael@0: break; michael@0: } michael@0: michael@0: const GOOGLE_CLIENT = google_client; michael@0: const MOZ_DISTRIBUTION_ID = runtime.distributionID; michael@0: michael@0: function test() { michael@0: let engine = Services.search.getEngineByName("Google"); michael@0: ok(engine, "Google is installed"); michael@0: michael@0: is(Services.search.defaultEngine, engine, "Check that Google is the default search engine"); michael@0: michael@0: let distributionID; michael@0: try { michael@0: distributionID = Services.prefs.getCharPref(BROWSER_SEARCH_PREF + "distributionID"); michael@0: } catch (ex) { michael@0: distributionID = MOZ_DISTRIBUTION_ID; michael@0: } michael@0: michael@0: let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&aq=t&rls={moz:distributionID}:{moz:locale}:{moz:official}&client=" + GOOGLE_CLIENT; michael@0: base = base.replace(MOZ_PARAM_LOCALE, getLocale()); michael@0: base = base.replace(MOZ_PARAM_DIST_ID, distributionID); michael@0: base = base.replace(MOZ_PARAM_OFFICIAL, MOZ_OFFICIAL); michael@0: michael@0: let url; michael@0: michael@0: // Test search URLs (including purposes). michael@0: url = engine.getSubmission("foo").uri.spec; michael@0: is(url, base, "Check search URL for 'foo'"); michael@0: michael@0: waitForExplicitFinish(); michael@0: michael@0: var gCurrTest; michael@0: var gTests = [ michael@0: { michael@0: name: "context menu search", michael@0: searchURL: base + "&channel=rcs", michael@0: run: function () { michael@0: // Simulate a contextmenu search michael@0: // FIXME: This is a bit "low-level"... michael@0: BrowserSearch.loadSearch("foo", false, "contextmenu"); michael@0: } michael@0: }, michael@0: { michael@0: name: "keyword search", michael@0: searchURL: base + "&channel=fflb", michael@0: run: function () { michael@0: gURLBar.value = "? foo"; michael@0: gURLBar.focus(); michael@0: EventUtils.synthesizeKey("VK_RETURN", {}); michael@0: } michael@0: }, michael@0: { michael@0: name: "search bar search", michael@0: searchURL: base + "&channel=sb", michael@0: run: function () { michael@0: let sb = BrowserSearch.searchBar; michael@0: sb.focus(); michael@0: sb.value = "foo"; michael@0: registerCleanupFunction(function () { michael@0: sb.value = ""; michael@0: }); michael@0: EventUtils.synthesizeKey("VK_RETURN", {}); michael@0: } michael@0: }, michael@0: { michael@0: name: "new tab search", michael@0: searchURL: base + "&channel=nts", michael@0: run: function () { michael@0: function doSearch(doc) { michael@0: // Re-add the listener, and perform a search michael@0: gBrowser.addProgressListener(listener); michael@0: doc.getElementById("newtab-search-text").value = "foo"; michael@0: doc.getElementById("newtab-search-submit").click(); michael@0: } michael@0: michael@0: // load about:newtab, but remove the listener first so it doesn't michael@0: // get in the way michael@0: gBrowser.removeProgressListener(listener); michael@0: gBrowser.loadURI("about:newtab"); michael@0: info("Waiting for about:newtab load"); michael@0: tab.linkedBrowser.addEventListener("load", function load(event) { michael@0: if (event.originalTarget != tab.linkedBrowser.contentDocument || michael@0: event.target.location.href == "about:blank") { michael@0: info("skipping spurious load event"); michael@0: return; michael@0: } michael@0: tab.linkedBrowser.removeEventListener("load", load, true); michael@0: michael@0: // Observe page setup michael@0: let win = gBrowser.contentWindow; michael@0: if (win.gSearch.currentEngineName == michael@0: Services.search.currentEngine.name) { michael@0: doSearch(win.document); michael@0: } michael@0: else { michael@0: info("Waiting for newtab search init"); michael@0: win.addEventListener("ContentSearchService", function done(event) { michael@0: info("Got newtab search event " + event.detail.type); michael@0: if (event.detail.type == "State") { michael@0: win.removeEventListener("ContentSearchService", done); michael@0: // Let gSearch respond to the event before continuing. michael@0: executeSoon(() => doSearch(win.document)); michael@0: } michael@0: }); michael@0: } michael@0: }, true); michael@0: } michael@0: }, michael@0: { michael@0: name: "home page search", michael@0: searchURL: base + "&channel=np&source=hp", michael@0: run: function () { michael@0: // Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB) michael@0: ignoreAllUncaughtExceptions(true); michael@0: michael@0: // load about:home, but remove the listener first so it doesn't michael@0: // get in the way michael@0: gBrowser.removeProgressListener(listener); michael@0: gBrowser.loadURI("about:home"); michael@0: info("Waiting for about:home load"); michael@0: tab.linkedBrowser.addEventListener("load", function load(event) { michael@0: if (event.originalTarget != tab.linkedBrowser.contentDocument || michael@0: event.target.location.href == "about:blank") { michael@0: info("skipping spurious load event"); michael@0: return; michael@0: } michael@0: tab.linkedBrowser.removeEventListener("load", load, true); michael@0: michael@0: // Observe page setup michael@0: let doc = gBrowser.contentDocument; michael@0: let mutationObserver = new MutationObserver(function (mutations) { michael@0: for (let mutation of mutations) { michael@0: if (mutation.attributeName == "searchEngineName") { michael@0: // Re-add the listener, and perform a search michael@0: gBrowser.addProgressListener(listener); michael@0: doc.getElementById("searchText").value = "foo"; michael@0: doc.getElementById("searchSubmit").click(); michael@0: } michael@0: } michael@0: }); michael@0: mutationObserver.observe(doc.documentElement, { attributes: true }); michael@0: }, true); michael@0: } michael@0: } michael@0: ]; michael@0: michael@0: function nextTest() { michael@0: // Make sure we listen again for uncaught exceptions in the next test or cleanup. michael@0: ignoreAllUncaughtExceptions(false); michael@0: michael@0: if (gTests.length) { michael@0: gCurrTest = gTests.shift(); michael@0: info("Running : " + gCurrTest.name); michael@0: executeSoon(gCurrTest.run); michael@0: } else { michael@0: finish(); michael@0: } michael@0: } michael@0: michael@0: let tab = gBrowser.selectedTab = gBrowser.addTab(); michael@0: michael@0: let listener = { michael@0: onStateChange: function onStateChange(webProgress, req, flags, status) { michael@0: info("onStateChange"); michael@0: // Only care about top-level document starts michael@0: let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT | michael@0: Ci.nsIWebProgressListener.STATE_START; michael@0: if (!(flags & docStart) || !webProgress.isTopLevel) michael@0: return; michael@0: michael@0: info("received document start"); michael@0: michael@0: ok(req instanceof Ci.nsIChannel, "req is a channel"); michael@0: is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded"); michael@0: info("Actual URI: " + req.URI.spec); michael@0: michael@0: req.cancel(Components.results.NS_ERROR_FAILURE); michael@0: michael@0: executeSoon(nextTest); michael@0: } michael@0: } michael@0: michael@0: registerCleanupFunction(function () { michael@0: gBrowser.removeProgressListener(listener); michael@0: gBrowser.removeTab(tab); michael@0: }); michael@0: michael@0: tab.linkedBrowser.addEventListener("load", function load() { michael@0: tab.linkedBrowser.removeEventListener("load", load, true); michael@0: gBrowser.addProgressListener(listener); michael@0: nextTest(); michael@0: }, true); michael@0: }