Backed out changeset 53d701cacdea (bug 1289913) for failing xpcshell test_user_autocomplete_result.js on Android and mochitest test_password_field_autocomplete.html on many platforms. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 12 Nov 2016 14:10:32 +0100
changeset 352264 162e1d1d9565e6d825c02b3e738bfaa1bf9766d6
parent 352263 dc661e1aa5ed02dcfbc644472f5377e6ce2c0faa
child 352265 516fd53f0f8428dd05a803ec9eaf9922ce23fedc
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1289913
milestone52.0a1
backs out53d701cacdeacc6b49f958844ea69d8670e3c1fa
Backed out changeset 53d701cacdea (bug 1289913) for failing xpcshell test_user_autocomplete_result.js on Android and mochitest test_password_field_autocomplete.html on many platforms. r=backout
modules/libpref/init/all.js
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/LoginManagerParent.jsm
toolkit/components/passwordmgr/nsLoginManager.js
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js
toolkit/components/passwordmgr/test/unit/xpcshell.ini
toolkit/components/satchel/nsFormFillController.cpp
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2166,19 +2166,16 @@ pref("security.sri.enable", true);
 pref("security.block_script_with_wrong_mime", true);
 
 // Block images of wrong MIME for XCTO: nosniff.
 pref("security.xcto_nosniff_block_images", false);
 
 // OCSP must-staple
 pref("security.ssl.enable_ocsp_must_staple", true);
 
