Bug 1317284 - Fix the intermittent failed in test_password_field_autocomplete.html.; r?MattN draft
authorSean Lee <selee@mozilla.com>
Tue, 15 Nov 2016 13:58:19 +0800
changeset 457377 53339f77ae03b228073dd0faa94c89340789095a
parent 457371 e9d16569a7b4518e3a90a0512128b838118dea55
child 541445 31c8f67d283d24be96658ca3562ad3f3cb0af2cc
push id40735
push userbmo:selee@mozilla.com
push dateSat, 07 Jan 2017 16:52:37 +0000
reviewersMattN
bugs1317284
milestone53.0a1
Bug 1317284 - Fix the intermittent failed in test_password_field_autocomplete.html.; r?MattN MozReview-Commit-ID: 8vBb2QZvX7T
toolkit/components/passwordmgr/LoginManagerContent.jsm
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1230,86 +1230,73 @@ var LoginUtils = {
       uriString = form.baseURI; // ala bug 297761
 
     return this._getPasswordOrigin(uriString, true);
   },
 };
 
 // nsIAutoCompleteResult implementation
 function UserAutoCompleteResult(aSearchString, matchingLogins, {isSecure, messageManager, isPasswordField}) {
+  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;
+  }
+
+  this._showInsecureFieldWarning = (!isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
   this.searchString = aSearchString;
-
+  this.logins = matchingLogins.sort(loginSort);
+  this.matchCount = matchingLogins.length + this._showInsecureFieldWarning;
+  this._messageManager = messageManager;
   this._stringBundle = Services.strings.createBundle("chrome://passwordmgr/locale/passwordmgr.properties");
   this._dateAndTimeFormatter = new Intl.DateTimeFormat(undefined,
                               { day: "numeric", month: "short", year: "numeric" });
 
-  this._messageManager = messageManager;
-  this._matchingLogins = matchingLogins;
   this._isPasswordField = isPasswordField;
-  this._isSecure = isSecure;
+
+  this._duplicateUsernames = findDuplicates(matchingLogins);
 
-  Services.prefs.addObserver("security.insecure_field_warning.contextual.enabled",
-                             this.updateWithPrefChange.bind(this), false);
-
-  Services.prefs.addObserver("signon.autofillForms.http",
-                             this.updateWithPrefChange.bind(this), false);
-
-  this.updateWithPrefChange();
+  if (this.matchCount > 0) {
+    this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
+    this.defaultIndex = 0;
+  }
 }
 
 UserAutoCompleteResult.prototype = {
   QueryInterface : XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult,
                                           Ci.nsISupportsWeakReference]),
 
   // private
   logins : null,
 
   // Allow autoCompleteSearch to get at the JS object so it can
   // modify some readonly properties for internal use.
   get wrappedJSObject() {
     return this;
   },
 
-  updateWithPrefChange() {
-    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;
-    }
-
-    this._showInsecureFieldWarning = (!this._isSecure && LoginHelper.showInsecureFieldWarning) ? 1 : 0;
-    this.logins = this._matchingLogins.sort(loginSort);
-    this.matchCount = this._matchingLogins.length + this._showInsecureFieldWarning;
-    this._duplicateUsernames = findDuplicates(this._matchingLogins);
-
-    if (this.matchCount > 0) {
-      this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
-      this.defaultIndex = 0;
-    }
-  },
-
   // Interfaces from idl...
   searchString : null,
   searchResult : Ci.nsIAutoCompleteResult.RESULT_NOMATCH,
   defaultIndex : -1,
   errorDescription : "",
   matchCount : 0,
 
   getValueAt(index) {
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -26,17 +26,17 @@ skip-if = toolkit == 'android' # autocom
 [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' || os == 'linux' # android:autocomplete., bug 1317284
+skip-if = toolkit == 'android' # android:autocomplete.
 [test_insecure_form_field_no_saved_login.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]
--- a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
@@ -96,27 +96,37 @@ var setupScript = runInParent(function s
 
 /** 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) {
+function* reinitializeForm(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;
+
+  yield new Promise(resolve => {
+    let observer = SpecialPowers.wrapCallback(() => {
+      SpecialPowers.removeObserver(observer, "passwordmgr-processed-form");
+      resolve();
+    });
+    SpecialPowers.addObserver(observer, "passwordmgr-processed-form", false);
+  });
+
+  yield SimpleTest.promiseFocus(window);
+
   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" });
@@ -143,26 +153,49 @@ add_task(function* test_form1_initial_em
   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_form2_password_readonly() {
+  yield SpecialPowers.pushPrefEnv({"set": [
+                                            ["security.insecure_field_warning.contextual.enabled", true],
+                                            ["signon.autofillForms.http", true]
+                                          ]});
+  yield reinitializeForm(2);
+
+  // Trigger autocomplete popup
+  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() {
+  yield SpecialPowers.pushPrefEnv({"set": [
+                                            ["security.insecure_field_warning.contextual.enabled", true],
+                                            ["signon.autofillForms.http", true]
+                                          ]});
+  yield reinitializeForm(3);
+
+  // Trigger autocomplete popup
+  doKey("down"); // open
+  let popupState = yield getPopupState();
+  is(popupState.open, false, "Check popup is closed for a disabled field.");
+});
+
 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);
+  yield reinitializeForm(1);
   // Trigger autocomplete popup
-  is(SpecialPowers.getBoolPref("security.insecure_field_warning.contextual.enabled"), true, "verify pref security.insecure_field_warning.contextual.enabled");
-  is(SpecialPowers.getBoolPref("signon.autofillForms.http"), true, "verify pref signon.autofillForms.http");
   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.",
@@ -180,21 +213,19 @@ add_task(function* test_form1_enabledIns
   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);
+  yield reinitializeForm(1);
+
   // Trigger autocomplete popup
-  is(SpecialPowers.getBoolPref("security.insecure_field_warning.contextual.enabled"), false, "verify pref security.insecure_field_warning.contextual.enabled");
-  is(SpecialPowers.getBoolPref("signon.autofillForms.http"), true, "verify pref signon.autofillForms.http");
   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 + ")",
@@ -211,21 +242,19 @@ add_task(function* test_form1_disabledIn
   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);
+  yield reinitializeForm(1);
+
   // Trigger autocomplete popup
-  is(SpecialPowers.getBoolPref("security.insecure_field_warning.contextual.enabled"), true, "verify pref security.insecure_field_warning.contextual.enabled");
-  is(SpecialPowers.getBoolPref("signon.autofillForms.http"), false, "verify pref signon.autofillForms.http");
   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.",
@@ -243,38 +272,20 @@ add_task(function* test_form1_enabledIns
   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);
+  yield reinitializeForm(1);
+
   // Trigger autocomplete popup
-  is(SpecialPowers.getBoolPref("security.insecure_field_warning.contextual.enabled"), false, "verify pref security.insecure_field_warning.contextual.enabled");
-  is(SpecialPowers.getBoolPref("signon.autofillForms.http"), false, "verify pref signon.autofillForms.http");
   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>