diff --git a/browser/base/content/test/urlbar/browser.ini b/browser/base/content/test/urlbar/browser.ini
index 1a055c20aece..3820a61bce0b 100644
--- a/browser/base/content/test/urlbar/browser.ini
+++ b/browser/base/content/test/urlbar/browser.ini
@@ -111,6 +111,10 @@ support-files =
file_urlbar_edit_dos.html
[browser_urlbar_searchsettings.js]
[browser_urlbar_search_speculative_connect.js]
+[browser_urlbar_search_speculative_connect_engine.js]
+support-files =
+ searchSuggestionEngine2.xml
+ searchSuggestionEngine.sjs
[browser_urlbar_stop_pending.js]
support-files =
slow-page.sjs
diff --git a/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect.js b/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect.js
index a50e243783b3..db22a493ff68 100644
--- a/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect.js
+++ b/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect.js
@@ -1,3 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
"use strict";
// This test ensures that we setup a speculative network
@@ -8,6 +12,8 @@ let gHttpServer = null;
let gScheme = "http";
let gHost = "localhost"; // 'localhost' by default.
let gPort = -1;
+let gPrivateWin = null;
+let gIsSpeculativeConnected = false;
add_task(async function setup() {
if (!gHttpServer) {
@@ -24,7 +30,9 @@ add_task(async function setup() {
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.autoFill", true],
- ["browser.urlbar.speculativeConnection.enabled", true],
+ // Turn off speculative connect to the search engine.
+ ["browser.search.suggest.enabled", false],
+ ["browser.urlbar.speculativeConnect.enabled", true],
// In mochitest this number is 0 by default but we have to turn it on.
["network.http.speculative-parallel-limit", 6],
// The http server is using IPv4, so it's better to disable IPv6 to avoid weird
@@ -38,45 +46,56 @@ add_task(async function setup() {
transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
}]);
+ gPrivateWin = await BrowserTestUtils.openNewBrowserWindow({private: true});
+ is(PrivateBrowsingUtils.isWindowPrivate(gPrivateWin), true, "A private window created.");
+
// Bug 764062 - we can't get port number from autocomplete result, so we have to mock
// this function to add it manually.
let oldSpeculativeConnect = gURLBar.popup.maybeSetupSpeculativeConnect.bind(gURLBar.popup);
- gURLBar.popup.maybeSetupSpeculativeConnect = (uriString) => {
+ let newSpeculativeConnect = (uriString) => {
+ gIsSpeculativeConnected = true;
info(`Original uri is ${uriString}`);
let newUriString = uriString.substr(0, uriString.length - 1) +
":" + gPort + "/";
info(`New uri is ${newUriString}`);
oldSpeculativeConnect(newUriString);
};
+ gURLBar.popup.maybeSetupSpeculativeConnect = newSpeculativeConnect;
+ gPrivateWin.gURLBar.popup.maybeSetupSpeculativeConnect = newSpeculativeConnect;
registerCleanupFunction(async function() {
- await PlacesTestUtils.clearHistory();
+ await PlacesUtils.history.clear();
gURLBar.popup.maybeSetupSpeculativeConnect = oldSpeculativeConnect;
+ gPrivateWin.gURLBar.popup.maybeSetupSpeculativeConnect = oldSpeculativeConnect;
gHttpServer.identity.remove(gScheme, gHost, gPort);
gHttpServer.stop(() => {
gHttpServer = null;
});
+ await BrowserTestUtils.closeWindow(gPrivateWin);
});
});
-add_task(async function autofill_tests() {
- const test = {
- search: gHost.substr(0, 2),
- autofilledValue: `${gHost}/`
- };
+const test = {
+ search: gHost.substr(0, 2),
+ autofilledValue: `${gHost}/`
+};
+add_task(async function autofill_tests() {
+ gIsSpeculativeConnected = false;
info(`Searching for '${test.search}'`);
await promiseAutocompleteResultPopup(test.search, window, true);
is(gURLBar.inputField.value, test.autofilledValue,
`Autofilled value is as expected for search '${test.search}'`);
-
- await BrowserTestUtils.waitForCondition(() => {
- if (gHttpServer) {
- is(gHttpServer.connectionNumber, 1,
- `${gHttpServer.connectionNumber} speculative connection has been setup.`)
- return gHttpServer.connectionNumber == 1;
- }
- return false;
- }, "Waiting for connection setup");
+ is(gIsSpeculativeConnected, true, "Speculative connection should be called");
+ await promiseSpeculativeConnection(gHttpServer);
});
+add_task(async function privateContext_test() {
+ info("In private context.");
+ gIsSpeculativeConnected = false;
+ info(`Searching for '${test.search}'`);
+ await promiseAutocompleteResultPopup(test.search, gPrivateWin, true);
+ is(gPrivateWin.gURLBar.inputField.value, test.autofilledValue,
+ `Autofilled value is as expected for search '${test.search}'`);
+ is(gIsSpeculativeConnected, false, "Speculative connection shouldn't be called");
+});
diff --git a/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect_engine.js b/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect_engine.js
new file mode 100644
index 000000000000..4f4439570e0d
--- /dev/null
+++ b/browser/base/content/test/urlbar/browser_urlbar_search_speculative_connect_engine.js
@@ -0,0 +1,66 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+// This test ensures that we setup a speculative network connection to
+// current search engine if the first result is 'searchengine'.
+
+let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
+let gHttpServer = null;
+let gScheme = "http";
+let gHost = "localhost"; // 'localhost' by default.
+let gPort = 20709; // the port number must be identical to what we said in searchSuggestionEngine2.xml
+const TEST_ENGINE_BASENAME = "searchSuggestionEngine2.xml";
+
+add_task(async function setup() {
+ if (!gHttpServer) {
+ gHttpServer = new HttpServer();
+ try {
+ gHttpServer.start(gPort);
+ gPort = gHttpServer.identity.primaryPort;
+ gHttpServer.identity.setPrimary(gScheme, gHost, gPort);
+ } catch (ex) {
+ info("We can't launch our http server successfully.")
+ }
+ }
+ is(gHttpServer.identity.has(gScheme, gHost, gPort), true, "make sure we have this domain listed");
+
+ await SpecialPowers.pushPrefEnv({
+ set: [["browser.urlbar.autoFill", true],
+ // Turn off speculative connect to the search engine.
+ ["browser.search.suggest.enabled", true],
+ ["browser.urlbar.suggest.searches", true],
+ ["browser.urlbar.speculativeConnect.enabled", true],
+ // In mochitest this number is 0 by default but we have to turn it on.
+ ["network.http.speculative-parallel-limit", 6],
+ // The http server is using IPv4, so it's better to disable IPv6 to avoid weird
+ // networking problem.
+ ["network.dns.disableIPv6", true]],
+ });
+
+ let engine = await promiseNewSearchEngine(TEST_ENGINE_BASENAME);
+ let oldCurrentEngine = Services.search.currentEngine;
+ Services.search.currentEngine = engine;
+
+ registerCleanupFunction(async function() {
+ await PlacesUtils.history.clear();
+ Services.search.currentEngine = oldCurrentEngine;
+ gHttpServer.identity.remove(gScheme, gHost, gPort);
+ gHttpServer.stop(() => {
+ gHttpServer = null;
+ });
+ });
+});
+
+add_task(async function autofill_tests() {
+ info("Searching for 'foo'");
+ await promiseAutocompleteResultPopup("foo", window, true);
+ // Check if the first result is with type "searchengine"
+ let controller = gURLBar.popup.input.controller;
+ let style = controller.getStyleAt(0);
+ is(style.includes("searchengine"), true, "The first result type is searchengine");
+ await promiseSpeculativeConnection(gHttpServer);
+});
+
diff --git a/browser/base/content/test/urlbar/head.js b/browser/base/content/test/urlbar/head.js
index 6d729d555422..5a5939f31716 100644
--- a/browser/base/content/test/urlbar/head.js
+++ b/browser/base/content/test/urlbar/head.js
@@ -235,3 +235,14 @@ function promisePageActionViewShown() {
}, { once: true });
});
}
+
+function promiseSpeculativeConnection(httpserver) {
+ return BrowserTestUtils.waitForCondition(() => {
+ if (httpserver) {
+ is(httpserver.connectionNumber, 1,
+ `${httpserver.connectionNumber} speculative connection has been setup.`)
+ return httpserver.connectionNumber == 1;
+ }
+ return false;
+ }, "Waiting for connection setup");
+}
diff --git a/browser/base/content/test/urlbar/searchSuggestionEngine2.xml b/browser/base/content/test/urlbar/searchSuggestionEngine2.xml
new file mode 100644
index 000000000000..23522c18994d
--- /dev/null
+++ b/browser/base/content/test/urlbar/searchSuggestionEngine2.xml
@@ -0,0 +1,13 @@
+
+
+
+
+browser_searchSuggestionEngine searchSuggestionEngine.xml
+
+
+
+
+
+
+
diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml
index 8fb76828106a..e225775c22ff 100644
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -76,9 +76,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
.getService(Components.interfaces.nsIPrefService)
.getDefaultBranch("browser.urlbar.");
+ Services.prefs.addObserver("browser.search.suggest.enabled", this);
+ this.browserSearchSuggestEnabled = Services.prefs.getBoolPref("browser.search.suggest.enabled");
+
this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll");
this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll");
this.completeDefaultIndex = this._prefs.getBoolPref("autoFill");
+ this.speculativeConnectEnabled = this._prefs.getBoolPref("speculativeConnect.enabled");
+ this.urlbarSearchSuggestEnabled = this._prefs.getBoolPref("suggest.searches");
this.timeout = this._prefs.getIntPref("delay");
this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled");
this._mayTrimURLs = this._prefs.getBoolPref("trimURLs");
@@ -134,6 +139,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
0 &&
- this.input.mController.getStyleAt(0).includes("autofill")) {
- let uri = this.input.mController.getFinalCompleteValueAt(0);
- // "http" will be stripped out, but other scheme won't.
- if (!uri.includes("://")) {
- uri = "http://" + uri;
+ this.input.speculativeConnectEnabled &&
+ !this.input.inPrivateContext &&
+ this.input.mController.matchCount > 0) {
+ let firstStyle = this.input.mController.getStyleAt(0);
+ if (firstStyle.includes("autofill")) {
+ let uri = this.input.mController.getFinalCompleteValueAt(0);
+ // "http" will be stripped out, but other scheme won't.
+ if (!uri.includes("://")) {
+ uri = "http://" + uri;
+ }
+ this.maybeSetupSpeculativeConnect(uri);
+ } else if (firstStyle.includes("searchengine") &&
+ this.input.browserSearchSuggestEnabled &&
+ this.input.urlbarSearchSuggestEnabled) {
+ // Preconnect to the current search engine only if the search
+ // suggestions are enabled.
+ let engine = Services.search.currentEngine;
+ engine.speculativeConnect({window,
+ originAttributes: gBrowser.contentPrincipal.originAttributes});
}
- this.maybeSetupSpeculativeConnect(uri);
}
// When a result is present the footer should always be visible.
diff --git a/testing/profiles/prefs_general.js b/testing/profiles/prefs_general.js
index 88fcd90a5cce..c53bb1f74b09 100644
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -7,7 +7,7 @@ user_pref("browser.firstrun.show.uidiscovery", false);
user_pref("browser.startup.page", 0); // use about:blank, not browser.startup.homepage
user_pref("browser.search.suggest.timeout", 10000); // use a 10s suggestion timeout in tests
user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
-user_pref("browser.urlbar.speculativeConnection.enabled", false);
+user_pref("browser.urlbar.speculativeConnect.enabled", false);
user_pref("dom.allow_scripts_to_close_windows", true);
user_pref("dom.disable_open_during_load", false);
user_pref("dom.experimental_forms", true); // on for testing