-// Insecure Form Field Warning
-pref("security.insecure_field_warning.contextual.enabled", false);
-
 // Disable pinning checks by default.
 pref("security.cert_pinning.enforcement_level", 0);
 // Do not process hpkp headers rooted by not built in roots by default.
 // This is to prevent accidental pinning from MITM devices and is used
 // for tests.
 pref("security.cert_pinning.process_headers_from_non_builtin_roots", false);
 
 // If set to true, allow view-source URIs to be opened from URIs that share
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -31,17 +31,16 @@ Cu.import("resource://gre/modules/XPCOMU
 this.LoginHelper = {
   /**
    * Warning: these only update if a logger was created.
    */
   debug: Services.prefs.getBoolPref("signon.debug"),
   formlessCaptureEnabled: Services.prefs.getBoolPref("signon.formlessCapture.enabled"),
   schemeUpgrades: Services.prefs.getBoolPref("signon.schemeUpgrades"),
   insecureAutofill: Services.prefs.getBoolPref("signon.autofillForms.http"),
-  showInsecureFieldWarning: Services.prefs.getBoolPref("security.insecure_field_warning.contextual.enabled"),
 
   createLogger(aLogPrefix) {
     let getMaxLogLevel = () => {
       return this.debug ? "debug" : "warn";
     };
 
     // Create a new instance of the ConsoleAPI so we can control the maxLogLevel with a pref.
     let ConsoleAPI = Cu.import("resource://gre/modules/Console.jsm", {}).ConsoleAPI;
@@ -55,20 +54,16 @@ this.LoginHelper = {
     Services.prefs.addObserver("signon.", () => {
       this.debug = Services.prefs.getBoolPref("signon.debug");
       this.formlessCaptureEnabled = Services.prefs.getBoolPref("signon.formlessCapture.enabled");
       this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
       this.insecureAutofill = Services.prefs.getBoolPref("signon.autofillForms.http");
       logger.maxLogLevel = getMaxLogLevel();
     }, false);
 
-    Services.prefs.addObserver("security.insecure_field_warning.", () => {
-      this.showInsecureFieldWarning = Services.prefs.getBoolPref("security.insecure_field_warning.contextual.enabled");
-    }, false);
-
     return logger;
   },
 
   /**
    * Due to the way the signons2.txt file is formatted, we need to make
    * sure certain field values or characters do not cause the file to
    * be parsed incorrectly.  Reject hostnames that we can't store correctly.
    *
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -5,16 +5,17 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = [ "LoginManagerContent",
                           "LoginFormFactory",
                           "UserAutoCompleteResult" ];
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 const PASSWORD_INPUT_ADDED_COALESCING_THRESHOLD_MS = 1;
+const PREF_INSECURE_FIELD_WARNING_ENABLED = "security.insecure_field_warning.contextual.enabled";
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Cu.import("resource://gre/modules/InsecurePasswordUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/Preferences.jsm");
 
@@ -307,17 +308,16 @@ var LoginManagerContent = {
 
     let requestData = {};
     let messageData = { formOrigin: formOrigin,
                         actionOrigin: actionOrigin,
                         searchString: aSearchString,
                         previousResult: previousResult,
                         rect: aRect,
                         isSecure: InsecurePasswordUtils.isFormSecure(form),
-                        isPasswordField: aElement.type == "password",
                         remote: remote };
 
     return this._sendRequest(messageManager, requestData,
                              "RemoteLogins:autoCompleteLogins",
                              messageData);
   },
 
   setupProgressListener(window) {
@@ -969,18 +969,16 @@ var LoginManagerContent = {
 
       // Need a valid password field to do anything.
       if (passwordField == null) {
         log("not filling form, no password field found");
         recordAutofillResult(AUTOFILL_RESULT.NO_PASSWORD_FIELD);
         return;
       }
 
-      this._formFillService.markAsLoginManagerField(passwordField);
-
       // If the password field is disabled or read-only, there's nothing to do.
       if (passwordField.disabled || passwordField.readOnly) {
         log("not filling form, password field disabled or read-only");
         recordAutofillResult(AUTOFILL_RESULT.PASSWORD_DISABLED_READONLY);
         return;
       }
 
       // Prevent autofilling insecure forms.
@@ -1024,19 +1022,18 @@ var LoginManagerContent = {
         log("form not filled, none of the logins fit in the field");
         recordAutofillResult(AUTOFILL_RESULT.NO_LOGINS_FIT);
         return;
       }
 
       // Attach autocomplete stuff to the username field, if we have
       // one. This is normally used to select from multiple accounts,
       // but even with one account we should refill if the user edits.
-      if (usernameField) {
+      if (usernameField)
         this._formFillService.markAsLoginManagerField(usernameField);
-      }
 
       // Don't clobber an existing password.
       if (passwordField.value && !clobberPassword) {
         log("form not filled, the password field was already filled");
         recordAutofillResult(AUTOFILL_RESULT.EXISTING_PASSWORD);
         return;
       }
 
@@ -1215,56 +1212,39 @@ var LoginUtils = {
     if (uriString == "")
       uriString = form.baseURI; // ala bug 297761
 
     return this._getPasswordOrigin(uriString, true);
   },
 };
 
 // nsIAutoCompleteResult implementation
-function UserAutoCompleteResult (aSearchString, matchingLogins, {isSecure, messageManager, isPasswordField}) {
+function UserAutoCompleteResult (aSearchString, matchingLogins, {isSecure, messageManager}) {
   function loginSort(a, b) {
     var userA = a.username.toLowerCase();
     var userB = b.username.toLowerCase();
 
     if (userA < userB)
       return -1;
 
     if (userA > userB)
       return  1;
 
     return 0;
   }
 
-  function findDuplicates(loginList) {
-    let seen = new Set();
-    let duplicates = new Set();
-    for (let login of loginList) {
-      if (seen.has(login.username)) {
-        duplicates.add(login.username);
-      }
-      seen.add(login.username);
-    }
-    return duplicates;
-  }
+  let prefShowInsecureFieldWarning =
+    Preferences.get(PREF_INSECURE_FIELD_WARNING_ENABLED, false);
 
-  if (!LoginHelper.insecureAutofill && !isSecure) {
-    matchingLogins = [];
-  }
-
-  this._showInsecureFieldWarning = (!isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
+  this._showInsecureFieldWarning = (!isSecure && prefShowInsecureFieldWarning) ? 1 : 0;
   this.searchString = aSearchString;
   this.logins = matchingLogins.sort(loginSort);
   this.matchCount = matchingLogins.length + this._showInsecureFieldWarning;
   this._messageManager = messageManager;
-  this._isPasswordField = isPasswordField;
   this._stringBundle = Services.strings.createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
-  this._duplicateUsernames = findDuplicates(matchingLogins);
-  this._dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
-                              { day: "numeric", month: "short", year: "numeric" });
 
   if (this.matchCount > 0) {
     this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
     this.defaultIndex = 0;
   }
 }
 
 UserAutoCompleteResult.prototype = {
@@ -1283,60 +1263,35 @@ UserAutoCompleteResult.prototype = {
   // Interfaces from idl...
   searchString : null,
   searchResult : Ci.nsIAutoCompleteResult.RESULT_NOMATCH,
   defaultIndex : -1,
   errorDescription : "",
   matchCount : 0,
 
   getValueAt(index) {
-    if (index < 0 || index >= this.matchCount) {
+    if (index < 0 || index >= this.matchCount)
       throw new Error("Index out of range.");
-    }
 
     if (this._showInsecureFieldWarning && index === 0) {
       return "";
     }
 
-    let selectedLogin = this.logins[index - this._showInsecureFieldWarning];
-
-    return this._isPasswordField ? selectedLogin.password : selectedLogin.username;
+    return this.logins[index - this._showInsecureFieldWarning].username;
   },
 
   getLabelAt(index) {
-    if (index < 0 || index >= this.matchCount) {
+    if (index < 0 || index >= this.matchCount)
       throw new Error("Index out of range.");
-    }
 
     if (this._showInsecureFieldWarning && index === 0) {
       return this._stringBundle.GetStringFromName("insecureFieldWarningDescription");
     }
 
-    let that = this;
-
-    function getLocalizedString(key, formatArgs) {
-      if (formatArgs) {
-        return that._stringBundle.formatStringFromName(key, formatArgs, formatArgs.length);
-      }
-      return that._stringBundle.GetStringFromName(key);
-    }
-
-    let login = this.logins[index - this._showInsecureFieldWarning];
-    let username = login.username;
-    // If login is empty or duplicated we want to append a modification date to it.
-    if (!username || this._duplicateUsernames.has(username)) {
-      if (!username) {
-        username = getLocalizedString("noUsername");
-      }
-      let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
-      let time = this._dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
-      username = getLocalizedString("loginHostAge", [username, time]);
-    }
-
-    return username;
+    return this.logins[index - this._showInsecureFieldWarning].username;
   },
 
   getCommentAt(index) {
     return "";
   },
 
   getStyleAt(index) {
     if (index == 0 && this._showInsecureFieldWarning) {
@@ -1349,19 +1304,18 @@ UserAutoCompleteResult.prototype = {
     return "";
   },
 
   getFinalCompleteValueAt(index) {
     return this.getValueAt(index);
   },
 
   removeValueAt(index, removeFromDB) {
-    if (index < 0 || index >= this.matchCount) {
-      throw new Error("Index out of range.");
-    }
+    if (index < 0 || index >= this.matchCount)
+        throw new Error("Index out of range.");
 
     if (this._showInsecureFieldWarning && index === 0) {
       // Ignore the warning message item.
       return;
     }
     if (this._showInsecureFieldWarning) {
       index--;
     }
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -222,18 +222,17 @@ var LoginManagerParent = {
       requestId: requestId,
       logins: jsLogins,
       recipes,
     });
   }),
 
   doAutocompleteSearch: function({ formOrigin, actionOrigin,
                                    searchString, previousResult,
-                                   rect, requestId, isSecure, isPasswordField,
-                                   remote }, target) {
+                                   rect, requestId, isSecure, remote }, target) {
     // Note: previousResult is a regular object, not an
     // nsIAutoCompleteResult.
 
     let searchStringLower = searchString.toLowerCase();
     let logins;
     if (previousResult &&
         searchStringLower.startsWith(previousResult.searchString.toLowerCase())) {
       log("Using previous autocomplete result");
@@ -256,21 +255,17 @@ var LoginManagerParent = {
       ];
       logins = LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin);
     }
 
     let matchingLogins = logins.filter(function(fullMatch) {
       let match = fullMatch.username;
 
       // Remove results that are too short, or have different prefix.
-      // Also don't offer empty usernames as possible results except
-      // for password field.
-      if (isPasswordField) {
-        return true;
-      }
+      // Also don't offer empty usernames as possible results.
       return match && match.toLowerCase().startsWith(searchStringLower);
     });
 
     // XXX In the E10S case, we're responsible for showing our own
     // autocomplete popup here because the autocomplete protocol hasn't
     // been e10s-ized yet. In the non-e10s case, our caller is responsible
     // for showing the autocomplete popup (via the regular
     // nsAutoCompleteController).
--- a/toolkit/components/passwordmgr/nsLoginManager.js
+++ b/toolkit/components/passwordmgr/nsLoginManager.js
@@ -479,21 +479,16 @@ LoginManager.prototype = {
    */
   autoCompleteSearchAsync(aSearchString, aPreviousResult,
                           aElement, aCallback) {
     // aPreviousResult is an nsIAutoCompleteResult, aElement is
     // nsIDOMHTMLInputElement
 
     let form = LoginFormFactory.createFromField(aElement);
     let isSecure = InsecurePasswordUtils.isFormSecure(form);
-    let isPasswordField = aElement.type == "password";
-    if (isPasswordField) {
-      // The login items won't be filtered for password field.
-      aSearchString = "";
-    }
 
     if (!this._remember) {
       setTimeout(function() {
         aCallback.onSearchCompletion(new UserAutoCompleteResult(aSearchString, [], {isSecure}));
       }, 0);
       return;
     }
 
@@ -518,17 +513,16 @@ LoginManager.prototype = {
                                  return;
                                }
 
                                this._autoCompleteLookupPromise = null;
                                let results =
                                  new UserAutoCompleteResult(aSearchString, logins, {
                                    messageManager,
                                    isSecure,
-                                   isPasswordField,
                                  });
                                aCallback.onSearchCompletion(results);
                              })
                             .then(null, Cu.reportError);
   },
 
   stopSearch() {
     this._autoCompleteLookupPromise = null;
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -22,18 +22,16 @@ skip-if = toolkit == 'android' # Bug 125
 [test_basic_form_1pw_2.html]
 [test_basic_form_2pw_1.html]
 [test_basic_form_2pw_2.html]
 [test_basic_form_3pw_1.html]
 [test_basic_form_autocomplete.html]
 skip-if = toolkit == 'android' # android:autocomplete.
 [test_insecure_form_field_autocomplete.html]
 skip-if = toolkit == 'android' # android:autocomplete.
-[test_password_field_autocomplete.html]
-skip-if = toolkit == 'android' # android:autocomplete.
 [test_basic_form_html5.html]
 [test_basic_form_pwevent.html]
 [test_basic_form_pwonly.html]
 [test_bug_627616.html]
 skip-if = toolkit == 'android' # Tests desktop prompts
 [test_bug_776171.html]
 [test_case_differences.html]
 skip-if = toolkit == 'android' # autocomplete
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
@@ -204,53 +204,29 @@ function sendFakeAutocompleteEvent(eleme
   element.dispatchEvent(acEvent);
 }
 
 function spinEventLoop() {
   return Promise.resolve();
 }
 
 add_task(function* setup() {
-  yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", false],
-                                           ["signon.autofillForms.http", true]]});
+  yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", false]]});
   listenForUnexpectedPopupShown();
 });
 
 add_task(function* test_form1_initial_empty() {
   yield SimpleTest.promiseFocus(window);
 
   // Make sure initial form is empty.
   checkACForm("", "");
   let popupState = yield getPopupState();
   is(popupState.open, false, "Check popup is initially closed");
 });
 
