Bug 388287 - Focus the proxy port field if its value is 0 and the server name is specified. r=MattN
authorManish Goregaokar <manishearth@gmail.com>
Thu, 13 Mar 2014 01:07:28 -0700
changeset 173323 dce96be376bd751874fd28d57c8c68d0aaa28788
parent 173322 81c63efd1278db830ac6dbbaedcee3f959e27259
child 173367 d9b7a56dbffbe6c668c962267fb9022114a58936
push id5651
push usermozilla@noorenberghe.ca
push dateThu, 13 Mar 2014 08:07:55 +0000
treeherderfx-team@dce96be376bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs388287
milestone30.0a1
Bug 388287 - Focus the proxy port field if its value is 0 and the server name is specified. r=MattN
browser/components/preferences/connection.js
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_connection_bug388287.js
browser/components/preferences/tests/browser.ini
browser/components/preferences/tests/browser_connection_bug388287.js
--- a/browser/components/preferences/connection.js
+++ b/browser/components/preferences/connection.js
@@ -13,16 +13,31 @@ var gConnectionsDialog = {
     }
 
     if (proxyTypePref.value != 1)
       return true;
 
     var httpProxyURLPref = document.getElementById("network.proxy.http");
     var httpProxyPortPref = document.getElementById("network.proxy.http_port");
     var shareProxiesPref = document.getElementById("network.proxy.share_proxy_settings");
