Backed out 3 changesets (bug 1388674) for mochitest failures e.g browser_doorhanger_toggles.js on a CLOSED TREE.
authorGurzau Raul <rgurzau@mozilla.com>
Tue, 19 Nov 2019 03:58:50 +0200
changeset 502523 dbb0fff9e65ce321b9bf2a7df7edb78cdc4288e2
parent 502522 841580134756b1671f056a4e1e7d847436ea3aa5
child 502524 d214c50eaa95b59f120c7f1a499ca2be8a0b3020
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1388674
milestone72.0a1
backs out09e3e82fb4396ae250cc5e92c7af8447ff5a5683
5caf9e9337388ac29a786e9600a6af240bb00275
ee452cb16fac66c1f5011cef8435f7e2b3e83502
Backed out 3 changesets (bug 1388674) for mochitest failures e.g browser_doorhanger_toggles.js on a CLOSED TREE. Backed out changeset 09e3e82fb439 (bug 1388674) Backed out changeset 5caf9e933738 (bug 1388674) Backed out changeset ee452cb16fac (bug 1388674)
modules/libpref/init/all.js
toolkit/components/passwordmgr/LoginHelper.jsm
toolkit/components/passwordmgr/LoginManagerChild.jsm
toolkit/components/passwordmgr/test/browser/browser_doorhanger_crossframe.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_dismissed_for_ccnumber.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_empty_password.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_password_edits.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_save_password.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_toggles.js
toolkit/components/passwordmgr/test/browser/browser_doorhanger_username_edits.js
toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js
toolkit/components/passwordmgr/test/browser/head.js
toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html
toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html
toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html
toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
toolkit/components/passwordmgr/test/mochitest/test_munged_username.html
toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html
toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html
toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3882,17 +3882,16 @@ pref("signon.autofillForms",            
 pref("signon.autofillForms.autocompleteOff", true);
 pref("signon.autofillForms.http",           false);
 pref("signon.autologin.proxy",              false);
 pref("signon.formlessCapture.enabled",      true);
 pref("signon.generation.available",         false);
 pref("signon.generation.enabled",           false);
 pref("signon.privateBrowsingCapture.enabled", false);
 pref("signon.storeWhenAutocompleteOff",     true);
-pref("signon.userInputRequiredToCapture.enabled", true);
 pref("signon.debug",                        false);
 pref("signon.recipes.path",                 "chrome://passwordmgr/content/recipes.json");
 pref("signon.schemeUpgrades",               false);
 pref("signon.includeOtherSubdomainsInLookup", false);
 // This temporarily prevents the master password to reprompt for autocomplete.
 pref("signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
 pref("signon.showAutoCompleteFooter", false);
 pref("signon.showAutoCompleteOrigins", false);
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -77,19 +77,16 @@ this.LoginHelper = {
     );
     this.schemeUpgrades = Services.prefs.getBoolPref("signon.schemeUpgrades");
     this.showAutoCompleteFooter = Services.prefs.getBoolPref(
       "signon.showAutoCompleteFooter"
     );
     this.storeWhenAutocompleteOff = Services.prefs.getBoolPref(
       "signon.storeWhenAutocompleteOff"
     );
-    this.userInputRequiredToCapture = Services.prefs.getBoolPref(
-      "signon.userInputRequiredToCapture.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.
--- a/toolkit/components/passwordmgr/LoginManagerChild.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerChild.jsm
@@ -211,81 +211,59 @@ const observer = {
     if (!aEvent.isTrusted) {
       return;
     }
 
     if (!LoginHelper.enabled) {
       return;
     }
 
-    let ownerDocument = aEvent.target.ownerDocument;
-    let window = ownerDocument.defaultView;
-    let docState = LoginManagerChild.forWindow(window).stateForDocument(
-      ownerDocument
-    );
+    let window = aEvent.target.ownerDocument.defaultView;
 
     switch (aEvent.type) {
       // Used to mask fields with filled generated passwords when blurred.
       case "blur": {
-        if (docState.generatedPasswordFields.has(aEvent.target)) {
-          let unmask = false;
-          LoginManagerChild.forWindow(window)._togglePasswordFieldMasking(
-            aEvent.target,
-            unmask
-          );
-        }
+        let unmask = false;
+        LoginManagerChild.forWindow(window)._togglePasswordFieldMasking(
+          aEvent.target,
+          unmask
+        );
         break;
       }
 
       // Used to watch for changes to fields filled with generated passwords.
       case "change": {
-        if (docState.generatedPasswordFields.has(aEvent.target)) {
-          LoginManagerChild.forWindow(window)._generatedPasswordFilledOrEdited(
-            aEvent.target
-          );
-        }
+        LoginManagerChild.forWindow(window)._generatedPasswordFilledOrEdited(
+          aEvent.target
+        );
         break;
       }
 
       // Used to watch for changes to fields filled with generated passwords.
       case "input": {
-        let field = aEvent.target;
-        if (docState.generatedPasswordFields.has(field)) {
-          LoginManagerChild.forWindow(
-            window
-          )._maybeStopTreatingAsGeneratedPasswordField(aEvent);
-        }
-        if (
-          field.hasBeenTypePassword ||
-          LoginHelper.isUsernameFieldType(field)
-        ) {
-          // flag this form as user-modified
-          let formLikeRoot = FormLikeFactory.findRootForField(field);
-          docState.fieldModificationsByRootElement.set(formLikeRoot, true);
-        }
+        LoginManagerChild.forWindow(
+          window
+        )._maybeStopTreatingAsGeneratedPasswordField(aEvent);
         break;
       }
 
       case "keydown": {
         if (
           aEvent.keyCode == aEvent.DOM_VK_TAB ||
           aEvent.keyCode == aEvent.DOM_VK_RETURN
         ) {
           LoginManagerChild.forWindow(window).onUsernameAutocompleted(
             aEvent.target
           );
         }
         break;
       }
 
       case "focus": {
-        if (
-          aEvent.target.type == "password" &&
-          docState.generatedPasswordFields.has(aEvent.target)
-        ) {
+        if (aEvent.target.type == "password") {
           // Used to unmask fields with filled generated passwords when focused.
           let unmask = true;
           LoginManagerChild.forWindow(window)._togglePasswordFieldMasking(
             aEvent.target,
             unmask
           );
           break;
         }
@@ -874,22 +852,16 @@ this.LoginManagerChild = class LoginMana
    *
    * @param {LoginForm} form to fetch the logins for then try autofill.
    */
   _fetchLoginsFromParentAndFillForm(form) {
     if (!LoginHelper.enabled) {
       return;
     }
 
-    // set up input event listeners so we know if the user has interacted with these fields
-    form.rootElement.addEventListener("input", observer, {
-      capture: true,
-      mozSystemGroup: true,
-    });
-
     this._getLoginDataFromParent(form, { showMasterPassword: true })
       .then(this.loginsFound.bind(this))
       .catch(Cu.reportError);
   }
 
   /**
    * Retrieves a reference to the state object associated with the given
    * document. This is initialized to an object with default values.
@@ -898,24 +870,19 @@ this.LoginManagerChild = class LoginMana
     let loginFormState = this._loginFormStateByDocument.get(document);
     if (!loginFormState) {
       loginFormState = {
         /**
          * Keeps track of filled fields and values.
          */
         fillsByRootElement: new WeakMap(),
         /**
-         * Keeps track of fields we've filled with generated passwords
-         */
-        generatedPasswordFields: new WeakSet(),
-        /**
          * Keeps track of logins that were last submitted.
          */
         lastSubmittedValuesByRootElement: new WeakMap(),
-        fieldModificationsByRootElement: new WeakMap(),
         loginFormRootElements: new WeakSet(),
       };
       this._loginFormStateByDocument.set(document, loginFormState);
     }
     return loginFormState;
   }
 
   /**
@@ -1568,27 +1535,19 @@ this.LoginManagerChild = class LoginMana
       )
     ) {
       log(
         "(form submission ignored -- already submitted with the same username and password)"
       );
       return;
     }
 
-    let docState = this.stateForDocument(doc);
-    let fieldsModified = this._formHasModifiedFields(formLikeRoot);
-    if (!fieldsModified && LoginHelper.userInputRequiredToCapture) {
-      // we know no fields in this form had user modifications, so don't prompt
-      log(
-        "(form submission ignored -- submitting values that are not changed by the user)"
-      );
-      return;
-    }
-
-    let autoFilledLogin = docState.fillsByRootElement.get(form.rootElement);
+    let autoFilledLogin = this.stateForDocument(doc).fillsByRootElement.get(
+      form.rootElement
+    );
 
     let detail = {
       origin,
       formActionOrigin,
       autoFilledLoginGuid: autoFilledLogin && autoFilledLogin.guid,
       usernameField: mockUsername,
       newPasswordField: mockPassword,
       oldPasswordField: mockOldPassword,
@@ -1611,20 +1570,16 @@ this.LoginManagerChild = class LoginMana
     if (!value || (event.data && event.data == value)) {
       this._stopTreatingAsGeneratedPasswordField(passwordField);
     }
   }
 
   _stopTreatingAsGeneratedPasswordField(passwordField) {
     log("_stopTreatingAsGeneratedPasswordField");
 
-    let fields = this.stateForDocument(passwordField.ownerDocument)
-      .generatedPasswordFields;
-    fields.delete(passwordField);
-
     // Remove all the event listeners added in _generatedPasswordFilledOrEdited
     for (let eventType of ["blur", "change", "focus", "input"]) {
       passwordField.removeEventListener(eventType, observer, {
         capture: true,
         mozSystemGroup: true,
       });
     }
 
@@ -1643,18 +1598,16 @@ this.LoginManagerChild = class LoginMana
     if (!LoginHelper.enabled) {
       throw new Error(
         "A generated password was filled while the password manager was disabled."
       );
     }
 
     let win = passwordField.ownerGlobal;
     let formLikeRoot = FormLikeFactory.findRootForField(passwordField);
-    let docState = this.stateForDocument(passwordField.ownerDocument);
-    docState.generatedPasswordFields.add(passwordField);
 
     this._highlightFilledField(passwordField);
 
     // change: Listen for changes to the field filled with the generated password so we can preserve edits.
     // input: Listen for the field getting blanked (without blurring) or a paste
     for (let eventType of ["blur", "change", "focus", "input"]) {
       passwordField.addEventListener(eventType, observer, {
         capture: true,
@@ -1835,16 +1788,17 @@ this.LoginManagerChild = class LoginMana
       userTriggered = false,
     } = {}
   ) {
     if (ChromeUtils.getClassName(form) === "HTMLFormElement") {
       throw new Error("_fillForm should only be called with LoginForm objects");
     }
 
     log("_fillForm", form.elements);
+    let usernameField;
     // Will be set to one of AUTOFILL_RESULT in the `try` block.
     let autofillResult = -1;
     const AUTOFILL_RESULT = {
       FILLED: 0,
       NO_PASSWORD_FIELD: 1,
       PASSWORD_DISABLED_READONLY: 2,
       NO_LOGINS_FIT: 3,
       NO_SAVED_LOGINS: 4,
@@ -1852,40 +1806,41 @@ this.LoginManagerChild = class LoginMana
       EXISTING_USERNAME: 6,
       MULTIPLE_LOGINS: 7,
       NO_AUTOFILL_FORMS: 8,
       AUTOCOMPLETE_OFF: 9,
       INSECURE: 10,
       PASSWORD_AUTOCOMPLETE_NEW_PASSWORD: 11,
     };
 
-    // Heuristically determine what the user/pass fields are
-    // We do this before checking to see if logins are stored,
-    // so that the user isn't prompted for a master password
-    // without need.
-    let [usernameField, passwordField] = this._getFormFields(
-      form,
-      false,
-      recipes
-    );
-
     try {
       // Nothing to do if we have no matching (excluding form action
       // checks) logins available, and there isn't a need to show
       // the insecure form warning.
       if (
         !foundLogins.length &&
         (InsecurePasswordUtils.isFormSecure(form) ||
           !LoginHelper.showInsecureFieldWarning)
       ) {
         // We don't log() here since this is a very common case.
         autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
         return;
       }
 
+      // Heuristically determine what the user/pass fields are
+      // We do this before checking to see if logins are stored,
+      // so that the user isn't prompted for a master password
+      // without need.
+      let passwordField;
+      [usernameField, passwordField] = this._getFormFields(
+        form,
+        false,
+        recipes
+      );
+
       // If we have a password inputElement parameter and it's not
       // the same as the one heuristically found, use the parameter
       // one instead.
       if (inputElement) {
         if (inputElement.type == "password") {
           passwordField = inputElement;
           if (!clobberUsername) {
             usernameField = null;
@@ -2168,24 +2123,16 @@ this.LoginManagerChild = class LoginMana
       }
 
       this.sendAsyncMessage("PasswordManager:formProcessed", {
         formid: form.rootElement.id,
       });
     }
   }
 
-  _formHasModifiedFields(formLikeRoot) {
-    let state = this.stateForDocument(formLikeRoot.ownerDocument);
-    let fieldsModified = state.fieldModificationsByRootElement.get(
-      formLikeRoot
-    );
-    return fieldsModified;
-  }
-
   /**
    * Given a field, determine whether that field was last filled as a username
    * field AND whether the username is still filled in with the username AND
    * whether the associated password field has the matching password.
    *
    * @note This could possibly be unified with getFieldContext but they have
    * slightly different use cases. getFieldContext looks up recipes whereas this
    * method doesn't need to since it's only returning a boolean based upon the
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_crossframe.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_crossframe.js
@@ -91,24 +91,24 @@ async function submitSomeCrossSiteFrames
 
   // Fill in the username and password for both the outer and inner frame
   // and submit the inner frame.
   notifyPromise = listenForNotifications(1);
   info("submit page after changing inner form");
 
   await SpecialPowers.spawn(outerFrameBC, [], () => {
     let doc = content.document;
-    doc.getElementById("outer-username").setUserInput("outer");
-    doc.getElementById("outer-password").setUserInput("outerpass");
+    doc.getElementById("outer-username").value = "outer";
+    doc.getElementById("outer-password").value = "outerpass";
   });
 
   await SpecialPowers.spawn(innerFrameBC, [locationMode], doClick => {
     let doc = content.document;
-    doc.getElementById("inner-username").setUserInput("inner");
-    doc.getElementById("inner-password").setUserInput("innerpass");
+    doc.getElementById("inner-username").value = "inner";
+    doc.getElementById("inner-password").value = "innerpass";
     if (doClick) {
       doc.getElementById("inner-gobutton").click();
     } else {
       doc.getElementById("inner-form").submit();
     }
   });
 
   await acceptPasswordSave();
@@ -133,18 +133,18 @@ async function submitSomeCrossSiteFrames
   await checkFormFields(innerFrameBC2, "inner", "inner", "innerpass");
 
   // Next, change the username and password fields in the outer frame and submit.
   notifyPromise = listenForNotifications(1);
   info("submit page after changing outer form");
 
   await SpecialPowers.spawn(outerFrameBC2, [locationMode], doClick => {
     let doc = content.document;
-    doc.getElementById("outer-username").setUserInput("outer2");
-    doc.getElementById("outer-password").setUserInput("outerpass2");
+    doc.getElementById("outer-username").value = "outer2";
+    doc.getElementById("outer-password").value = "outerpass2";
     if (doClick) {
       doc.getElementById("outer-gobutton").click();
     } else {
       doc.getElementById("outer-form").submit();
     }
 
     doc.getElementById("outer-form").submit();
   });
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_dismissed_for_ccnumber.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_dismissed_for_ccnumber.js
@@ -80,22 +80,20 @@ add_task(async function test_doorhanger_
       url,
     },
     async function test_un_with_invalid_cc_number(browser) {
       // If the username field has a CC number that is invalid,
       // we show the doorhanger to save logins like we usually do.
 
       let processedPromise = listenForTestNotification("FormSubmit");
       await ContentTask.spawn(browser, null, async () => {
-        content.document
-          .getElementById("form-basic-username")
-          .setUserInput("1234123412341234");
-        content.document
-          .getElementById("form-basic-password")
-          .setUserInput("411");
+        content.document.getElementById("form-basic-username").value =
+          "1234123412341234";
+        content.document.getElementById("form-basic-password").value = "411";
+
         content.document.getElementById("form-basic-submit").click();
       });
       await processedPromise;
 
       let notif = await getCaptureDoorhangerThatMayOpen("password-save");
       ok(notif, "got notification popup");
       ok(
         !notif.dismissed,
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_empty_password.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_empty_password.js
@@ -17,18 +17,18 @@ add_task(async function test_empty_passw
       url:
         "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
     },
     async function(browser) {
       // Submit the form in the content page with the credentials from the test
       // case. This will cause the doorhanger notification to be displayed.
       await ContentTask.spawn(browser, null, async function() {
         let doc = content.document;
-        doc.getElementById("form-basic-username").setUserInput("username");
-        doc.getElementById("form-basic-password").setUserInput("pw");
+        doc.getElementById("form-basic-username").value = "username";
+        doc.getElementById("form-basic-password").value = "pw";
         doc.getElementById("form-basic").submit();
       });
 
       await waitForDoorhanger(browser, "password-save");
       // Synthesize input to empty the field
       await updateDoorhangerInputValues({
         password: "",
       });
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_password_edits.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_password_edits.js
@@ -9,55 +9,47 @@
  *   - Editing username to an empty one and a new password.
  *
  * If both the username and password matches an already existing login, we should not
  * update it's password, but only it's usage timestamp and count.
  */
 add_task(async function test_edit_password() {
   let testCases = [
     {
-      description: "No saved logins, update password in doorhanger",
       usernameInPage: "username",
       passwordInPage: "password",
       passwordChangedTo: "newPassword",
       timesUsed: 1,
     },
     {
-      description: "Login is saved, update password in doorhanger",
       usernameInPage: "username",
       usernameInPageExists: true,
       passwordInPage: "password",
       passwordInStorage: "oldPassword",
       passwordChangedTo: "newPassword",
       timesUsed: 2,
     },
     {
-      description:
-        "Change username in doorhanger to match saved login, update password in doorhanger",
       usernameInPage: "username",
       usernameChangedTo: "newUsername",
       usernameChangedToExists: true,
       passwordInPage: "password",
       passwordChangedTo: "newPassword",
       timesUsed: 2,
     },
     {
-      description:
-        "Change username in doorhanger to match saved login, dont update password in doorhanger",
       usernameInPage: "username",
       usernameChangedTo: "newUsername",
       usernameChangedToExists: true,
       passwordInPage: "password",
       passwordChangedTo: "password",
       timesUsed: 2,
       checkPasswordNotUpdated: true,
     },
     {
-      description:
-        "Change username and password in doorhanger to match saved empty-username login",
       usernameInPage: "newUsername",
       usernameChangedTo: "",
       usernameChangedToExists: true,
       passwordInPage: "password",
       passwordChangedTo: "newPassword",
       timesUsed: 2,
     },
   ];
@@ -102,32 +94,41 @@ add_task(async function test_edit_passwo
           PopupNotifications.panel,
           "popupshown",
           event => event.target == PopupNotifications.panel
         );
         await ContentTask.spawn(browser, testCase, async function(
           contentTestCase
         ) {
           let doc = content.document;
-          doc
-            .getElementById("form-basic-username")
-            .setUserInput(contentTestCase.usernameInPage);
-          doc
-            .getElementById("form-basic-password")
-            .setUserInput(contentTestCase.passwordInPage);
+          doc.getElementById("form-basic-username").value =
+            contentTestCase.usernameInPage;
+          doc.getElementById("form-basic-password").value =
+            contentTestCase.passwordInPage;
           doc.getElementById("form-basic").submit();
         });
         await promiseShown;
         let notificationElement = PopupNotifications.panel.childNodes[0];
+        // Style flush to make sure binding is attached
+        notificationElement.querySelector("#password-notification-password")
+          .clientTop;
 
-        // Modify the username & password in the dialog if requested.
-        await updateDoorhangerInputValues({
-          username: testCase.usernameChangedTo,
-          password: testCase.passwordChangedTo,
-        });
+        // Modify the username in the dialog if requested.
+        if (testCase.usernameChangedTo) {
+          notificationElement.querySelector(
+            "#password-notification-username"
+          ).value = testCase.usernameChangedTo;
+        }
+
+        // Modify the password in the dialog if requested.
+        if (testCase.passwordChangedTo) {
+          notificationElement.querySelector(
+            "#password-notification-password"
+          ).value = testCase.passwordChangedTo;
+        }
 
         // We expect a modifyLogin notification if the final username used by the
         // dialog exists in the logins database, otherwise an addLogin one.
         let expectModifyLogin =
           typeof testCase.usernameChangedTo !== "undefined"
             ? testCase.usernameChangedToExists
             : testCase.usernameInPageExists;
 
@@ -136,52 +137,42 @@ add_task(async function test_edit_passwo
         // of operation we expect.
         let expectedNotification = expectModifyLogin
           ? "modifyLogin"
           : "addLogin";
         let promiseLogin = TestUtils.topicObserved(
           "passwordmgr-storage-changed",
           (_, data) => data == expectedNotification
         );
-
-        let promiseHidden = BrowserTestUtils.waitForEvent(
-          PopupNotifications.panel,
-          "popuphidden"
-        );
         notificationElement.button.doCommand();
-
         let [result] = await promiseLogin;
-        await promiseHidden;
 
         // Check that the values in the database match the expected values.
         let login = expectModifyLogin
           ? result
               .QueryInterface(Ci.nsIArray)
               .queryElementAt(1, Ci.nsILoginInfo)
           : result.QueryInterface(Ci.nsILoginInfo);
-        let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
 
-        let expectedLogin = {
-          username:
-            "usernameChangedTo" in testCase
-              ? testCase.usernameChangedTo
-              : testCase.usernameInPage,
-          password:
-            "passwordChangedTo" in testCase
-              ? testCase.passwordChangedTo
-              : testCase.passwordInPage,
-          timesUsed: testCase.timesUsed,
-        };
+        Assert.equal(
+          login.username,
+          testCase.usernameChangedTo || testCase.usernameInPage
+        );
+        Assert.equal(
+          login.password,
+          testCase.passwordChangedTo || testCase.passwordInPage
+        );
+
+        let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
+        Assert.equal(meta.timesUsed, testCase.timesUsed);
+
         // Check that the password was not updated if the user is empty
         if (testCase.checkPasswordNotUpdated) {
-          expectedLogin.usedSince = meta.timeCreated;
-          expectedLogin.timeCreated = meta.timePasswordChanged;
+          Assert.ok(meta.timeLastUsed > meta.timeCreated);
+          Assert.ok(meta.timeCreated == meta.timePasswordChanged);
         }
-        verifyLogins([expectedLogin]);
-
-        await cleanupDoorhanger();
       }
     );
 
     // Clean up the database before the next test case is executed.
     Services.logins.removeAllLogins();
   }
 });
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_save_password.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_save_password.js
@@ -88,58 +88,65 @@ add_task(async function test_save_change
         gBrowser,
         url:
           "https://example.com/browser/toolkit/components/" +
           "passwordmgr/test/browser/form_basic.html",
       },
       async function(browser) {
         // Submit the form in the content page with the credentials from the test
         // case. This will cause the doorhanger notification to be displayed.
+        let promiseShown = BrowserTestUtils.waitForEvent(
+          PopupNotifications.panel,
+          "popupshown",
+          event => event.target == PopupNotifications.panel
+        );
         await ContentTask.spawn(browser, [username, password], async function([
           contentUsername,
           contentPassword,
         ]) {
           let doc = content.document;
-          doc
-            .getElementById("form-basic-username")
-            .setUserInput(contentUsername);
-          doc
-            .getElementById("form-basic-password")
-            .setUserInput(contentPassword);
+          doc.getElementById("form-basic-username").value = contentUsername;
+          doc.getElementById("form-basic-password").value = contentPassword;
           doc.getElementById("form-basic").submit();
         });
+        await promiseShown;
+        let notif = PopupNotifications.getNotification("password", browser);
+        let notificationElement = PopupNotifications.panel.childNodes[0];
+        // Style flush to make sure binding is attached
+        notificationElement.querySelector("#password-notification-password")
+          .clientTop;
+
+        // Check the actual content of the popup notification.
+        Assert.equal(
+          notificationElement.querySelector("#password-notification-username")
+            .value,
+          username
+        );
+        Assert.equal(
+          notificationElement.querySelector("#password-notification-password")
+            .value,
+          password
+        );
 
         // Simulate the action on the notification to request the login to be
         // saved, and wait for the data to be updated or saved based on the type
         // of operation we expect.
-        let expectedNotification, expectedDoorhanger;
+        let expectedNotification;
         if (oldPassword !== undefined && oldUsername !== undefined) {
           expectedNotification = "addLogin";
-          expectedDoorhanger = "password-save";
         } else if (oldPassword !== undefined) {
           expectedNotification = "modifyLogin";
-          expectedDoorhanger = "password-change";
         } else {
           expectedNotification = "addLogin";
-          expectedDoorhanger = "password-save";
         }
-
-        let notif = getCaptureDoorhanger(
-          expectedDoorhanger,
-          PopupNotifications,
-          browser
-        );
-        // Check the actual content of the popup notification.
-        await checkDoorhangerUsernamePassword(username, password);
-
         let promiseLogin = TestUtils.topicObserved(
           "passwordmgr-storage-changed",
           (_, data) => data == expectedNotification
         );
-        await clickDoorhangerButton(notif, REMEMBER_BUTTON);
+        notificationElement.button.doCommand();
         await promiseLogin;
         await cleanupDoorhanger(notif); // clean slate for the next test
 
         // Check that the values in the database match the expected values.
         verifyLogins(expectOutcome);
       }
     );
 
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_toggles.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_toggles.js
@@ -13,24 +13,28 @@ add_task(async function test_toggle_pass
     {
       gBrowser,
       url:
         "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
     },
     async function(browser) {
       // Submit the form in the content page with the credentials from the test
       // case. This will cause the doorhanger notification to be displayed.
+      let promiseShown = BrowserTestUtils.waitForEvent(
+        PopupNotifications.panel,
+        "popupshown",
+        event => event.target == PopupNotifications.panel
+      );
       await ContentTask.spawn(browser, null, async function() {
         let doc = content.document;
-        doc.getElementById("form-basic-username").setUserInput("username");
-        doc.getElementById("form-basic-password").setUserInput("pw");
+        doc.getElementById("form-basic-username").value = "username";
+        doc.getElementById("form-basic-password").value = "pw";
         doc.getElementById("form-basic").submit();
       });
-      // Check the actual content of the popup notification.
-      await checkDoorhangerUsernamePassword("username", "pw");
+      await promiseShown;
 
       let notificationElement = PopupNotifications.panel.childNodes[0];
       let passwordTextbox = notificationElement.querySelector(
         "#password-notification-password"
       );
       let toggleCheckbox = notificationElement.querySelector(
         "#password-notification-visibilityToggle"
       );
@@ -63,26 +67,31 @@ add_task(async function test_checkbox_di
     {
       gBrowser,
       url:
         "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
     },
     async function(browser) {
       // Submit the form in the content page with the credentials from the test
       // case. This will cause the doorhanger notification to be displayed.
+      let promiseShown = BrowserTestUtils.waitForEvent(
+        PopupNotifications.panel,
+        "popupshown",
+        event => event.target == PopupNotifications.panel
+      );
+
       LoginTestUtils.masterPassword.enable();
 
       await ContentTask.spawn(browser, null, async function() {
         let doc = content.document;
-        doc.getElementById("form-basic-username").setUserInput("username");
-        doc.getElementById("form-basic-password").setUserInput("pass");
+        doc.getElementById("form-basic-username").value = "username";
+        doc.getElementById("form-basic-password").value = "pass";
         doc.getElementById("form-basic").submit();
       });
-      // Check the actual content of the popup notification.
-      await checkDoorhangerUsernamePassword("username", "pass");
+      await promiseShown;
 
       let notificationElement = PopupNotifications.panel.childNodes[0];
       let passwordTextbox = notificationElement.querySelector(
         "#password-notification-password"
       );
       let toggleCheckbox = notificationElement.querySelector(
         "#password-notification-visibilityToggle"
       );
--- a/toolkit/components/passwordmgr/test/browser/browser_doorhanger_username_edits.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_doorhanger_username_edits.js
@@ -89,34 +89,32 @@ add_task(async function test_edit_userna
           "popupshown",
           event => event.target == PopupNotifications.panel
         );
         await ContentTask.spawn(
           browser,
           testCase.usernameInPage,
           async function(usernameInPage) {
             let doc = content.document;
-            doc
-              .getElementById("form-basic-username")
-              .setUserInput(usernameInPage);
-            doc.getElementById("form-basic-password").setUserInput("password");
+            doc.getElementById("form-basic-username").value = usernameInPage;
+            doc.getElementById("form-basic-password").value = "password";
             doc.getElementById("form-basic").submit();
           }
         );
         await promiseShown;
         let notificationElement = PopupNotifications.panel.childNodes[0];
         // Style flush to make sure binding is attached
         notificationElement.querySelector("#password-notification-password")
           .clientTop;
 
         // Modify the username in the dialog if requested.
         if (testCase.usernameChangedTo) {
-          await updateDoorhangerInputValues({
-            username: testCase.usernameChangedTo,
-          });
+          notificationElement.querySelector(
+            "#password-notification-username"
+          ).value = testCase.usernameChangedTo;
         }
 
         // We expect a modifyLogin notification if the final username used by the
         // dialog exists in the logins database, otherwise an addLogin one.
         let expectModifyLogin = testCase.usernameChangedTo
           ? testCase.usernameChangedToExists
           : testCase.usernameInPageExists;
 
@@ -125,23 +123,18 @@ add_task(async function test_edit_userna
         // of operation we expect.
         let expectedNotification = expectModifyLogin
           ? "modifyLogin"
           : "addLogin";
         let promiseLogin = TestUtils.topicObserved(
           "passwordmgr-storage-changed",
           (_, data) => data == expectedNotification
         );
-        let promiseHidden = BrowserTestUtils.waitForEvent(
-          PopupNotifications.panel,
-          "popuphidden"
-        );
         notificationElement.button.doCommand();
         let [result] = await promiseLogin;
-        await promiseHidden;
 
         // Check that the values in the database match the expected values.
         let login = expectModifyLogin
           ? result
               .QueryInterface(Ci.nsIArray)
               .queryElementAt(1, Ci.nsILoginInfo)
           : result.QueryInterface(Ci.nsILoginInfo);
         Assert.equal(
--- a/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js
@@ -1,22 +1,20 @@
 /*
  * Test that browser chrome UI interactions don't trigger a capture doorhanger.
  */
 
 "use strict";
 
 async function fillTestPage(aBrowser) {
   await ContentTask.spawn(aBrowser, null, async function() {
-    content.document
-      .getElementById("form-basic-username")
-      .setUserInput("my_username");
-    content.document
-      .getElementById("form-basic-password")
-      .setUserInput("my_password");
+    content.document.getElementById("form-basic-username").value =
+      "my_username";
+    content.document.getElementById("form-basic-password").value =
+      "my_password";
   });
   info("fields filled");
 }
 
 function withTestPage(aTaskFn) {
   return BrowserTestUtils.withNewTab(
     {
       gBrowser,
--- a/toolkit/components/passwordmgr/test/browser/head.js
+++ b/toolkit/components/passwordmgr/test/browser/head.js
@@ -83,19 +83,16 @@ function verifyLogins(expectedLogins = [
         ok(login.timeLastUsed > expected.usedSince, "Check timeLastUsed");
       }
       if (typeof expected.passwordChangedSince !== "undefined") {
         ok(
           login.timePasswordChanged > expected.passwordChangedSince,
           "Check timePasswordChanged"
         );
       }
-      if (typeof expected.timeCreated !== "undefined") {
-        is(login.timeCreated, expected.timeCreated, "Check timeCreated");
-      }
     }
   }
   return allLogins;
 }
 
 /**
  * Submit the content form and return a promise resolving to the username and
  * password values echoed out in the response
@@ -106,42 +103,27 @@ function verifyLogins(expectedLogins = [
  * @param {Object = null} responseSelectors - Optional object with selectors to find the username and password in the response
  */
 async function submitFormAndGetResults(
   browser,
   formAction = "",
   selectorValues,
   responseSelectors
 ) {
-  async function contentSubmitForm([contentFormAction, contentSelectorValues]) {
-    const { WrapPrivileged } = ChromeUtils.import(
-      "resource://specialpowers/WrapPrivileged.jsm",
-      this
-    );
+  function contentSubmitForm([contentFormAction, contentSelectorValues]) {
     let doc = content.document;
     let form = doc.querySelector("form");
     if (contentFormAction) {
       form.action = contentFormAction;
     }
     for (let [sel, value] of Object.entries(contentSelectorValues)) {
       try {
-        let field = doc.querySelector(sel);
-        let gotInput = ContentTaskUtils.waitForEvent(
-          field,
-          "input",
-          "Got input event on " + sel
-        );
-        // we don't get an input event if the new value == the old
-        field.value = "###";
-        WrapPrivileged.wrap(field).setUserInput(value);
-        await gotInput;
+        doc.querySelector(sel).setUserInput(value);
       } catch (ex) {
-        throw new Error(
-          `submitForm: Couldn't set value of field at: ${sel}: ${ex.message}`
-        );
+        throw new Error(`submitForm: Couldn't set value of field at: ${sel}`);
       }
     }
     form.submit();
   }
   await ContentTask.spawn(
     browser,
     [formAction, selectorValues],
     contentSubmitForm
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html
@@ -9,18 +9,18 @@
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  userField.value = "notifyu1";
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html
@@ -8,17 +8,17 @@
 <h2>Subtest 10</h2>
 <form id="form" action="formsubmit.sjs">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html
@@ -11,18 +11,18 @@
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
   // Get the password from the query string (exclude '?').
   let [username, password] = window.location.search.substring(1).split("|");
-  SpecialPowers.wrap(userField).setUserInput(username);
-  SpecialPowers.wrap(passField).setUserInput(password);
+  userField.value = username;
+  passField.value = password;
   form.submit();
   window.opener.formSubmitted();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html
@@ -10,18 +10,18 @@
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user" autocomplete="off">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  userField.value = "notifyu1";
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html
@@ -9,17 +9,17 @@
 <form id="form" action="formsubmit.sjs">
   <input id="pass1" name="pass1" type="password" value="staticpw">
   <input id="pass" name="pass" type="password">
   <button type="submit">Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(pass).setUserInput("notifyp1");
+  pass.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var pass      = document.getElementById("pass");
 
 </script>
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html
@@ -11,18 +11,18 @@
   <input id="city"  name="city"  value="city">
   <input id="pass"  name="pass"  type="password">
   <input id="pin"   name="pin"   type="password" value="static-pin">
   <button type="submit">Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  userField.value = "notifyu1";
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html
@@ -10,18 +10,18 @@
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user">
   <input id="pass" name="pass" type="password" autocomplete="off">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  userField.value = "notifyu1";
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html
@@ -10,18 +10,18 @@
 <form id="form" action="formsubmit.sjs" autocomplete="off">
   <input id="user" name="user">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  userField.value = "notifyu1";
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html
@@ -8,17 +8,17 @@
 <h2>Subtest 5</h2>
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
+  userField.value = "notifyu1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 
 </script>
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html
@@ -9,17 +9,17 @@
 (password-only form)
 <form id="form" action="formsubmit.sjs">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(passField).setUserInput("notifyp1");
+  passField.value = "notifyp1";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var passField = document.getElementById("pass");
 
 </script>
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html
@@ -9,18 +9,18 @@
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("notifyu1");
-  SpecialPowers.wrap(passField).setUserInput("pass2");
+  userField.value = "notifyu1";
+  passField.value = "pass2";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html
@@ -9,18 +9,18 @@
 <form id="form" action="formsubmit.sjs">
   <input id="user" name="user">
   <input id="pass" name="pass" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(userField).setUserInput("");
-  SpecialPowers.wrap(passField).setUserInput("pass2");
+  userField.value = "";
+  passField.value = "pass2";
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
 
--- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html
+++ b/toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html
@@ -10,18 +10,18 @@
   <input id="pass_current" name="pass_current" type="password" value="notifyp1">
   <input id="pass" name="pass" type="password">
   <input id="pass_confirm" name="pass_confirm" type="password">
   <button type='submit'>Submit</button>
 </form>
 
 <script>
 function submitForm() {
-  SpecialPowers.wrap(passField).setUserInput("pass2");
-  SpecialPowers.wrap(passConfirmField).setUserInput("pass2");
+  passField.value = "pass2";
+  passConfirmField.value = "pass2";
 
   form.submit();
 }
 
 window.onload = submitForm;
 var form      = document.getElementById("form");
 var userField = document.getElementById("user");
 var passField = document.getElementById("pass");
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -155,15 +155,14 @@ skip-if = e10s || toolkit == 'android' #
 [test_password_length.html]
 scheme = https
 skip-if = toolkit == 'android' # bug 1527403
 [test_prompt_promptAuth.html]
 skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_prompt_promptAuth_proxy.html]
 skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_recipe_login_fields.html]
-[test_submit_without_field_modifications.html]
 [test_username_focus.html]
 skip-if = toolkit == 'android' # android:autocomplete.
 [test_xhr.html]
 skip-if = toolkit == 'android' # Tests desktop prompts
 [test_xhr_2.html]
 
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
@@ -109,67 +109,16 @@ function checkAutoCompleteResults(actual
 }
 
 function getIframeBrowsingContext(window, iframeNumber = 0) {
   let bc = SpecialPowers.wrap(window).getWindowGlobalChild().browsingContext;
   return SpecialPowers.unwrap(bc.getChildren()[iframeNumber]);
 }
 
 /**
- * Set input values via setUserInput to emulate user input
- * and distinguish them from declarative or script-assigned values
- */
-function setUserInputValues(parentNode, selectorValues) {
-  for (let [selector, newValue] of Object.entries(selectorValues)) {
-    info(`setUserInputValues, selector: ${selector}`);
-    try {
-      let field = SpecialPowers.wrap(parentNode.querySelector(selector));
-      if (field.value == newValue) {
-        // we don't get an input event if the new value == the old
-        field.value += "#";
-      }
-      field.setUserInput(newValue);
-    } catch (ex) {
-      info(ex.message);
-      info(ex.stack);
-      ok(
-        false,
-        `setUserInputValues: Couldn't set value of field: ${ex.message}`
-      );
-    }
-  }
-}
-
-/**
- * @param {Function} [aFilterFn = undefined] Function to filter out irrelevant submissions.
- * @return {Promise} resolving when a relevant form submission was processed.
- */
-function getSubmitMessage(aFilterFn = undefined) {
-  info("getSubmitMessage");
-  return new Promise((resolve, reject) => {
-    PWMGR_COMMON_PARENT.addMessageListener(
-      "formSubmissionProcessed",
-      function processed(...args) {
-        if (aFilterFn && !aFilterFn(...args)) {
-          // This submission isn't the one we're waiting for.
-          return;
-        }
-
-        info("got formSubmissionProcessed");
-        PWMGR_COMMON_PARENT.removeMessageListener(
-          "formSubmissionProcessed",
-          processed
-        );
-        resolve(...args);
-      }
-    );
-  });
-}
-
-/**
  * Check for expected username/password in form.
  * @see `checkForm` below for a similar function.
  */
 function checkLoginForm(
   usernameField,
   expectedUsername,
   passwordField,
   expectedPassword
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html
@@ -31,19 +31,19 @@ var numStartingLogins = 0;
 function startTest() {
   // Check for unfilled forms
   is($_(1, "uname").value, "", "Checking username 1");
   is($_(1, "pword").value, "", "Checking password 1A");
   is($_(1, "qword").value, "", "Checking password 1B");
 
   // Fill in the username and password fields, for account creation.
   // Form 1
-  SpecialPowers.wrap($_(1, "uname")).setUserInput("newuser1");
-  SpecialPowers.wrap($_(1, "pword")).setUserInput("newpass1");
-  SpecialPowers.wrap($_(1, "qword")).setUserInput("newpass1");
+  $_(1, "uname").value = "newuser1";
+  $_(1, "pword").value = "newpass1";
+  $_(1, "qword").value = "newpass1";
 
   // eslint-disable-next-line no-unused-vars
   var button = getFormSubmitButton(1);
 
   todo(false, "form submission disabled, can't auto-accept dialog yet");
   SimpleTest.finish();
 }
 
--- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html
@@ -41,158 +41,129 @@ add_task(async function setup() {
     }],
   });
 });
 
 const DEFAULT_ORIGIN = "http://mochi.test:8888";
 const TESTCASES = [
   {
     // Inputs
-    document: `<input type=password value="">`,
-    selectorValues: {
-      "[type=password]": "pass1",
-    },
+    document: `<input type=password value="pass1">`,
     inputIndexForFormLike: 0,
 
     // Expected outputs similar to PasswordManager:onFormSubmit
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: null,
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
-    document: `<input id="u1" value="">
-      <input type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "[type=password]": "pass1",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">`,
     inputIndexForFormLike: 0,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
-    document: `<input id="u1" value="">
-      <input type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "[type=password]": "pass1",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">`,
     inputIndexForFormLike: 1,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input id="p2" type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "pass1",
-      "#p2": "pass2",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">
+      <input type=password value="pass2">`,
     inputIndexForFormLike: 2,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: "pass1",
   },
   {
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input id="p2" type=password value="">
-      <input id="p3" type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "pass1",
-      "#p2": "pass2",
-      "#p3": "pass2",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">
+      <input type=password value="pass2">
+      <input type=password value="pass2">`,
     inputIndexForFormLike: 3,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: "pass1",
   },
   {
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="" form="form1">
-      <input id="p2" type=password value="">
+    document: `<input value="user1">
+      <input type=password value="user2" form="form1">
+      <input type=password value="pass1">
       <form id="form1">
-        <input id="u2" value="">
-        <input id="p3" type=password value="">
+        <input value="user3">
+        <input type=password value="pass2">
       </form>`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "user2",
-      "#p2": "pass1",
-      "#u2": "user3",
-      "#p3": "pass2",
-    },
     inputIndexForFormLike: 2,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
     document: `<!-- recipe field override -->
-      <input name="recipeuname" value="">
-      <input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input name="recipepword" type=password value="">`,
-    selectorValues: {
-      "[name='recipeuname']": "username from recipe",
-      "#u1": "default field username",
-      "#p1": "pass1",
-      "[name='recipepword']": "pass2",
-    },
+      <input name="recipeuname" value="username from recipe">
+      <input value="default field username">
+      <input type=password value="pass1">
+      <input name="recipepword" type=password value="pass2">`,
     inputIndexForFormLike: 2,
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "username from recipe",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: null,
   },
 ];
 
+function getSubmitMessage() {
+  info("getSubmitMessage");
+  return new Promise((resolve, reject) => {
+    PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
+      info("got formSubmissionProcessed");
+      PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
+      resolve(...args);
+    });
+  });
+}
+
 add_task(async function test() {
   let count = 0;
   let loginFrame = document.getElementById("loginFrame");
 
   for (let tc of TESTCASES) {
-    let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document;
+    let frameDoc = loginFrame.contentWindow.document;
     info("Starting testcase: " + JSON.stringify(tc));
 
-    let formProcessed = promiseFormsProcessed();
     // eslint-disable-next-line no-unsanitized/property
     frameDoc.documentElement.innerHTML = tc.document;
-    await formProcessed;
-    // We eliminate no user input as a reason for not capturing by modifying the value
-    setUserInputValues(frameDoc.documentElement, tc.selectorValues);
-
     let inputForFormLike = frameDoc.querySelectorAll("input")[tc.inputIndexForFormLike];
 
     let formLike = LoginFormFactory.createFromField(inputForFormLike);
 
     info("Calling _onFormSubmit with FormLike");
-    let submitProcessed = getSubmitMessage();
+    let processedPromise = getSubmitMessage();
     LoginManagerChild.forWindow(frameDoc.defaultView)._onFormSubmit(formLike);
 
-    let submittedResult = await submitProcessed;
+    let submittedResult = await processedPromise;
 
     // Check data sent via PasswordManager:onFormSubmit
     is(submittedResult.origin, tc.origin, "Check origin");
     is(submittedResult.formActionOrigin, tc.formActionOrigin, "Check formActionOrigin");
 
     if (tc.usernameFieldValue === null) {
       is(submittedResult.usernameField, tc.usernameFieldValue, "Check usernameField");
     } else {
--- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
@@ -42,145 +42,127 @@ add_task(async function setup() {
 const DEFAULT_ORIGIN = "http://test1.mochi.test:8888";
 const SCRIPTS = {
   PUSHSTATE: `history.pushState({}, "Pushed state", "?pushed");`,
   WINDOW_LOCATION: `window.location = "data:text/html;charset=utf-8,window.location";`,
 };
 const TESTCASES = [
   {
     // Inputs
-    document: `<input type=password value="">`,
-    selectorValues: {
-      "[type=password]": "pass1",
-    },
+    document: `<input type=password value="pass1">`,
 
     // Expected outputs similar to PasswordManager:onFormSubmit
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: null,
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
-    document: `<input id="u1" value="">
-      <input type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "[type=password]": "pass1",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">`,
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   {
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input id="p2" type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "pass1",
-      "#p2": "pass2",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">
+      <input type=password value="pass2">`,
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: "pass1",
   },
   {
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input id="p2" type=password value="">
-      <input id="p3" type=password value="">`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "pass1",
-      "#p2": "pass2",
-      "#p3": "pass2",
-    },
+    document: `<input value="user1">
+      <input type=password value="pass1">
+      <input type=password value="pass2">
+      <input type=password value="pass2">`,
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: "pass1",
   },
   {
     // Since there are two FormLikes to auto-submit in this case we mark
     // one FormLike's password fields with a magic "ignore-form-submission"
     // value so we can just focus on the other form. We then repeat the testcase
     // below with the other FormLike ignored.
-    document: `<input id="u1" value="">
-      <input type=password id="p1" value="" form="form1">
-      <input type=password id="p2" value="">
+    document: `<input value="user1">
+      <input type=password value="ignore-form-submission" form="form1">
+      <input type=password value="pass1">
       <form id="form1">
-        <input id="u2" value="">
-        <input id="p3" type=password value="">
+        <input value="user3">
+        <input type=password value="ignore-form-submission">
       </form>`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "ignore-form-submission",
-      "#p2": "pass1",
-      "#u2": "user3",
-      "#p3": "ignore-form-submission",
-    },
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "user1",
     newPasswordFieldValue: "pass1",
     oldPasswordFieldValue: null,
   },
   { // Same as above but with the other form ignored.
-    document: `<input id="u1" value="">
-      <input id="p1" type=password value="" form="form1">
-      <input id="p2" type=password value="">
+    document: `<input value="user1">
+      <input type=password value="pass2" form="form1">
+      <input type=password value="ignore-form-submission">
       <form id="form1">
-        <input id="u2" value="">
-        <input id="p3" type=password value="">
+        <input value="user3">
+        <input type=password value="pass2">
       </form>`,
-    selectorValues: {
-      "#u1": "user1",
-      "#p1": "pass2",
-      "#p2": "ignore-form-submission",
-      "#u2": "user3",
-      "#p3": "pass2",
-    },
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: null,
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: null,
   },
   {
     document: `<!-- recipe field override -->
-      <input name="recipeuname" value="">
-      <input id="u1" value="">
-      <input id="p1" type=password value="">
-      <input name="recipepword" type=password value="">`,
-    selectorValues: {
-      "[name='recipeuname']": "username from recipe",
-      "#u1": "default field username",
-      "#p1": "pass1",
-      "[name='recipepword']": "pass2",
-    },
+      <input name="recipeuname" value="username from recipe">
+      <input value="default field username">
+      <input type=password value="pass1">
+      <input name="recipepword" type=password value="pass2">`,
 
     origin: DEFAULT_ORIGIN,
     formActionOrigin: DEFAULT_ORIGIN,
     usernameFieldValue: "username from recipe",
     newPasswordFieldValue: "pass2",
     oldPasswordFieldValue: null,
   },
 ];
 
+/**
+ * @param {Function} [aFilterFn = undefined] Function to filter out irrelevant submissions.
+ * @return {Promise} resolving when a relevant form submission was processed.
+ */
+function getSubmitMessage(aFilterFn = undefined) {
+  info("getSubmitMessage");
+  return new Promise((resolve, reject) => {
+    PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
+      if (aFilterFn && !aFilterFn(...args)) {
+        // This submission isn't the one we're waiting for.
+        return;
+      }
+
+      info("got formSubmissionProcessed");
+      PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
+      resolve(...args);
+    });
+  });
+}
+
 function filterFormSubmissions(data) {
   return data.newPasswordField.value != "ignore-form-submission";
 }
 
 add_task(async function test() {
   let loginFrame = document.getElementById("loginFrame");
 
   for (let tc of TESTCASES) {
@@ -202,30 +184,25 @@ add_task(async function test() {
         if (surroundDocumentWithForm) {
           if (testDoc.includes("<form")) {
             info("Skipping surroundDocumentWithForm case since document already contains a <form>");
             continue;
           }
           testDoc = "<form>" + testDoc + "</form>";
         }
 
-        let formProcessed = promiseFormsProcessed();
         // eslint-disable-next-line no-unsanitized/property
         frameDoc.documentElement.innerHTML = testDoc;
-        await formProcessed;
-        // We eliminate no user input as a reason for not capturing by modifying the value
-        setUserInputValues(frameDoc.documentElement, tc.selectorValues)
-
-        let submitProcessed = getSubmitMessage(filterFormSubmissions);
+        // Wait for the form to be processed before trying to submit.
+        await promiseFormsProcessed();
+        let processedPromise = getSubmitMessage(filterFormSubmissions);
         info("Running " + scriptName + " script to cause a submission");
         frameDoc.defaultView.eval(SCRIPTS[scriptName]);
 
-        info("Waiting for formSubmissionProcsssed message");
-        let submittedResult = await submitProcessed;
-        info("Got for formSubmissionProcsssed message");
+        let submittedResult = await processedPromise;
 
         // Check data sent via PasswordManager:onFormSubmit
         is(submittedResult.origin, tc.origin, "Check origin");
         is(submittedResult.formActionOrigin, tc.formActionOrigin, "Check formActionOrigin");
 
         if (tc.usernameFieldValue === null) {
           is(submittedResult.usernameField, tc.usernameFieldValue, "Check usernameField");
         } else {
--- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
@@ -48,44 +48,32 @@ const SCRIPTS = {
   WINDOW_LOCATION_RELOAD: `window.location.reload();`,
   HISTORY_BACK: `history.back();`,
   HISTORY_GO_MINUS1: `history.go(-1);`,
 };
 const TESTCASES = [
   // Begin test cases that shouldn't trigger capture.
   {
     // Empty password field in a form
-    document: `<form><input type=password value="xxx"></form>`,
-    selectorValues: {
-      "[type=password]": "",
-    },
+    document: `<form><input type=password value=""></form>`,
   },
   {
     // Empty password field
     document: `<input type=password value="">`,
-    selectorValues: {
-      "[type=password]": "",
-    },
   },
   {
     // Test with an input that would normally be captured but with SCRIPTS that
     // shouldn't trigger capture.
-    document: `<input type=password value="">`,
-    selectorValues: {
-      "[type=password]": "pass2",
-    },
+    document: `<input type=password value="pass2">`,
     wouldCapture: true,
   },
   {
     // Test with an input that would normally be captured but with SCRIPTS that
     // shouldn't trigger capture.
-    document: `<form><input type=password value=""></form>`,
-    selectorValues: {
-      "[type=password]": "pass2",
-    },
+    document: `<form><input type=password value="pass2"></form>`,
     wouldCapture: true,
   },
 ];
 
 add_task(async function test() {
   let loginFrame = document.getElementById("loginFrame");
 
   let waitTime;
@@ -111,18 +99,19 @@ add_task(async function test() {
         }, {once: true});
       });
       loginFrame.src = DEFAULT_ORIGIN + "/tests/toolkit/components/passwordmgr/test/mochitest/blank.html";
       await loadedPromise;
 
       let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document;
       // eslint-disable-next-line no-unsanitized/property
       frameDoc.documentElement.innerHTML = tc.document;
-      // We eliminate no user input as a reason for not capturing by modifying the value
-      setUserInputValues(frameDoc.documentElement, tc.selectorValues);
+
+      // Wait for the form to be processed before trying to submit.
+      await promiseFormsProcessed();
 
       info("Running " + scriptName + " script to check for a submission");
       frameDoc.defaultView.eval(SCRIPTS[scriptName]);
 
       // Wait to see if the promise above resolves.
       await new Promise(resolve => setTimeout(resolve, waitTime));
       ok(true, "Done waiting for captures");
     }
--- a/toolkit/components/passwordmgr/test/mochitest/test_munged_username.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_munged_username.html
@@ -58,25 +58,16 @@ async function loadFormIntoIframe(origin
   await loadedPromise;
   await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [html], function(contentHtml) {
     // eslint-disable-next-line no-unsanitized/property
     this.content.document.documentElement.innerHTML = contentHtml;
   });
 
   // Wait for the form to be processed before trying to submit.
   await promiseFormsProcessed();
-
-  await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [html], function(contentHtml) {
-    let doc = this.content.document;
-    for (let field of doc.querySelectorAll("input")) {
-      let actualValue = field.value;
-      field.value = "";
-      SpecialPowers.wrap(field).setUserInput(actualValue);
-    }
-  });
 }
 
 add_task(async function setup() {
   info("Waiting for setup and page and frame loads");
   await readyPromise;
   await loadPromise;
 });
 
@@ -131,16 +122,30 @@ const TESTCASES = [
   },
   {
     testName: "test_okBulletUsername2",
     username: "••user••",
     expected: "••user••",
   },
 ];
 
+/**
+ * @return {Promise} resolving when form submission was processed.
+ */
+function getSubmitMessage() {
+  info("getSubmitMessage");
+  return new Promise((resolve, reject) => {
+    PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
+      info("got formSubmissionProcessed");
+      PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
+      resolve(...args);
+    });
+  });
+}
+
 add_task(async function test_new_logins() {
   for (let tc of TESTCASES) {
     info("Starting testcase: " + JSON.stringify(tc));
     await loadFormIntoIframe(DEFAULT_ORIGIN, `<form id="form1" onsubmit="return false;">
       <input  type="text"       name="uname" value="${tc.username}">
       <input  type="password"   name="pword" value="thepassword">
       <button type="submit" id="submitBtn">Submit</button>
     </form>`);
@@ -183,18 +188,18 @@ add_task(async function test_no_autofill
   await loadFormIntoIframe(ORG_ORIGIN, `<form id="form1" onsubmit="return false;">
     <input  type="text"       name="uname" value="">
     <input  type="password"   name="pword" value="">
     <button type="submit" id="submitBtn">Submit</button>
   </form>`);
   await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [], function() {
     let doc = this.content.document;
     Assert.equal(doc.querySelector("[name='uname']").value, "", "Check username didn't get autofilled");
-    SpecialPowers.wrap(doc.querySelector("[name='uname']")).setUserInput("real••••user");
-    SpecialPowers.wrap(doc.querySelector("[name='pword']")).setUserInput("pass1");
+    doc.querySelector("[name='uname']").setUserInput("real••••user");
+    doc.querySelector("[name='pword']").setUserInput("pass1");
   });
 
   // we shouldn't get the save password doorhanger...
   let popupShownPromise = promiseNoUnexpectedPopupShown();
 
   // Check data sent via PasswordManager:onFormSubmit
   let processedPromise = getSubmitMessage();
   await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [], function() {
--- a/toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html
@@ -7,16 +7,27 @@
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="pwmgr_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script>
   let chromeScript = runChecksAfterCommonInit();
 
+  function getSubmitMessage() {
+    info("getSubmitMessage");
+    return new Promise((resolve, reject) => {
+      chromeScript.addMessageListener("formSubmissionProcessed", function processed(...args) {
+        info("got formSubmissionProcessed");
+        chromeScript.removeMessageListener("formSubmissionProcessed", processed);
+        resolve(...args);
+      });
+    });
+  }
+
   SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected popupshown to occur");
 </script>
 <p id="display"></p>
 
 <div id="content" style="display: none">
    <form id="form1" onsubmit="return false;">
     <input  type="text"     name="uname" id="ufield">
     <input  type="password" name="pword" id="pfield">
@@ -29,18 +40,18 @@
   /** Test for Login Manager: Don't repeatedly prompt to save the
       same username and password combination in the same document **/
 
   add_task(async function test_prompt_does_not_reappear() {
     let username = document.getElementById("ufield");
     let password = document.getElementById("pfield");
     let submitButton = document.getElementById("submitBtn");
 
-    SpecialPowers.wrap(username).setUserInput("user");
-    SpecialPowers.wrap(password).setUserInput("pass");
+    username.value = "user";
+    password.value = "pass";
 
     let processedPromise = getSubmitMessage();
     let promptShownPromise = promisePromptShown("passwordmgr-prompt-save");
     submitButton.click();
     await processedPromise;
     await promptShownPromise;
 
     is(username.value, "user", "Checking for filled username");
--- a/toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html
@@ -35,25 +35,22 @@ Login Manager test: input value change r
   </form>
 
 </div>
 
 <pre id="test"></pre>
 <script>
   /** Test for Login Manager: input value change right after onsubmit event **/
   add_task(async function checkFormValues() {
-    SpecialPowers.wrap(document.getElementById("ufield")).setUserInput("testuser");
-    SpecialPowers.wrap(document.getElementById("pfield")).setUserInput("testpass");
+    document.getElementById("ufield").value = "testuser";
+    document.getElementById("pfield").value = "testpass";
     is($_(1, "uname").value, "testuser", "Checking for filled username");
     is($_(1, "pword").value, "testpass", "Checking for filled password");
 
     document.getElementById("form1").addEventListener("submit", () => {
-      // deliberately assign to .value rather than setUserInput:
-      // the scenario under test here is that script is changing/populating
-      // fields after the user has clicked the submit button
       document.getElementById("ufield").value = "newuser";
       document.getElementById("pfield").value = "newpass";
     }, true);
 
     document.getElementById("form1").addEventListener("submit", (e) => e.preventDefault());
 
     let processedPromise = getSubmitMessage();
 
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html
+++ /dev/null
@@ -1,233 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Don't send onFormSubmit message on navigation if the user did not interact
-    with the login fields</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
-  <script type="text/javascript" src="pwmgr_common.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<p id="display"></p>
-
-<div id="content">
-  <iframe id="loginFrame">
-  </iframe>
-</div>
-
-<pre id="test"></pre>
-<script>
-const { TestUtils } = SpecialPowers.Cu.import("resource://testing-common/TestUtils.jsm");
-SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected popup to show");
-let iframe = document.getElementById("loginFrame");
-
-function waitForLoad() {
-  return new Promise(resolve => {
-    function handleLoad() {
-      iframe.removeEventListener("load", handleLoad);
-      resolve();
-    }
-    iframe.addEventListener("load", handleLoad);
-  });
-}
-
- async function setup(pageUrl) {
-  let loadPromise = waitForLoad();
-  iframe.src = pageUrl || "https://example.org/tests/toolkit/components/passwordmgr/test/mochitest/formless_basic.html";
-
-  await loadPromise;
-  let win = SpecialPowers.wrap(iframe.contentWindow);
-  let iframeDoc = win.document;
-
-  let link = document.createElement("a");
-  link.setAttribute("href", "http://mochi.test:8888");
-  iframeDoc.body.appendChild(link);
-
-  return {iframeDoc, link};
-}
-
-function setValue(doc) {
-  // assign to .value directly, we deliberately don't emulate user input
-  doc.getElementById("form-basic-username").value = "user";
-  doc.getElementById("form-basic-password").value = "pass";
-}
-
-add_task(async function test_init() {
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["signon.userInputRequiredToCapture.enabled", true],
-  ]});
-});
-
-add_task(async function test_no_message_on_navigation() {
-  // If login field values were set by the website, we don't message to save the
-  // login values if the user did not interact with the fields before submiting.
-  let elements = await setup();
-  setValue(elements.iframeDoc);
-  await promiseFormsProcessed();
-
-  let submitMessageSent = false;
-  getSubmitMessage().then(value => {
-    submitMessageSent = true;
-  });
-
-  let loadPromise = waitForLoad();
-  SpecialPowers.wrap(elements.link).click();
-  await loadPromise;
-
-  // allow time to pass before concluding no onFormSubmit message was sent
-  await new Promise(res => setTimeout(res, 1000));
-  ok(!submitMessageSent, "onFormSubmit message is not sent on navigation since the login fields were not modified");
-});
-
-add_task(async function test_prefd_off_message_on_navigation() {
-  // Confirm the pref controls capture behavior with non-user-set field values.
-  await SpecialPowers.pushPrefEnv({"set": [
-    ["signon.userInputRequiredToCapture.enabled", false],
-  ]});
-
-  let elements = await setup();
-  setValue(elements.iframeDoc);
-  await promiseFormsProcessed();
-
-  let promiseSubmitMessage = getSubmitMessage();
-  SpecialPowers.wrap(elements.link).click();
-  await promiseSubmitMessage;
-  info("onFormSubmit message was sent as expected after navigation");
-
-  SpecialPowers.popPrefEnv();
-});
-
-add_task(async function test_message_with_user_interaction_on_navigation() {
-  let elements = await setup();
-  setValue(elements.iframeDoc);
-  await promiseFormsProcessed();
-
-  let username = elements.iframeDoc.getElementById("form-basic-username");
-  username.setUserInput("foo");
-  let promiseSubmitMessage = getSubmitMessage();
-  SpecialPowers.wrap(elements.link).click();
-  await promiseSubmitMessage;
-  info("onFormSubmit message was sent as expected after user interaction");
-});
-
-add_task(async function test_empty_form_with_input_handler() {
-  let elements = await setup();
-  await promiseFormsProcessed();
-
-  elements.iframeDoc.getElementById("form-basic-username").setUserInput("user");
-  elements.iframeDoc.getElementById("form-basic-password").setUserInput("pass");
-
-  let promiseSubmitMessage = getSubmitMessage();
-  SpecialPowers.wrap(elements.link).click();
-  await promiseSubmitMessage;
-  info("onFormSubmit message was sent as expected after user interaction");
-});
-
-add_task(async function test_message_on_autofill_without_user_interaction() {
-  runInParent(function addLogin() {
-    const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-    let login = Cc["@mozilla.org/login-manager/loginInfo;1"]
-                        .createInstance(Ci.nsILoginInfo);
-    login.init("https://example.org", "https://example.org", null,
-               "user1", "pass1", "", "");
-
-    Services.logins.addLogin(login);
-  });
-
-  let elements = await setup();
-  await promiseFormsProcessed();
-
-  // Check for autofilled values.
-  let doc = elements.iframeDoc;
-  let uname = doc.getElementById("form-basic-username");
-  let pword = doc.getElementById("form-basic-password");
-  is(uname.value, "user1", "Username was autofilled correctly");
-  is(pword.value, "pass1", "Password was autofilled correctly");
-
-  let promiseSubmitMessage = getSubmitMessage();
-  let loadPromise = waitForLoad();
-  SpecialPowers.wrap(elements.link).click();
-  await loadPromise;
-
-  let messageData = await promiseSubmitMessage;
-  ok(messageData.autoFilledLoginGuid, "Message was sent with autoFilledLoginGuid");
-});
-
-add_task(async function test_message_on_autofill_with_user_interaction() {
-  runInParent(function addLogin() {
-    const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-    let login = Cc["@mozilla.org/login-manager/loginInfo;1"]
-                        .createInstance(Ci.nsILoginInfo);
-    login.init("https://example.org", "https://example.org", null,
-               "user1", "pass1", "", "");
-
-    Services.logins.addLogin(login);
-  });
-
-  let elements = await setup();
-  await promiseFormsProcessed();
-  // Check for autofilled values.
-  let doc = elements.iframeDoc;
-  let uname = doc.getElementById("form-basic-username");
-  let pword = doc.getElementById("form-basic-password");
-  is(uname.value, "user1", "Username was autofilled correctly");
-  is(pword.value, "pass1", "Password was autofilled correctly");
-
-  elements.iframeDoc.getElementById("form-basic-username").setUserInput("newuser");
-  let promiseSubmitMessage = getSubmitMessage();
-  let loadPromise = waitForLoad();
-  SpecialPowers.wrap(elements.link).click();
-  await loadPromise;
-
-  let messageData = await promiseSubmitMessage;
-  ok(messageData.autoFilledLoginGuid, "Message was sent with autoFilledLoginGuid");
-  is(messageData.usernameField.value, "newuser", "Message was sent with correct usernameField.value");
-  info("Message was sent as expected after user interaction");
-});
-
-add_task(async function test_no_message_on_user_input_from_other_form() {
-  // ensure input into unrelated fields on the page don't change login form modified-ness
-  let elements = await setup("http://example.com/tests/toolkit/components/passwordmgr/test/mochitest/form_basic.html");
-  await promiseFormsProcessed();
-  info("initial form processed");
-  // Add a form which will not be submitted and an input associated with that form
-  let doc = SpecialPowers.wrap(elements.iframeDoc);
-  let loginForm = doc.querySelector("form");
-  let fragment = doc.createDocumentFragment();
-  let otherForm = doc.createElement("form");
-  otherForm.id ="otherForm";
-  fragment.appendChild(otherForm);
-
-  let alienField = doc.createElement("input");
-  alienField.type = "text"; // not a password field
-  alienField.setAttribute("form", "otherForm");
-  // new field is child of the login, but a member of different non-login form via its .form property
-  loginForm.appendChild(alienField);
-  doc.body.appendChild(fragment);
-
-  await TestUtils.waitForTick();
-
-  SpecialPowers.wrap(alienField).setUserInput("something");
-
-  let submitMessageSent = false;
-  getSubmitMessage().then(data => {
-    info("submit mesage data: " + JSON.stringify(data));
-    submitMessageSent = true;
-  });
-
-  info("submitting the form");
-  let loadPromise = waitForLoad();
-  SpecialPowers.wrap(elements.link).click();
-  info("waiting for response to load");
-  await loadPromise;
-
-  // allow time to pass before concluding no onFormSubmit message was sent
-  await new Promise(res => setTimeout(res, 1000));
-  ok(!submitMessageSent, "onFormSubmit message is not sent on navigation since no login fields were modified");
-});
-
-</script>
-</body>
-</html>