-add_task(function* test_form1_menuitems() {
-  yield SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  restoreForm();
-  let shownPromise = promiseACShown();
-  doKey("down"); // open
-  let results = yield shownPromise;
-
-  let popupState = yield getPopupState();
-  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
-
-  let expectedMenuItems = ["tempuser1",
-                           "testuser2",
-                           "testuser3",
-                           "zzzuser4"];
-  checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly.");
-
-  checkACForm("", ""); // value shouldn't update just by selecting
-  doKey("return"); // not "enter"!
-  yield spinEventLoop(); // let focus happen
-  checkACForm("", "");
-});
-
 add_task(function* test_form1_first_entry() {
   yield SimpleTest.promiseFocus(window);
   // Trigger autocomplete popup
   restoreForm();
   let shownPromise = promiseACShown();
   doKey("down"); // open
   yield shownPromise;
 
--- a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
@@ -204,18 +204,17 @@ function sendFakeAutocompleteEvent(eleme
   element.dispatchEvent(acEvent);
 }
 
 function spinEventLoop() {
   return Promise.resolve();
 }
 
 add_task(function* setup() {
-  yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", true],
-                                           ["signon.autofillForms.http", true]]});
+  yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", true]]});
   listenForUnexpectedPopupShown();
 });
 
 add_task(function* test_form1_initial_empty() {
   yield SimpleTest.promiseFocus(window);
 
   // Make sure initial form is empty.
   checkACForm("", "");
@@ -224,28 +223,21 @@ add_task(function* test_form1_initial_em
 });
 
 add_task(function* test_form1_warning_entry() {
   yield SimpleTest.promiseFocus(window);
   // Trigger autocomplete popup
   restoreForm();
   let shownPromise = promiseACShown();
   doKey("down"); // open
-  let results = yield shownPromise;
+  yield shownPromise;
 
   let popupState = yield getPopupState();
   is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
 
-  let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised.",
-                           "tempuser1",
-                           "testuser2",
-                           "testuser3",
-                           "zzzuser4"];
-  checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly.");
-
   doKey("down"); // select insecure warning
   checkACForm("", ""); // value shouldn't update just by selecting
   doKey("return"); // not "enter"!
   yield spinEventLoop(); // let focus happen
   checkACForm("", "");
 });
 
 add_task(function* test_form1_first_entry() {
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
+++ /dev/null
@@ -1,267 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test basic login autocomplete</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
-  <script type="text/javascript" src="satchel_common.js"></script>
-  <script type="text/javascript" src="pwmgr_common.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-Login Manager test: multiple login autocomplete
-
-<script>
-var chromeScript = runChecksAfterCommonInit();
-
-var setupScript = runInParent(function setup() {
-  const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-  Cu.import("resource://gre/modules/Services.jsm");
-
-  // Create some logins just for this form, since we'll be deleting them.
-  var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
-                                           Ci.nsILoginInfo, "init");
-  assert.ok(nsLoginInfo != null, "nsLoginInfo constructor");
-
-  // login0 has no username, so should be filtered out from the autocomplete list.
-  var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                               "", "user0pass", "", "pword");
-
-  var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                               "tempuser1", "temppass1", "uname", "pword");
-
-  var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                               "testuser2", "testpass2", "uname", "pword");
-
-  var login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                               "testuser3", "testpass3", "uname", "pword");
-
-  var login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                               "zzzuser4", "zzzpass4", "uname", "pword");
-
-
-  // try/catch in case someone runs the tests manually, twice.
-  try {
-    Services.logins.addLogin(login0);
-    Services.logins.addLogin(login1);
-    Services.logins.addLogin(login2);
-    Services.logins.addLogin(login3);
-    Services.logins.addLogin(login4);
-  } catch (e) {
-    assert.ok(false, "addLogin threw: " + e);
-  }
-
-  addMessageListener("addLogin", loginVariableName => {
-    let login = eval(loginVariableName);
-    assert.ok(!!login, "Login to add is defined: " + loginVariableName);
-    Services.logins.addLogin(login);
-  });
-  addMessageListener("removeLogin", loginVariableName => {
-    let login = eval(loginVariableName);
-    assert.ok(!!login, "Login to delete is defined: " + loginVariableName);
-    Services.logins.removeLogin(login);
-  });
-});
-</script>
-<p id="display"></p>
-
-<!-- we presumably can't hide the content for this test. -->
-<div id="content">
-
-  <!-- form1 tests multiple matching logins -->
-  <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
-    <input  type="text"       name="uname">
-    <input  type="password"   name="pword">
-    <button type="submit">Submit</button>
-  </form>
-
-  <form id="form2" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
-    <input  type="text"       name="uname">
-    <input  type="password"   name="pword" readonly="true">
-    <button type="submit">Submit</button>
-  </form>
-
-  <form id="form3" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
-    <input  type="text"       name="uname">
-    <input  type="password"   name="pword" disabled="true">
-    <button type="submit">Submit</button>
-  </form>
-
-</div>
-
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Login Manager: multiple login autocomplete. **/
-
-var uname = $_(1, "uname");
-var pword = $_(1, "pword");
-const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK;
-
-// Restore the form to the default state.
-function restoreForm(index) {
-  // Using innerHTML is for creating the autocomplete popup again, so the
-  // preference value will be applied to the constructor of
-  // UserAutoCompleteResult.
-  let form = document.getElementById("form" + index);
-  let temp = form.innerHTML;
-  form.innerHTML = "";
-  form.innerHTML = temp;
-  uname = $_(index, "uname");
-  pword = $_(index, "pword");
-
-  uname.value = "";
-  pword.value = "";
-  pword.focus();
-}
-
-function generateDateString(date) {
-  let dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
-                             { day: "numeric", month: "short", year: "numeric" });
-  return dateAndTimeFormatter.format(date);
-}
-
-const DATE_NOW_STRING = generateDateString(new Date());
-
-// Check for expected username/password in form.
-function checkACFormPasswordField(expectedPassword) {
-  var formID = uname.parentNode.id;
-  is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword);
-}
-
-function spinEventLoop() {
-  return Promise.resolve();
-}
-
-add_task(function* setup() {
-  listenForUnexpectedPopupShown();
-});
-
-add_task(function* test_form1_initial_empty() {
-  yield SimpleTest.promiseFocus(window);
-
-  // Make sure initial form is empty.
-  checkACFormPasswordField("");
-  let popupState = yield getPopupState();
-  is(popupState.open, false, "Check popup is initially closed");
-});
-
-add_task(function* test_form1_enabledInsecureFieldWarning_enabledInsecureAutoFillForm() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-                                            ["security.insecure_field_warning.contextual.enabled", true],
-                                            ["signon.autofillForms.http", true]
-                                          ]});
-  restoreForm(1);
-  yield SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  let shownPromise = promiseACShown();
-  doKey("down"); // open
-  let results = yield shownPromise;
-
-  let popupState = yield getPopupState();
-  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
-
-  let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised.",
-                           "No username (" + DATE_NOW_STRING + ")",
-                           "tempuser1",
-                           "testuser2",
-                           "testuser3",
-                           "zzzuser4"];
-  checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly.");
-
-  doKey("down"); // select insecure warning
-  checkACFormPasswordField(""); // value shouldn't update just by selecting
-  doKey("return"); // not "enter"!
-  yield spinEventLoop(); // let focus happen
-  checkACFormPasswordField("");
-});
-
-add_task(function* test_form1_disabledInsecureFieldWarning_enabledInsecureAutoFillForm() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-                                            ["security.insecure_field_warning.contextual.enabled", false],
-                                            ["signon.autofillForms.http", true]
-                                          ]});
-  restoreForm(1);
-  yield SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  let shownPromise = promiseACShown();
-  doKey("down"); // open
-  let results = yield shownPromise;
-
-  let popupState = yield getPopupState();
-  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
-
-  let expectedMenuItems = ["No username (" + DATE_NOW_STRING + ")",
-                           "tempuser1",
-                           "testuser2",
-                           "testuser3",
-                           "zzzuser4"];
-  checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly.");
-
-  doKey("down"); // select first item
-  checkACFormPasswordField(""); // value shouldn't update just by selecting
-  doKey("return"); // not "enter"!
-  yield spinEventLoop(); // let focus happen
-  checkACFormPasswordField("user0pass");
-});
-
-add_task(function* test_form1_enabledInsecureFieldWarning_disabledInsecureAutoFillForm() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-                                            ["security.insecure_field_warning.contextual.enabled", true],
-                                            ["signon.autofillForms.http", false]
-                                          ]});
-  restoreForm(1);
-  yield SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  let shownPromise = promiseACShown();
-  doKey("down"); // open
-  let results = yield shownPromise;
-
-  let popupState = yield getPopupState();
-  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
-
-  let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised."];
-  checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly.");
-
-  doKey("down"); // select insecure warning
-  checkACFormPasswordField(""); // value shouldn't update just by selecting
-  doKey("return"); // not "enter"!
-  yield spinEventLoop(); // let focus happen
-  checkACFormPasswordField("");
-});
-
-add_task(function* test_form1_disabledInsecureFieldWarning_disabledInsecureAutoFillForm() {
-  yield SpecialPowers.pushPrefEnv({"set": [
-                                            ["security.insecure_field_warning.contextual.enabled", false],
-                                            ["signon.autofillForms.http", false]
-                                          ]});
-  restoreForm(1);
-  yield SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  doKey("down"); // open
-  let popupState = yield getPopupState();
-  is(popupState.open, false, "Check popup is closed with no AutoFillForms.");
-});
-
-add_task(function* test_form2_password_readonly() {
-  // Trigger autocomplete popup
-  restoreForm(2);
-  doKey("down"); // open
-  let popupState = yield getPopupState();
-  is(popupState.open, false, "Check popup is closed for a readonly field.");
-});
-
-add_task(function* test_form3_password_disabled() {
-  // Trigger autocomplete popup
-  restoreForm(3);
-  doKey("down"); // open
-  let popupState = yield getPopupState();
-  is(popupState.open, false, "Check popup is closed for a disabled field.");
-});
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js
+++ /dev/null
@@ -1,448 +0,0 @@
-XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
-                                  "resource://gre/modules/LoginHelper.jsm");
-Cu.import("resource://gre/modules/LoginManagerContent.jsm");
-var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
-                                         Ci.nsILoginInfo, "init");
-
-const PREF_INSECURE_FIELD_WARNING_ENABLED = "security.insecure_field_warning.contextual.enabled";
-const PREF_INSECURE_AUTOFILLFORMS_ENABLED = "signon.autofillForms.http";
-
-let matchingLogins = [];
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                                    "", "emptypass1", "uname", "pword"));
-
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                                    "tempuser1", "temppass1", "uname", "pword"));
-
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                                    "testuser2", "testpass2", "uname", "pword"));
-
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                                    "testuser3", "testpass3", "uname", "pword"));
-
-matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
-                                    "zzzuser4", "zzzpass4", "uname", "pword"));
-
-let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo);
-let dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
-                            { day: "numeric", month: "short", year: "numeric" });
-let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
-const LABEL_NO_USERNAME = "No username (" + time + ")";
-
-let expectedResults = [
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: true,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised.",
-      style: "insecureWarning"
-    }, {
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: false,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised.",
-      style: "insecureWarning"
-    }, {
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: true,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: true,
-    isSecure: false,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: true,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised.",
-      style: "insecureWarning"
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: true,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: false,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: "This connection is not secure. Logins entered here could be compromised.",
-      style: "insecureWarning"
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: true,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "tempuser1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testuser2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testuser3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzuser4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: false,
-    isPasswordField: false,
-    matchingLogins: matchingLogins,
-    items: []
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: true,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: [{
-      value: "emptypass1",
-      label: LABEL_NO_USERNAME,
-      style: ""
-    }, {
-      value: "temppass1",
-      label: "tempuser1",
-      style: ""
-    }, {
-      value: "testpass2",
-      label: "testuser2",
-      style: ""
-    }, {
-      value: "testpass3",
-      label: "testuser3",
-      style: ""
-    }, {
-      value: "zzzpass4",
-      label: "zzzuser4",
-      style: ""
-    }]
-  },
-  {
-    insecureFieldWarningEnabled: false,
-    insecureAutoFillFormsEnabled: false,
-    isSecure: false,
-    isPasswordField: true,
-    matchingLogins: matchingLogins,
-    items: []
-  },
-];
-
-add_task(function* test_all_patterns() {
-  LoginHelper.createLogger("UserAutoCompleteResult");
-  expectedResults.forEach(pattern => {
-    Services.prefs.setBoolPref(PREF_INSECURE_FIELD_WARNING_ENABLED,
-                               pattern.insecureFieldWarningEnabled);
-    Services.prefs.setBoolPref(PREF_INSECURE_AUTOFILLFORMS_ENABLED,
-                               pattern.insecureAutoFillFormsEnabled);
-    let actual = new UserAutoCompleteResult("", pattern.matchingLogins,
-                                            {
-                                              isSecure: pattern.isSecure,
-                                              isPasswordField: pattern.isPasswordField
-                                            });
-    pattern.items.forEach((item, index) => {
-      equal(actual.getValueAt(index), item.value);
-      equal(actual.getLabelAt(index), item.label);
-      equal(actual.getStyleAt(index), item.style);
-    });
-
-    if (pattern.items.length != 0) {
-      Assert.throws(() => actual.getValueAt(pattern.items.length),
-        /Index out of range\./);
-
-      Assert.throws(() => actual.getLabelAt(pattern.items.length),
-        /Index out of range\./);
-
-      Assert.throws(() => actual.removeValueAt(pattern.items.length, true),
-        /Index out of range\./);
-    }
-  });
-});
--- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini
+++ b/toolkit/components/passwordmgr/test/unit/xpcshell.ini
@@ -26,17 +26,16 @@ run-if = buildapp == "browser"
 [test_getPasswordFields.js]
 [test_getPasswordOrigin.js]
 [test_isOriginMatching.js]
 [test_legacy_empty_formSubmitURL.js]
 [test_legacy_validation.js]
 [test_logins_change.js]
 [test_logins_decrypt_failure.js]
 skip-if = os == "android" # Bug 1171687: Needs fixing on Android