+
+    // If the port is 0 and the proxy server is specified, focus on the port and cancel submission.
+    for (let prefName of ["http","ssl","ftp","socks"]) {
+      let proxyPortPref = document.getElementById("network.proxy." + prefName + "_port");
+      let proxyPref = document.getElementById("network.proxy." + prefName);
+      // Only worry about ports which are currently active. If the share option is on, then ignore
+      // all ports except the HTTP port
+      if (proxyPref.value != "" && proxyPortPref.value == 0 &&
+            (prefName == "http" || !shareProxiesPref.value)) {
+        document.getElementById("networkProxy" + prefName.toUpperCase() + "_Port").focus();
+        return false;
+      }
+    }
+
+    // In the case of a shared proxy preference, backup the current values and update with the HTTP value
     if (shareProxiesPref.value) {
       var proxyPrefs = ["ssl", "ftp", "socks"];
       for (var i = 0; i < proxyPrefs.length; ++i) {
         var proxyServerURLPref = document.getElementById("network.proxy." + proxyPrefs[i]);
         var proxyPortPref = document.getElementById("network.proxy." + proxyPrefs[i] + "_port");
         var backupServerURLPref = document.getElementById("network.proxy.backup." + proxyPrefs[i]);
         var backupPortPref = document.getElementById("network.proxy.backup." + proxyPrefs[i] + "_port");
         backupServerURLPref.value = backupServerURLPref.value || proxyServerURLPref.value;
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -2,16 +2,17 @@
 support-files =
   head.js
   privacypane_tests_perwindow.js
 
 [browser_advanced_update.js]
 [browser_bug410900.js]
 [browser_bug731866.js]
 [browser_connection.js]
+[browser_connection_bug388287.js]
 [browser_healthreport.js]
 skip-if = !healthreport || (os == 'linux' && debug)
 [browser_proxy_backup.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
 [browser_privacypane_5.js]
 [browser_privacypane_8.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_connection_bug388287.js
@@ -0,0 +1,168 @@
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// From browser/components/preferences/in-content/test/head.js
+function open_preferences(aCallback) {
+  gBrowser.selectedTab = gBrowser.addTab("about:preferences");
+  let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
+  newTabBrowser.addEventListener("Initialized", function () {
+    newTabBrowser.removeEventListener("Initialized", arguments.callee, true);
+    aCallback(gBrowser.contentWindow);
+  }, true);
+}
+
+function test() {
+  waitForExplicitFinish();
+  let connectionTests = runConnectionTestsGen();
+  connectionTests.next();
+  const connectionURL = "chrome://browser/content/preferences/connection.xul";
+  let closeable = false;
+  let finalTest = false;
+  let prefWin;
+
+  // The changed preferences need to be backed up and restored because this mochitest
+  // changes them setting from the default
+  let oldNetworkProxyType = Services.prefs.getIntPref("network.proxy.type");
+  registerCleanupFunction(function() {
+    Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
+    Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
+    for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
+      Services.prefs.clearUserPref("network.proxy." + proxyType);
+      Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
+      if (proxyType == "http") {
+        continue;
+      }
+      Services.prefs.clearUserPref("network.proxy.backup." + proxyType);
+      Services.prefs.clearUserPref("network.proxy.backup." + proxyType + "_port");
+    }
+    try {
+      Services.ww.unregisterNotification(observer);
+    } catch(e) {
+      // Do nothing, if the test was successful the above line should fail silently.
+    }
+  });
+
+  // this observer is registered after the pref tab loads
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      if (aTopic == "domwindowopened") {
+        // when the connection window loads, proceed forward in test
+        let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
+        win.addEventListener("load", function winLoadListener() {
+          win.removeEventListener("load", winLoadListener);
+          if (win.location.href == connectionURL) {
+            // If this is a connection window, run the next test
+            connectionTests.next(win);
+          }
+        });
+      } else if (aTopic == "domwindowclosed") {
+        // Check if the window should have closed, and respawn another window for further testing
+        let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
+        if (win.location.href == connectionURL) {
+          ok(closeable, "Connection dialog closed");
+
+          // Last close event, don't respawn, and clean up
+          if (finalTest) {
+            Services.ww.unregisterNotification(observer);
+            gBrowser.removeCurrentTab();
+            finish();
+            return;
+          }
+
+          // Open another connection pane for the next test
+          gBrowser.contentWindow.gAdvancedPane.showConnections();
+        }
+      }
+    }
+  };
+
+  // The actual tests to run, in a generator
+  function* runConnectionTestsGen() {
+    let doc, connectionWin, proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
+
+    // Convenient function to reset the variables for the new window
+    function setDoc(win) {
+      doc = win.document;
+      connectionWin = win;
+      proxyTypePref = doc.getElementById("network.proxy.type");
+      sharePref = doc.getElementById("network.proxy.share_proxy_settings");
+      httpPref = doc.getElementById("network.proxy.http");
+      httpPortPref = doc.getElementById("network.proxy.http_port");
+      ftpPref = doc.getElementById("network.proxy.ftp");
+      ftpPortPref = doc.getElementById("network.proxy.ftp_port");
+    }
+
+    // This batch of tests should not close the dialog
+    setDoc(yield null);
+
+    // Testing HTTP port 0 with share on
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    httpPref.value = "localhost";
+    httpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // Testing HTTP port 0 + FTP port 80 with share off
+    sharePref.value = false;
+    ftpPref.value = "localhost";
+    ftpPortPref.value = 80;
+    doc.documentElement.acceptDialog();
+
+    // Testing HTTP port 80 + FTP port 0 with share off
+    httpPortPref.value = 80;
+    ftpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // From now on, the dialog should close since we are giving it legitimate inputs.
+    // The test will timeout if the onbeforeaccept kicks in erroneously.
+    closeable = true;
+
+    // Both ports 80, share on
+    httpPortPref.value = 80;
+    ftpPortPref.value = 80;
+    doc.documentElement.acceptDialog();
+
+    // HTTP 80, FTP 0, with share on
+    setDoc(yield null);
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    ftpPref.value = "localhost";
+    httpPref.value = "localhost";
+    httpPortPref.value = 80;
+    ftpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // HTTP host empty, port 0 with share on
+    setDoc(yield null);
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    httpPref.value = "";
+    httpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // HTTP 0, but in no proxy mode
+    setDoc(yield null);
+    proxyTypePref.value = 0;
+    sharePref.value = true;
+    httpPref.value = "localhost";
+    httpPortPref.value = 0;
+
+    // This is the final test, don't spawn another connection window
+    finalTest = true;
+    doc.documentElement.acceptDialog();
+    yield null;
+  }
+
+  /*
+   The connection dialog alone won't save onaccept since it uses type="child",
+   so it has to be opened as a sub dialog of the main pref tab.
+   Open the main tab here.
+   */
+  open_preferences(function tabOpened(aContentWindow) {
+    Services.ww.registerNotification(observer);
+    gBrowser.contentWindow.gAdvancedPane.showConnections();
+  });
+}
--- a/browser/components/preferences/tests/browser.ini
+++ b/browser/components/preferences/tests/browser.ini
@@ -2,16 +2,17 @@
 support-files =
   head.js
   privacypane_tests_perwindow.js
 
 [browser_advanced_update.js]
 [browser_bug410900.js]
 [browser_bug705422.js]
 [browser_chunk_permissions.js]
+[browser_connection_bug388287.js]
 [browser_healthreport.js]
 skip-if = !healthreport || (os == 'linux' && debug)
 [browser_permissions.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
 [browser_privacypane_5.js]
 [browser_privacypane_8.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/tests/browser_connection_bug388287.js
@@ -0,0 +1,160 @@
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  let connectionTests = runConnectionTestsGen();
+  connectionTests.next();
+  const connectionURL = "chrome://browser/content/preferences/connection.xul";
+  const preferencesURL = "chrome://browser/content/preferences/preferences.xul";
+  let closeable = false;
+  let final = false;
+  let prefWin;
+
+  // The changed preferences need to be backed up and restored because this mochitest
+  // changes them setting from the default
+  let oldNetworkProxyType = Services.prefs.getIntPref("network.proxy.type");
+  registerCleanupFunction(function() {
+    Services.prefs.setIntPref("network.proxy.type", oldNetworkProxyType);
+    Services.prefs.clearUserPref("network.proxy.share_proxy_settings");
+    for (let proxyType of ["http", "ssl", "ftp", "socks"]) {
+      Services.prefs.clearUserPref("network.proxy." + proxyType);
+      Services.prefs.clearUserPref("network.proxy." + proxyType + "_port");
+      if (proxyType == "http") {
+        continue;
+      }
+      Services.prefs.clearUserPref("network.proxy.backup." + proxyType);
+      Services.prefs.clearUserPref("network.proxy.backup." + proxyType + "_port");
+    }
+    try {
+      Services.ww.unregisterNotification(observer);
+    } catch(e) {
+      // Do nothing, if the test was successful the above line should fail silently.
+    }
+  });
+
+  // this observer is registered after the pref tab loads
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      if (aTopic == "domwindowopened") {
+        // when the connection window loads, proceed forward in test
+        let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
+        win.addEventListener("load", function winLoadListener() {
+          win.removeEventListener("load", winLoadListener);
+          if (win.location.href == connectionURL) {
+            // If this is a connection window, run the next test
+            connectionTests.next(win);
+          } else if (win.location.href == preferencesURL) {
+            // If this is the preferences window, initiate the tests by showing the connection pane
+            prefWin = win;
+            prefWin.gAdvancedPane.showConnections();
+
+            // Since the above method immediately triggers the observer chain,
+            // the cleanup below won't happen until all the tests finish successfully.
+            prefWin.close();
+            Services.prefs.setIntPref("network.proxy.type",0);
+            finish();
+          }
+        });
+      } else if (aTopic == "domwindowclosed") {
+        // Check if the window should have closed, and respawn another window for further testing
+        let win = aSubject.QueryInterface(Components.interfaces.nsIDOMWindow);
+        if (win.location.href == connectionURL) {
+          ok(closeable, "Connection dialog closed");
+
+          // Last close event, don't respawn
+          if(final){
+            Services.ww.unregisterNotification(observer);
+            return;
+          }
+
+          // Open another connection pane for the next test
+          prefWin.gAdvancedPane.showConnections();
+        }
+      }
+    }
+  }
+
+  // The actual tests to run, in a generator
+  function* runConnectionTestsGen() {
+    let doc, connectionWin, proxyTypePref, sharePref, httpPref, httpPortPref, ftpPref, ftpPortPref;
+
+    // Convenient function to reset the variables for the new window
+    function setDoc(win){
+      doc = win.document;
+      connectionWin = win;
+      proxyTypePref = doc.getElementById("network.proxy.type");
+      sharePref = doc.getElementById("network.proxy.share_proxy_settings");
+      httpPref = doc.getElementById("network.proxy.http");
+      httpPortPref = doc.getElementById("network.proxy.http_port");
+      ftpPref = doc.getElementById("network.proxy.ftp");
+      ftpPortPref = doc.getElementById("network.proxy.ftp_port");
+    }
+
+    // This batch of tests should not close the dialog
+    setDoc(yield null);
+
+    // Testing HTTP port 0 with share on
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    httpPref.value = "localhost";
+    httpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // Testing HTTP port 0 + FTP port 80 with share off
+    sharePref.value = false;
+    ftpPref.value = "localhost";
+    ftpPortPref.value = 80;
+    doc.documentElement.acceptDialog();
+
+    // Testing HTTP port 80 + FTP port 0 with share off
+    httpPortPref.value = 80;
+    ftpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // From now on, the dialog should close since we are giving it legitimate inputs.
+    // The test will timeout if the onbeforeaccept kicks in erroneously.
+    closeable = true;
+
+    // Both ports 80, share on
+    httpPortPref.value = 80;
+    ftpPortPref.value = 80;
+    doc.documentElement.acceptDialog();
+
+    // HTTP 80, FTP 0, with share on
+    setDoc(yield null);
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    ftpPref.value = "localhost";
+    httpPref.value = "localhost";
+    httpPortPref.value = 80;
+    ftpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // HTTP host empty, port 0 with share on
+    setDoc(yield null);
+    proxyTypePref.value = 1;
+    sharePref.value = true;
+    httpPref.value = "";
+    httpPortPref.value = 0;
+    doc.documentElement.acceptDialog();
+
+    // HTTP 0, but in no proxy mode
+    setDoc(yield null);
+    proxyTypePref.value = 0;
+    sharePref.value = true;
+    httpPref.value = "localhost";
+    httpPortPref.value = 0;
+
+    final = true; // This is the final test, don't spawn another connection window
+    doc.documentElement.acceptDialog();
+    yield null;
+  }
+
+  Services.ww.registerNotification(observer);
+  openDialog(preferencesURL, "Preferences",
+           "chrome,titlebar,toolbar,centerscreen,dialog=no", "paneAdvanced");
+}