Bug 1539677 - Do not highlight the password field when pressing enter on the footer or the insecure field warning. r=MattN
authorprathiksha <prathikshaprasadsuman@gmail.com>
Fri, 19 Apr 2019 11:54:32 -0700
changeset 470298 3dec47dd1b9bd55ef81b52d39f18742ecd2c9c05
parent 470297 8f243d93742049295c734a5bd6e252d5a7d67c99
child 470299 33f6d42d7fa92c72b4adb78cf1e6f19932266bf6
push id35894
push userdvarga@mozilla.com
push dateSat, 20 Apr 2019 21:47:58 +0000
treeherdermozilla-central@72be82c6809e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1539677
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1539677 - Do not highlight the password field when pressing enter on the footer or the insecure field warning. r=MattN Differential Revision: https://phabricator.services.mozilla.com/D27405
browser/extensions/formautofill/test/mochitest/formautofill_common.js
browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html
toolkit/components/autocomplete/nsAutoCompleteController.cpp
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html
toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html
--- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js
@@ -112,18 +112,19 @@ function checkFieldValue(elem, expectedV
   is(elem.value, String(expectedValue), "Checking " + elem.id + " field");
 }
 
 function triggerAutofillAndCheckProfile(profile) {
   const adaptedProfile = _getAdaptedProfile(profile);
   const promises = [];
 
   for (const [fieldName, value] of Object.entries(adaptedProfile)) {
+    info(`triggerAutofillAndCheckProfile: ${fieldName}`);
     const element = document.getElementById(fieldName);
-    const expectingEvent = document.activeElement == element ? "DOMAutoComplete" : "change";
+    const expectingEvent = document.activeElement == element ? "input" : "change";
     const checkFieldAutofilled = Promise.all([
       new Promise(resolve => element.addEventListener("input", (event) => {
         if (element.tagName == "INPUT" && element.type == "text") {
           ok(event instanceof InputEvent,
              `"input" event should be dispatched with InputEvent interface on ${element.tagName}`);
           is(event.inputType, "insertReplacementText",
              "inputType value should be \"insertReplacementText\"");
           is(event.data, String(value),
--- a/browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html
+++ b/browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html
@@ -75,17 +75,17 @@ function checkElementFilled(element, exp
         resolve();
       }, {once: true});
     }),
   ];
 }
 
 function checkAutoCompleteInputFilled(element, expectedvalue) {
   return new Promise(resolve => {
-    element.addEventListener("DOMAutoComplete", function onChange() {
+    element.addEventListener("input", function onInput() {
       is(element.value, expectedvalue, "Checking " + element.name + " field");
       resolve();
     }, {once: true});
   });
 }
 
 function checkFormFilled(selector, address) {
   info("expecting form filled");
@@ -120,49 +120,49 @@ add_task(async function setup() {
   // without `supportedCountries` allowing Canada
   await SpecialPowers.pushPrefEnv({"set": [["extensions.formautofill.supportedCountries", "US,CA"]]});
 
   await setupAddressStorage();
 });
 
 // Autofill the address with address level 1 code.
 add_task(async function autofill_with_level1_code() {
-  await setInput("#organization-en", "Mozilla Toronto");
+  await setInput("#organization-en", "Mozilla Toront");
   synthesizeKey("KEY_ArrowDown");
   await expectPopup();
 
   synthesizeKey("KEY_ArrowDown");
   // Replace address level 1 code with full name in English for test result
   let result = Object.assign({}, MOCK_STORAGE[1], {"address-level1": "Ontario"});
   await checkFormFilled("#form-en", result);
 
-  await setInput("#organization-fr", "Mozilla Vancouver");
+  await setInput("#organization-fr", "Mozilla Vancouve");
   synthesizeKey("KEY_ArrowDown");
   await expectPopup();
 
   synthesizeKey("KEY_ArrowDown");
   // Replace address level 1 code with full name in French for test result
   result = Object.assign({}, MOCK_STORAGE[0], {"address-level1": "Colombie-Britannique"});
   await checkFormFilled("#form-fr", result);
   document.querySelector("#form-en").reset();
   document.querySelector("#form-fr").reset();
 });
 
 // Autofill the address with address level 1 full name.
 add_task(async function autofill_with_level1_full_name() {
-  await setInput("#organization-en", "ExpoCité");
+  await setInput("#organization-en", "ExpoCit");
   synthesizeKey("KEY_ArrowDown");
   await expectPopup();
 
   synthesizeKey("KEY_ArrowDown");
   // Replace address level 1 code with full name in French for test result
   let result = Object.assign({}, MOCK_STORAGE[3], {"address-level1": "Quebec"});
   await checkFormFilled("#form-en", result);
 
-  await setInput("#organization-fr", "Prince of Wales Northern Heritage");
+  await setInput("#organization-fr", "Prince of Wales");
   synthesizeKey("KEY_ArrowDown");
   await expectPopup();
 
   synthesizeKey("KEY_ArrowDown");
   // Replace address level 1 code with full name in English for test result
   result = Object.assign({}, MOCK_STORAGE[2], {"address-level1": "Territoires du Nord-Ouest"});
   await checkFormFilled("#form-fr", result);
 });
--- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp
+++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp
@@ -1268,17 +1268,17 @@ nsresult nsAutoCompleteController::Enter
     input->SelectTextRange(value.Length(), value.Length());
     SetSearchStringInternal(value);
   }
 
   obsSvc->NotifyObservers(input, "autocomplete-did-enter-text", nullptr);
   ClosePopup();
 
   bool cancel;
-  bool itemWasSelected = selectedIndex >= 0;
+  bool itemWasSelected = selectedIndex >= 0 && !value.IsEmpty();
   input->OnTextEntered(aEvent, itemWasSelected, &cancel);
 
   return NS_OK;
 }
 
 nsresult nsAutoCompleteController::RevertTextValue() {
   // StopSearch() can call PostSearchCleanup() which might result
   // in a blur event, which could null out mInput, so we need to check it
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -22,16 +22,19 @@ support-files =
   ../authenticate.sjs
 skip-if = toolkit == 'android' && !is_fennec # Don't run on GeckoView
 
 # Note: new tests should use scheme = https unless they have a specific reason not to
 
 [test_autocomplete_highlight.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
+[test_autocomplete_highlight_non_login.html]
+scheme = https
+skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_https_upgrade.html]
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_password_open.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_sandboxed.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
--- a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html
@@ -100,13 +100,16 @@ add_task(async function test_field_highl
   // Clear existing highlight on the password field. We check by pressing the tab key after backspace
   // (by shifting focus to the next element) because the tab key was known to cause a bug where the
   // highlight is applied once again. See Bug 1526522.
   synthesizeKey("KEY_Backspace");
   synthesizeKey("KEY_Tab");
 
   is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
      "Highlight was successfully removed on the password field");
+
+  // Clear login fields.
+  username.value = "";
+  password.value = "";
 });
 </script>
 </body>
 </html>
-
copy from toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html
copy to toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html
--- a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html
@@ -5,108 +5,117 @@
   <title>Test form field autofill highlight</title>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <script src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="text/javascript" src="../../../satchel/test/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>
 <script>
+SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected field highlight to occur");
 let readyPromise = registerRunTests();
 
 runInParent(function initLogins() {
   const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
   let login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]
                         .createInstance(Ci.nsILoginInfo);
-  login1.init("https://example.com", "https://autocomplete", null,
+  login1.init("http://example.com", "http://autocomplete", null,
               "user1", "pass1", "", "");
 
   let login2 = Cc["@mozilla.org/login-manager/loginInfo;1"]
                         .createInstance(Ci.nsILoginInfo);
-  login2.init("https://example.com", "https://autocomplete", null,
+  login2.init("http://example.com", "http://autocomplete", null,
               "user2", "pass2", "", "");
 
   Services.logins.addLogin(login1);
   Services.logins.addLogin(login2);
 });
 
 </script>
 <body>
 <p id="display"></p>
 <div id="content">
-  <form id="form1" action="https://autocomplete" onsubmit="return false;">
+  <form id="form1" action="http://autocomplete" onsubmit="return false;">
     <input  type="text"       id="uname">
     <input  type="password"   id="pword">
     <button type="submit">Submit</button>
   </form>
 <pre id="test">
 <script>
-let {ContentTaskUtils} = SpecialPowers.Cu.import("resource://testing-common/ContentTaskUtils.jsm", {});
+let username = document.getElementById("uname");
+let password = document.getElementById("pword");
 
 add_task(async function setup() {
   ok(readyPromise, "check promise is available");
   await readyPromise;
+
+  await SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", true]]});
+});
+
+add_task(async function test_field_highlight_on_pw_field_autocomplete_insecureWarning() {
+  // Press enter on insecure warning and check.
+  password.focus();
+  let shownPromise = promiseACShown();
+  synthesizeKey("KEY_ArrowDown"); // open popup
+  await shownPromise;
+  synthesizeKey("KEY_ArrowDown"); // insecure warning
+  synthesizeKey("KEY_Enter");
+
+  await new Promise(resolve => setTimeout(resolve, 1000));
+  is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the password field if enter key is pressed on the insecure warning item");
+  is(document.defaultView.getComputedStyle(username).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the username field if enter key is pressed on the insecure warning item");
+
+  // Press tab on insecure warning and check.
+  password.focus();
+  shownPromise = promiseACShown();
+  synthesizeKey("KEY_ArrowDown"); // open popup
+  await shownPromise;
+  synthesizeKey("KEY_ArrowDown"); // insecure warning
+  synthesizeKey("KEY_Tab");
+
+  await new Promise(resolve => setTimeout(resolve, 1000));
+  is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the password field if tab key is pressed on the insecure warning item");
+  is(document.defaultView.getComputedStyle(username).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the username field if tab key is pressed on the insecure warning item");
 });
 
-add_task(async function test_field_highlight_on_autocomplete() {
-  // Test username autocomplete.
-  let username = document.getElementById("uname");
-  let password = document.getElementById("pword");
-
-  username.focus();
-
+add_task(async function test_field_highlight_on_pw_field_autocomplete_footer() {
+  // Press enter on the footer and check.
+  password.focus();
   let shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
+  synthesizeKey("KEY_ArrowDown"); // open popup
   await shownPromise;
-  synthesizeKey("KEY_ArrowDown");
-  await synthesizeKey("KEY_Enter");
-
-  await ContentTaskUtils.waitForCondition(() => {
-    return document.defaultView.getComputedStyle(username).getPropertyValue("filter") !== "none";
-  }, "Highlight was successfully applied to the username field on username autocomplete");
-
-  isnot(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
-        "Highlight was successfully applied to the password field on username autocomplete");
+  synthesizeKey("KEY_ArrowUp"); // footer
+  synthesizeKey("KEY_Enter");
 
-  // Clear existing highlight on login fields. We check by pressing the tab key after backspace
-  // (by shifting focus to the next element) because the tab key was known to cause a bug where the
-  // highlight is applied once again. See Bug 1526522.
-  username.focus();
-  synthesizeKey("KEY_Backspace");
-  synthesizeKey("KEY_Tab");
+  await new Promise(resolve => setTimeout(resolve, 1000));
+  is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the password field if enter key is pressed on the footer item");
   is(document.defaultView.getComputedStyle(username).getPropertyValue("filter"), "none",
-     "Highlight was successfully removed on the username field");
+     "Highlight is not applied to the username field if enter key is pressed on the footer item");
 
-  synthesizeKey("KEY_Backspace");
-  synthesizeKey("KEY_Tab");
-  is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
-     "Highlight was successfully removed on the password field");
+  runInParent(function cleanUpWindow() {
+    const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+    let window = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
+    window.close();
+  });
 
-  // Clear login fields.
-  username.value = "";
-  password.value = "";
-
-  // Test password field autocomplete.
+  // Press tab on the footer and check.
   password.focus();
   shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown");
+  synthesizeKey("KEY_ArrowDown"); // open popup
   await shownPromise;
-  synthesizeKey("KEY_ArrowDown");
-  synthesizeKey("KEY_Enter");
-
-  await ContentTaskUtils.waitForCondition(() => {
-    return document.defaultView.getComputedStyle(password).getPropertyValue("filter") !== "none";
-  }, "Highlight was successfully applied to the password field on password autocomplete");
-
-  // Clear existing highlight on the password field. We check by pressing the tab key after backspace
-  // (by shifting focus to the next element) because the tab key was known to cause a bug where the
-  // highlight is applied once again. See Bug 1526522.
-  synthesizeKey("KEY_Backspace");
+  synthesizeKey("KEY_ArrowUp"); // footer
   synthesizeKey("KEY_Tab");
 
+  await new Promise(resolve => setTimeout(resolve, 1000));
   is(document.defaultView.getComputedStyle(password).getPropertyValue("filter"), "none",
-     "Highlight was successfully removed on the password field");
+     "Highlight is not applied to the password field if tab key is pressed on the footer item");
+  is(document.defaultView.getComputedStyle(username).getPropertyValue("filter"), "none",
+     "Highlight is not applied to the username field if tab key is pressed on the insecure warning item");
 });
 </script>
 </body>
 </html>
-