-[test_user_autocomplete_result.js]
 [test_logins_metainfo.js]
 [test_logins_search.js]
 [test_notifications.js]
 [test_OSCrypto_win.js]
 skip-if = os != "win"
 [test_recipes_add.js]
 [test_recipes_content.js]
 [test_search_schemeUpgrades.js]
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -211,17 +211,17 @@ nsFormFillController::NodeWillBeDestroye
     mFocusedInput = nullptr;
   }
 }
 
 void
 nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode)
 {
   // Nodes being tracked in mPwmgrInputs will have their observers removed when
-  // they stop being tracked.
+  // they stop being tracked. 
   if (!mPwmgrInputs.Get(aNode)) {
     aNode->RemoveMutationObserver(this);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////
 //// nsIFormFillController
 
@@ -895,17 +895,17 @@ nsFormFillController::RemoveForDocument(
 void
 nsFormFillController::MaybeStartControllingInput(nsIDOMHTMLInputElement* aInput)
 {
   nsCOMPtr<nsINode> inputNode = do_QueryInterface(aInput);
   if (!inputNode)
     return;
 
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aInput);
-  if (!formControl || !formControl->IsSingleLineTextControl(false))
+  if (!formControl || !formControl->IsSingleLineTextControl(true))
     return;
 
   bool isReadOnly = false;
   aInput->GetReadOnly(&isReadOnly);
   if (isReadOnly)
     return;
 
   bool autocomplete = nsContentUtils::IsAutocompleteEnabled(aInput);