Merge mozilla-central to autoland. a=merge CLOSED TREE
authorNoemi Erli <nerli@mozilla.com>
Thu, 28 Mar 2019 07:03:14 +0200
changeset 466508 1aa2a852f2fd0ece3a15285518b579afe424b702
parent 466507 4503d8e8ee40c25bae1f0d91432a16282e1277b0 (current diff)
parent 466346 0b5c2f979c83ffaba7bfec7229ea3588118313d4 (diff)
child 466509 7f0d03ec917cfc831b7c4104729801fa33b1d167
push id35768
push useropoprus@mozilla.com
push dateThu, 28 Mar 2019 09:55:54 +0000
treeherdermozilla-central@c045dd97faf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
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
Merge mozilla-central to autoland. a=merge CLOSED TREE
toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formSubmitURL.html
toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete_formSubmitURL.html
toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
--- a/taskcluster/ci/openh264-plugin/kind.yml
+++ b/taskcluster/ci/openh264-plugin/kind.yml
@@ -127,17 +127,17 @@ jobs:
             using: mozharness
             script: mozharness/scripts/openh264_build.py
             config:
                 - openh264/win64.py
         toolchains:
             - win64-clang-cl
     win64-aarch64/opt:
         attributes:
-            build_platform: windows2012-aarch64
+            build_platform: win64-aarch64
             build_type: opt
         treeherder:
             platform: win64-aarch64/opt
         worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
         worker:
             max-run-time: 1800
             artifacts:
                 - name: private/openh264
--- a/toolkit/components/passwordmgr/LoginHelper.jsm
+++ b/toolkit/components/passwordmgr/LoginHelper.jsm
@@ -267,30 +267,25 @@ var LoginHelper = {
    *                                 from a form or page that we are considering.
    * @param {nsILoginFindOptions} aOptions - Options to affect whether the origin
    *                                         from the login (aLoginOrigin) is a
    *                                         match for the origin we're looking
    *                                         for (aSearchOrigin).
    */
   isOriginMatching(aLoginOrigin, aSearchOrigin, aOptions = {
     schemeUpgrades: false,
-    acceptWildcardMatch: false,
   }) {
     if (aLoginOrigin == aSearchOrigin) {
       return true;
     }
 
     if (!aOptions) {
       return false;
     }
 
-    if (aOptions.acceptWildcardMatch && aLoginOrigin == "") {
-      return true;
-    }
-
     if (aOptions.schemeUpgrades) {
       try {
         let loginURI = Services.io.newURI(aLoginOrigin);
         let searchURI = Services.io.newURI(aSearchOrigin);
         if (loginURI.scheme == "http" && searchURI.scheme == "https" &&
             loginURI.hostPort == searchURI.hostPort) {
           return true;
         }
@@ -480,27 +475,22 @@ var LoginHelper = {
    *        a scheme matching `preferredOrigin`'s if there are two logins with
    *        the same `uniqueKeys`. The default preference to distinguish two
    *        logins is `timeLastUsed`. If there is no preference between two
    *        logins, the first one found wins.
    * @param {string} [preferredOrigin = undefined]
    *        String representing the origin to use for preferring one login over
    *        another when they are dupes. This is used with "scheme" for
    *        `resolveBy` so the scheme from this origin will be preferred.
-   * @param {string} [preferredFormActionOrigin = undefined]
-   *        String representing the action origin to use for preferring one login over
-   *        another when they are dupes. This is used with "actionOrigin" for
-   *        `resolveBy` so the scheme from this action origin will be preferred.
    *
    * @returns {nsILoginInfo[]} list of unique logins.
    */
   dedupeLogins(logins, uniqueKeys = ["username", "password"],
                resolveBy = ["timeLastUsed"],
-               preferredOrigin = undefined,
-               preferredFormActionOrigin = undefined) {
+               preferredOrigin = undefined) {
     const KEY_DELIMITER = ":";
 
     if (!preferredOrigin && resolveBy.includes("scheme")) {
       throw new Error("dedupeLogins: `preferredOrigin` is required in order to " +
                       "prefer schemes which match it.");
     }
 
     let preferredOriginScheme;
@@ -535,26 +525,16 @@ var LoginHelper = {
     function isLoginPreferred(existingLogin, login) {
       if (!resolveBy || resolveBy.length == 0) {
         // If there is no preference, prefer the existing login.
         return false;
       }
 
       for (let preference of resolveBy) {
         switch (preference) {
-          case "actionOrigin": {
-            if (!preferredFormActionOrigin) {
-              break;
-            }
-            if (LoginHelper.isOriginMatching(existingLogin.formSubmitURL, preferredFormActionOrigin, {schemeUpgrades: LoginHelper.schemeUpgrades}) &&
-                !LoginHelper.isOriginMatching(login.formSubmitURL, preferredFormActionOrigin, {schemeUpgrades: LoginHelper.schemeUpgrades})) {
-              return false;
-            }
-            break;
-          }
           case "scheme": {
             if (!preferredOriginScheme) {
               break;
             }
 
             try {
               // Only `hostname` is currently considered
               let existingLoginURI = Services.io.newURI(existingLogin.hostname);
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -1169,20 +1169,19 @@ var LoginManagerContent = {
   },
 
   /**
    * Attempt to find the username and password fields in a form, and fill them
    * in using the provided logins and recipes.
    *
    * @param {LoginForm} form
    * @param {nsILoginInfo[]} foundLogins an array of nsILoginInfo that could be
-   *        used for the form, including ones with a different form action origin
-   *        which are only used when the fill is userTriggered
+            used for the form
    * @param {Set} recipes a set of recipes that could be used to affect how the
-   *        form is filled
+            form is filled
    * @param {Object} [options = {}] a list of options for this method
    * @param {HTMLInputElement} [options.inputElement = null] an optional target
    *        input element we want to fill
    * @param {bool} [options.autofillForm = false] denotes if we should fill the
    *        form in automatically
    * @param {bool} [options.clobberUsername = false] controls if an existing
    *        username can be overwritten. If this is false and an inputElement
    *        of type password is also passed, the username field will be ignored.
@@ -1220,19 +1219,18 @@ var LoginManagerContent = {
       MULTIPLE_LOGINS: 7,
       NO_AUTOFILL_FORMS: 8,
       AUTOCOMPLETE_OFF: 9,
       INSECURE: 10,
       PASSWORD_AUTOCOMPLETE_NEW_PASSWORD: 11,
     };
 
     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.
+      // Nothing to do if we have no matching logins available,
+      // and there isn't a need to show the insecure form warning.
       if (foundLogins.length == 0 &&
           (InsecurePasswordUtils.isFormSecure(form) ||
           !LoginHelper.showInsecureFieldWarning)) {
         // We don't log() here since this is a very common case.
         autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
         return;
       }
 
@@ -1278,29 +1276,16 @@ var LoginManagerContent = {
       // but even with one account we should refill if the user edits.
       // We would also need this attached to show the insecure login
       // warning, regardless of saved login.
       if (usernameField) {
         this._formFillService.markAsLoginManagerField(usernameField);
         usernameField.addEventListener("keydown", observer);
       }
 
-      if (!userTriggered) {
-        // Only autofill logins that match the form's action. In the above code
-        // we have attached autocomplete for logins that don't match the form action.
-        foundLogins = foundLogins.filter(l => {
-          return LoginHelper.isOriginMatching(l.formSubmitURL,
-                                              LoginHelper.getFormActionOrigin(form),
-                                              {
-                                                schemeUpgrades: LoginHelper.schemeUpgrades,
-                                                acceptWildcardMatch: true,
-                                              });
-        });
-      }
-
       // Nothing to do if we have no matching logins available.
       // Only insecure pages reach this block and logs the same
       // telemetry flag.
       if (foundLogins.length == 0) {
         // We don't log() here since this is a very common case.
         autofillResult = AUTOFILL_RESULT.NO_SAVED_LOGINS;
         return;
       }
--- a/toolkit/components/passwordmgr/LoginManagerParent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm
@@ -35,45 +35,41 @@ var LoginManagerParent = {
    * @deprecated
    */
   _recipeManager: null,
 
   // Tracks the last time the user cancelled the master password prompt,
   // to avoid spamming master password prompts on autocomplete searches.
   _lastMPLoginCancelled: Math.NEGATIVE_INFINITY,
 
-  _searchAndDedupeLogins(formOrigin, actionOrigin, {looseActionOriginMatch} = {}) {
+  _searchAndDedupeLogins(formOrigin, actionOrigin) {
     let logins;
-    let matchData = {
-      hostname: formOrigin,
-      schemeUpgrades: LoginHelper.schemeUpgrades,
-    };
-    if (!looseActionOriginMatch) {
-      matchData.formSubmitURL = actionOrigin;
-    }
     try {
-      logins = LoginHelper.searchLoginsWithObject(matchData);
+      logins = LoginHelper.searchLoginsWithObject({
+        hostname: formOrigin,
+        formSubmitURL: actionOrigin,
+        schemeUpgrades: LoginHelper.schemeUpgrades,
+      });
     } catch (e) {
       // Record the last time the user cancelled the MP prompt
       // to avoid spamming them with MP prompts for autocomplete.
       if (e.result == Cr.NS_ERROR_ABORT) {
         log("User cancelled master password prompt.");
         this._lastMPLoginCancelled = Date.now();
         return [];
       }
       throw e;
     }
 
     // Dedupe so the length checks below still make sense with scheme upgrades.
     let resolveBy = [
-      "actionOrigin",
       "scheme",
       "timePasswordChanged",
     ];
-    return LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin, actionOrigin);
+    return LoginHelper.dedupeLogins(logins, ["username"], resolveBy, formOrigin);
   },
 
   // Listeners are added in BrowserGlue.jsm on desktop
   // and in BrowserCLH.js on mobile.
   receiveMessage(msg) {
     let data = msg.data;
     switch (msg.name) {
       case "PasswordManager:findLogins": {
@@ -221,18 +217,17 @@ var LoginManagerParent = {
       // never return). We should guarantee that at least one of these
       // will fire.
       // See bug XXX.
       Services.obs.addObserver(observer, "passwordmgr-crypto-login");
       Services.obs.addObserver(observer, "passwordmgr-crypto-loginCanceled");
       return;
     }
 
-    // Autocomplete results do not need to match actionOrigin.
-    let logins = this._searchAndDedupeLogins(formOrigin, actionOrigin, {looseActionOriginMatch: true});
+    let logins = this._searchAndDedupeLogins(formOrigin, actionOrigin);
 
     log("sendLoginDataToChild:", logins.length, "deduped logins");
     // Convert the array of nsILoginInfo to vanilla JS objects since nsILoginInfo
     // doesn't support structured cloning.
     var jsLogins = LoginHelper.loginsToVanillaObjects(logins);
     target.sendAsyncMessage("PasswordManager:loginsFound", {
       requestId,
       logins: jsLogins,
@@ -270,18 +265,17 @@ var LoginManagerParent = {
       log("Using previous autocomplete result");
 
       // We have a list of results for a shorter search string, so just
       // filter them further based on the new search string.
       logins = LoginHelper.vanillaObjectsToLogins(previousResult.logins);
     } else {
       log("Creating new autocomplete search result.");
 
-      // Autocomplete results do not need to match actionOrigin.
-      logins = this._searchAndDedupeLogins(formOrigin, actionOrigin, {looseActionOriginMatch: true});
+      logins = this._searchAndDedupeLogins(formOrigin, actionOrigin);
     }
 
     let matchingLogins = logins.filter(function(fullMatch) {
       let match = fullMatch.username;
 
       // Remove results that are too short, or have different prefix.
       // Also don't offer empty usernames as possible results except
       // for password field.
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -30,19 +30,16 @@ skip-if = toolkit == 'android' # autocom
 [test_autocomplete_https_upgrade.html]
 skip-if = toolkit == 'android' # autocomplete
 [test_autocomplete_sandboxed.html]
 scheme = https
 skip-if = toolkit == 'android' # autocomplete
 [test_autofill_autocomplete_types.html]
 scheme = https
 skip-if = toolkit == 'android' # bug 1533965
-[test_autofill_different_formSubmitURL.html]
-scheme = https
-skip-if = toolkit == 'android' # Bug 1259768
 [test_autofill_from_bfcache.html]
 scheme = https
 skip-if = toolkit == 'android' # bug 1527403
 [test_autofill_highlight.html]
 scheme = https
 skip-if = toolkit == 'android' # Bug 1531185
 [test_autofill_https_upgrade.html]
 skip-if = toolkit == 'android' # Bug 1259768
@@ -55,21 +52,17 @@ skip-if = toolkit == 'android' # autocom
 [test_basic_form.html]
 [test_basic_form_0pw.html]
 [test_basic_form_1pw.html]
 [test_basic_form_1pw_2.html]
 [test_basic_form_2pw_1.html]
 [test_basic_form_2pw_2.html]
 [test_basic_form_3pw_1.html]
 [test_basic_form_autocomplete.html]
-skip-if = toolkit == 'android' || (webrender && os == 'linux' && debug) # android:autocomplete, linux: bug 1538955
-scheme = https
-[test_basic_form_autocomplete_formSubmitURL.html]
 skip-if = toolkit == 'android' # android:autocomplete.
-scheme = https
 [test_basic_form_honor_autocomplete_off.html]
 scheme = https
 skip-if = toolkit == 'android' # android:autocomplete.
 [test_insecure_form_field_autocomplete.html]
 skip-if = toolkit == 'android' || os == 'linux' # android:autocomplete., linux: bug 1325778
 [test_password_field_autocomplete.html]
 skip-if = toolkit == 'android' # android:autocomplete.
 [test_insecure_form_field_no_saved_login.html]
@@ -77,17 +70,16 @@ skip-if = toolkit == 'android' # android
 [test_basic_form_html5.html]
 [test_basic_form_pwevent.html]
 [test_basic_form_pwonly.html]
 [test_bug_627616.html]
 skip-if = toolkit == 'android' # Tests desktop prompts
 [test_bug_776171.html]
 [test_case_differences.html]
 skip-if = toolkit == 'android' # autocomplete
-scheme = https
 [test_form_action_1.html]
 [test_form_action_2.html]
 [test_form_action_javascript.html]
 [test_formless_autofill.html]
 [test_formless_submit.html]
 skip-if = toolkit == 'android' && debug # bug 1397615
 [test_formless_submit_navigation.html]
 skip-if = toolkit == 'android' && debug # bug 1397615
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js
@@ -129,17 +129,21 @@ function checkUnmodifiedForm(formNum) {
 
     is(ele.value, ele.defaultValue, "Test to default value of field " +
        ele.name + " in form " + formNum);
   }
 }
 
 function registerRunTests() {
   return new Promise(resolve => {
-    function onDOMContentLoaded() {
+    // We provide a general mechanism for our tests to know when they can
+    // safely run: we add a final form that we know will be filled in, wait
+    // for the login manager to tell us that it's filled in and then continue
+    // with the rest of the tests.
+    window.addEventListener("DOMContentLoaded", (event) => {
       var form = document.createElement("form");
       form.id = "observerforcer";
       var username = document.createElement("input");
       username.name = "testuser";
       form.appendChild(username);
       var password = document.createElement("input");
       password.name = "testpass";
       password.type = "password";
@@ -156,28 +160,17 @@ function registerRunTests() {
           var runTestEvent = new Event("runTests");
           window.dispatchEvent(runTestEvent);
           resolve();
         });
       });
       SpecialPowers.addObserver(observer, "passwordmgr-processed-form");
 
       document.body.appendChild(form);
-    }
-    // We provide a general mechanism for our tests to know when they can
-    // safely run: we add a final form that we know will be filled in, wait
-    // for the login manager to tell us that it's filled in and then continue
-    // with the rest of the tests.
-    if (document.readyState == "complete" ||
-        document.readyState == "loaded" ||
-        document.readyState == "interactive") {
-      onDOMContentLoaded();
-    } else {
-      window.addEventListener("DOMContentLoaded", onDOMContentLoaded);
-    }
+    });
   });
 }
 
 function enableMasterPassword() {
   setMasterPassword(true);
 }
 
 function disableMasterPassword() {
@@ -273,53 +266,28 @@ function promisePromptShown(expectedTopi
 function runInParent(aFunctionOrURL) {
   let chromeScript = SpecialPowers.loadChromeScript(aFunctionOrURL);
   SimpleTest.registerCleanupFunction(() => {
     chromeScript.destroy();
   });
   return chromeScript;
 }
 
-/*
- * gTestDependsOnDeprecatedLogin Set this global to true if your test relies
- * on the testuser/testpass login that is created in pwmgr_common.js. New tests
- * should not rely on this login.
- */
-var gTestDependsOnDeprecatedLogin = false;
-
-/**
- * Replace the content innerHTML with the provided form and wait for autofill to fill in the form.
- *
- * @param {string} form The form to be appended to the #content element.
- * @param {string} fieldSelector The CSS selector for the field to-be-filled
- * @param {string} fieldValue The value expected to be filled
- * @param {string} formId The ID (excluding the # character) of the form
- */
-function setFormAndWaitForFieldFilled(form, {fieldSelector, fieldValue, formId}) {
-  // eslint-disable-next-line no-unsanitized/property
-  document.querySelector("#content").innerHTML = form;
-  return SimpleTest.promiseWaitForCondition(() => {
-    let ancestor = formId ? document.querySelector("#" + formId) :
-                            document.documentElement;
-    return ancestor.querySelector(fieldSelector).value == fieldValue;
-  }, "Wait for password manager to fill form");
-}
-
 /**
  * Run commonInit synchronously in the parent then run the test function after the runTests event.
  *
  * @param {Function} aFunction The test function to run
  */
 function runChecksAfterCommonInit(aFunction = null) {
   SimpleTest.waitForExplicitFinish();
   if (aFunction) {
     window.addEventListener("runTests", aFunction);
     PWMGR_COMMON_PARENT.addMessageListener("registerRunTests", () => registerRunTests());
   }
-  PWMGR_COMMON_PARENT.sendSyncMessage("setupParent", {testDependsOnDeprecatedLogin: gTestDependsOnDeprecatedLogin});
+  PWMGR_COMMON_PARENT.sendSyncMessage("setupParent");
   return PWMGR_COMMON_PARENT;
 }
 
 // Begin code that runs immediately for all tests that include this file.
 
 const PWMGR_COMMON_PARENT = runInParent(SimpleTest.getTestFileURL("pwmgr_common_parent.js"));
 
 SimpleTest.registerCleanupFunction(() => {
--- a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
+++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
@@ -16,43 +16,41 @@ const {LoginTestUtils} = ChromeUtils.imp
 var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Init with a common login
  * If selfFilling is true or non-undefined, fires an event at the page so that
  * the test can start checking filled-in values. Tests that check observer
  * notifications might be confused by this.
  */
-function commonInit(selfFilling, testDependsOnDeprecatedLogin) {
+function commonInit(selfFilling) {
   var pwmgr = Services.logins;
   assert.ok(pwmgr != null, "Access LoginManager");
 
   // Check that initial state has no logins
   var logins = pwmgr.getAllLogins();
   assert.equal(logins.length, 0, "Not expecting logins to be present");
   var disabledHosts = pwmgr.getAllDisabledHosts();
   if (disabledHosts.length) {
     assert.ok(false, "Warning: wasn't expecting disabled hosts to be present.");
     for (var host of disabledHosts) {
       pwmgr.setLoginSavingEnabled(host, true);
     }
   }
 
-  if (testDependsOnDeprecatedLogin) {
-    // Add a login that's used in multiple tests
-    var login = Cc["@mozilla.org/login-manager/loginInfo;1"].
-                createInstance(Ci.nsILoginInfo);
-    login.init("http://mochi.test:8888", "http://mochi.test:8888", null,
-               "testuser", "testpass", "uname", "pword");
-    pwmgr.addLogin(login);
-  }
+  // Add a login that's used in multiple tests
+  var login = Cc["@mozilla.org/login-manager/loginInfo;1"].
+              createInstance(Ci.nsILoginInfo);
+  login.init("http://mochi.test:8888", "http://mochi.test:8888", null,
+             "testuser", "testpass", "uname", "pword");
+  pwmgr.addLogin(login);
 
   // Last sanity check
   logins = pwmgr.getAllLogins();
-  assert.equal(logins.length, testDependsOnDeprecatedLogin ? 1 : 0, "Checking for successful init login");
+  assert.equal(logins.length, 1, "Checking for successful init login");
   disabledHosts = pwmgr.getAllDisabledHosts();
   assert.equal(disabledHosts.length, 0, "Checking for no disabled hosts");
 
   if (selfFilling) {
     return;
   }
 
   // Notify the content side that initialization is done and tests can start.
@@ -101,18 +99,18 @@ function onPrompt(subject, topic, data) 
   });
 }
 Services.obs.addObserver(onPrompt, "passwordmgr-prompt-change");
 Services.obs.addObserver(onPrompt, "passwordmgr-prompt-save");
 
 
 // Begin message listeners
 
-addMessageListener("setupParent", ({selfFilling = false, testDependsOnDeprecatedLogin = false} = {}) => {
-  commonInit(selfFilling, testDependsOnDeprecatedLogin);
+addMessageListener("setupParent", ({selfFilling = false} = {selfFilling: false}) => {
+  commonInit(selfFilling);
   sendAsyncMessage("doneSetup");
 });
 
 addMessageListener("loadRecipes", async function(recipes) {
   var recipeParent = await LoginManagerParent.recipeParentPromise;
   await recipeParent.load(recipes);
   sendAsyncMessage("loadedRecipes", recipes);
 });
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formSubmitURL.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test autofill on an HTTPS page using upgraded HTTP logins wtih different formSubmitURL</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/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>
-<script>
-const MISSING_ACTION_PATH = TESTS_DIR + "mochitest/form_basic.html";
-
-const chromeScript = runChecksAfterCommonInit(false);
-
-let nsLoginInfo = SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1",
-                                                                           SpecialPowers.Ci.nsILoginInfo,
-                                                                           "init");
-</script>
-<p id="display"></p>
-
-<!-- we presumably can't hide the content for this test. -->
-<div id="content">
-  <iframe></iframe>
-</div>
-
-<pre id="test">
-<script class="testbody" type="text/javascript">
-let iframe = SpecialPowers.wrap(document.getElementsByTagName("iframe")[0]);
-
-// Check for expected username/password in form.
-function checkACForm(expectedUsername, expectedPassword) {
-  let iframeDoc = iframe.contentDocument;
-  let uname = iframeDoc.getElementById("form-basic-username");
-  let pword = iframeDoc.getElementById("form-basic-password");
-  let formID = uname.parentNode.id;
-  is(uname.value, expectedUsername, "Checking " + formID + " username");
-  is(pword.value, expectedPassword, "Checking " + formID + " password");
-}
-async function prepareLoginsAndProcessForm(url, logins = []) {
-  LoginManager.removeAllLogins();
-
-  let dates = Date.now();
-  for (let login of logins) {
-    SpecialPowers.do_QueryInterface(login, SpecialPowers.Ci.nsILoginMetaInfo);
-    // Force all dates to be the same so they don't affect things like deduping.
-    login.timeCreated = login.timePasswordChanged = login.timeLastUsed = dates;
-    LoginManager.addLogin(login);
-  }
-
-  iframe.src = url;
-  await promiseFormsProcessed();
-}
-
-add_task(async function test_formSubmitURL_wildcard_should_autofill() {
-  await prepareLoginsAndProcessForm("https://example.com" + MISSING_ACTION_PATH, [
-    new nsLoginInfo("https://example.com", "", null,
-                    "name2", "pass2", "uname", "pword"),
-  ]);
-
-  checkACForm("name2", "pass2");
-});
-
-add_task(async function test_formSubmitURL_different_shouldnt_autofill() {
-  await prepareLoginsAndProcessForm("https://example.com" + MISSING_ACTION_PATH, [
-    new nsLoginInfo("https://example.com", "https://another.domain", null,
-                    "name2", "pass2", "uname", "pword"),
-  ]);
-
-  checkACForm("", "");
-});
-
-</script>
-</pre>
-</body>
-</html>
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html
@@ -6,42 +6,39 @@
   <script type="text/javascript" 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>
 Login Manager test: simple form fill
 
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(startTest);
 
 /** Test for Login Manager: form fill, multiple forms. **/
 
-async function startTest() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form1" action="formtest.js">
-      <p>This is form 1.</p>
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-
-      <button type="submit">Submit</button>
-      <button type="reset"> Reset </button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "testuser"});
-
+function startTest() {
   is($_(1, "uname").value, "testuser", "Checking for filled username");
   is($_(1, "pword").value, "testpass", "Checking for filled password");
 
   SimpleTest.finish();
 }
 </script>
 
 <p id="display"></p>
 
 <div id="content" style="display: none">
 
+  <form id="form1" action="formtest.js">
+    <p>This is form 1.</p>
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+
+    <button type="submit">Submit</button>
+    <button type="reset"> Reset </button>
+  </form>
 
 </div>
 
 <pre id="test"></pre>
 </body>
 </html>
 
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html
@@ -5,17 +5,16 @@
   <title>Test autofill for forms with 1 password field</title>
   <script type="text/javascript" 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>
 Login Manager test: forms with 1 password field
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 
 <div id="content" style="display: none">
 
 <!-- no username fields -->
 
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html
@@ -5,17 +5,16 @@
   <title>Test forms with 1 password field, part 2</title>
   <script type="text/javascript" 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>
 Login Manager test: forms with 1 password field, part 2
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 
 <div id="content" style="display: none">
 
 <form id='form1' action='formtest.js'> 1
     <input type='password' name='pname' value=''>
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html
@@ -5,17 +5,16 @@
   <title>Test autofill for forms with 2 password fields</title>
   <script type="text/javascript" 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>
 Login Manager test: forms with 2 password fields
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 
 <div id="content" style="display: none">
 
 
 <!-- no username fields -->
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html
@@ -5,17 +5,16 @@
   <title>Test autofill for forms with 3 password fields</title>
   <script type="text/javascript" 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>
 Login Manager test: forms with 3 password fields (form filling)
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 
 <div id="content" style="display: none">
   <p>The next three forms are <b>user/pass/passB/passC</b>, as all-empty, preuser(only), and preuser/pass</p>
   <form id="form1" action="formtest.js">
     <input  type="text"       name="uname">
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html
@@ -20,66 +20,71 @@ var setupScript = runInParent(function s
   const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
   // Create some logins just for this form, since we'll be deleting them.
   var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
                                            Ci.nsILoginInfo, "init");
   assert.ok(nsLoginInfo != null, "nsLoginInfo constructor");
 
   // login0 has no username, so should be filtered out from the autocomplete list.
-  var login0 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "", "user0pass", "", "pword");
 
-  var login1 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "tempuser1", "temppass1", "uname", "pword");
 
-  var login2 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "testuser2", "testpass2", "uname", "pword");
 
-  var login3 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "testuser3", "testpass3", "uname", "pword");
 
-  var login4 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "zzzuser4", "zzzpass4", "uname", "pword");
 
-  // The following unused variables are referenced by `eval` in the message listeners below.
   // login 5 only used in the single-user forms
-  /* eslint-disable no-unused-vars */
-  var login5 = new nsLoginInfo("https://example.com", "https://autocomplete2", null,
+  var login5 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete2", null,
                                "singleuser5", "singlepass5", "uname", "pword");
 
-  var login6A = new nsLoginInfo("https://example.com", "https://autocomplete3", null,
+  var login6A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null,
                                 "form7user1", "form7pass1", "uname", "pword");
-  var login6B = new nsLoginInfo("https://example.com", "https://autocomplete3", null,
+  var login6B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null,
                                 "form7user2", "form7pass2", "uname", "pword");
 
-  var login7  = new nsLoginInfo("https://example.com", "https://autocomplete4", null,
+  var login7  = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete4", null,
                                 "form8user", "form8pass", "uname", "pword");
 
-  var login8A = new nsLoginInfo("https://example.com", "https://autocomplete5", null,
+  var login8A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAB", "form9pass", "uname", "pword");
-  var login8B = new nsLoginInfo("https://example.com", "https://autocomplete5", null,
+  var login8B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAAB", "form9pass", "uname", "pword");
-  var login8C = new nsLoginInfo("https://example.com", "https://autocomplete5", null,
+  // Reference by `eval` in the message listeners below.
+  // eslint-disable-next-line no-unused-vars
+  var login8C = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null,
                                 "form9userAABzz", "form9pass", "uname", "pword");
 
-  var login10 = new nsLoginInfo("https://example.com", "https://autocomplete7", null,
+  var login10 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete7", null,
                                 "testuser10", "testpass10", "uname", "pword");
 
-  var login11 = new nsLoginInfo("https://example.com", "https://example.com", null,
-                                "testuser11", "testpass11", "uname", "pword");
-  /* eslint-enable no-unused-vars */
 
   // try/catch in case someone runs the tests manually, twice.
   try {
     Services.logins.addLogin(login0);
     Services.logins.addLogin(login1);
     Services.logins.addLogin(login2);
     Services.logins.addLogin(login3);
     Services.logins.addLogin(login4);
+    Services.logins.addLogin(login5);
+    Services.logins.addLogin(login6A);
+    Services.logins.addLogin(login6B);
+    Services.logins.addLogin(login7);
+    Services.logins.addLogin(login8A);
+    Services.logins.addLogin(login8B);
+    // login8C is added later
+    Services.logins.addLogin(login10);
   } catch (e) {
     assert.ok(false, "addLogin threw: " + e);
   }
 
   addMessageListener("addLogin", loginVariableName => {
     // eslint-disable-next-line no-eval
     let login = eval(loginVariableName);
     assert.ok(!!login, "Login to add is defined: " + loginVariableName);
@@ -94,23 +99,95 @@ var setupScript = runInParent(function s
 });
 </script>
 <p id="display"></p>
 
 <!-- we presumably can't hide the content for this test. -->
 <div id="content">
 
   <!-- form1 tests multiple matching logins -->
+  <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
   <!-- other forms test single logins, with autocomplete=off set -->
-  <form id="form1" action="https://autocomplete:8888/formtest.js" onsubmit="return false;">
+  <form id="form2" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword" autocomplete="off">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form3" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname" autocomplete="off">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form5" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname" autocomplete="off">
+    <input  type="password"   name="pword" autocomplete="off">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- control -->
+  <form id="form6" action="http://autocomplete2" onsubmit="return false;">
     <input  type="text"       name="uname">
     <input  type="password"   name="pword">
     <button type="submit">Submit</button>
   </form>
 
+  <!-- This form will be manipulated to insert a different username field. -->
+  <form id="form7" action="http://autocomplete3" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test for no autofill after onblur with blank username -->
+  <form id="form8" action="http://autocomplete4" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test autocomplete dropdown -->
+  <form id="form9" action="http://autocomplete5" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- tests <form>-less autocomplete -->
+  <div id="form11">
+     <input  type="text"       name="uname" id="uname">
+     <input  type="password"   name="pword" id="pword">
+     <button type="submit">Submit</button>
+  </div>
+
+  <!-- test for onUsernameInput recipe testing -->
+  <form id="form12" action="http://autocomplete7" onsubmit="return false;">
+    <input  type="text"   name="1">
+    <input  type="text"   name="2">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test not closing when the search string (.value) becomes empty -->
+  <form id="form13" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
+    <input  type="text"       name="uname" value="prefilled">
+    <input  type="password"   name="pword" value="prefilled">
+    <button type="submit">Submit</button>
+  </form>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Login Manager: multiple login autocomplete. **/
 
 var uname = $_(1, "uname");
@@ -163,17 +240,17 @@ add_task(async function test_form1_menui
 
   let popupState = await getPopupState();
   is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
 
   let expectedMenuItems = ["tempuser1",
                            "testuser2",
                            "testuser3",
                            "zzzuser4"];
-  checkAutoCompleteResults(results, expectedMenuItems, "example.com", "Check all menuitems are displayed correctly.");
+  checkAutoCompleteResults(results, expectedMenuItems, "mochi.test", "Check all menuitems are displayed correctly.");
 
   checkACForm("", ""); // value shouldn't update just by selecting
   synthesizeKey("KEY_Enter");
   await spinEventLoop(); // let focus happen
   checkACForm("", "");
 });
 
 add_task(async function test_form1_first_entry() {
@@ -386,28 +463,28 @@ add_task(async function test_form1_delet
 
   // XXX tried sending character "t" before/during dropdown to test
   // filtering, but had no luck. Seemed like the character was getting lost.
   // Setting uname.value didn't seem to work either. This works with a human
   // driver, so I'm not sure what's up.
 
   // Delete the first entry (of 4), "tempuser1"
   synthesizeKey("KEY_ArrowDown");
-  let numLogins = LoginManager.countLogins("https://example.com", "https://autocomplete:8888", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 5, "Correct number of logins before deleting one");
 
   let countChangedPromise = notifyMenuChanged(4);
   var deletionPromise = promiseStorageChanged(["removeLogin"]);
   // On OS X, shift-backspace and shift-delete work, just delete does not.
   // On Win/Linux, shift-backspace does not work, delete and shift-delete do.
   synthesizeKey("KEY_Delete", {shiftKey: true});
   await deletionPromise;
 
   checkACForm("", "");
-  numLogins = LoginManager.countLogins("https://example.com", "https://autocomplete:8888", null);
+  numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 4, "Correct number of logins after deleting one");
   await countChangedPromise;
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("testuser2", "testpass2");
 });
 
 add_task(async function test_form1_first_after_deletion() {
@@ -429,17 +506,17 @@ add_task(async function test_form1_delet
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
   // Delete the second entry (of 3), "testuser3"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("https://example.com", "https://autocomplete:8888", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 3, "Correct number of logins after deleting one");
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("zzzuser4", "zzzpass4");
 });
 
 add_task(async function test_form1_first_after_deletion2() {
   restoreForm();
@@ -461,17 +538,17 @@ add_task(async function test_form1_delet
   await shownPromise;
 
   /* test 54 */
   // Delete the last entry (of 2), "zzzuser4"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("https://example.com", "https://autocomplete:8888", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 2, "Correct number of logins after deleting one");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("testuser2", "testpass2");
 });
 
 add_task(async function test_form1_first_after_3_deletions() {
@@ -493,37 +570,25 @@ add_task(async function test_form1_check
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
   /* test 56 */
   // Delete the only remaining entry, "testuser2"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("https://example.com", "https://autocomplete:8888", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 1, "Correct number of logins after deleting one");
 
-  // remove the logins for the previous tests
+  // remove the login that's not shown in the list.
   setupScript.sendSyncMessage("removeLogin", "login0");
-  setupScript.sendSyncMessage("removeLogin", "login1");
-  setupScript.sendSyncMessage("removeLogin", "login2");
-  setupScript.sendSyncMessage("removeLogin", "login3");
-  setupScript.sendSyncMessage("removeLogin", "login4");
-  setupScript.sendSyncMessage("addLogin", "login5");
 });
 
 /* Tests for single-user forms for ignoring autocomplete=off */
 add_task(async function test_form2() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form2" action="https://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword" autocomplete="off">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   // Turn our attention to form2
   uname = $_(2, "uname");
   pword = $_(2, "pword");
   checkACForm("singleuser5", "singlepass5");
 
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
@@ -533,23 +598,16 @@ add_task(async function test_form2() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form3() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form3" action="https://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname" autocomplete="off">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(3, "uname");
   pword = $_(3, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -557,23 +615,16 @@ add_task(async function test_form3() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form4() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form4" action="https://autocomplete2" onsubmit="return false;" autocomplete="off">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(4, "uname");
   pword = $_(4, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -581,23 +632,16 @@ add_task(async function test_form4() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form5() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form5" action="https://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname" autocomplete="off">
-      <input  type="password"   name="pword" autocomplete="off">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(5, "uname");
   pword = $_(5, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -605,24 +649,16 @@ add_task(async function test_form5() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form6() {
-  await setFormAndWaitForFieldFilled(`
-    <!-- control -->
-    <form id="form6" action="https://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   // (this is a control, w/o autocomplete=off, to ensure the login
   // that was being suppressed would have been filled in otherwise)
   uname = $_(6, "uname");
   pword = $_(6, "pword");
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form6_changeUsername() {
@@ -630,32 +666,21 @@ add_task(async function test_form6_chang
   // the username.
   uname.focus();
   synthesizeKey("KEY_ArrowRight");
   synthesizeKey("X", {shiftKey: true});
   // Trigger the 'blur' event on uname
   pword.focus();
   await spinEventLoop();
   checkACForm("singleuser5X", "singlepass5");
-  uname.focus();
 
   setupScript.sendSyncMessage("removeLogin", "login5");
 });
 
 add_task(async function test_form7() {
-  setupScript.sendSyncMessage("addLogin", "login6A");
-  setupScript.sendSyncMessage("addLogin", "login6B");
-  await setFormAndWaitForFieldFilled(`
-    <!-- This form will be manipulated to insert a different username field. -->
-    <form id="form7" action="https://autocomplete3" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: ""});
-
   uname = $_(7, "uname");
   pword = $_(7, "pword");
   checkACForm("", "");
 
   // Insert a new username field into the form. We'll then make sure
   // that invoking the autocomplete doesn't try to fill the form.
   var newField = document.createElement("input");
   newField.setAttribute("type", "text");
@@ -686,31 +711,16 @@ add_task(async function test_form7_2() {
   checkACForm("form7user1", "");
   is($_(7, "uname2").value, "", "Verifying empty uname2");
   restoreForm(); // clear field, so reloading test doesn't fail
 
   setupScript.sendSyncMessage("removeLogin", "login6A");
 });
 
 add_task(async function test_form8() {
-  setupScript.sendSyncMessage("addLogin", "login7");
-  await setFormAndWaitForFieldFilled(`
-    <!-- This form will be manipulated to insert a different username field. -->
-    <form id="form7" action="https://autocomplete3" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>
-    <!-- test for no autofill after onblur with blank username -->
-    <form id="form8" action="https://autocomplete4" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "form8user", formId: "form8"});
-
   uname = $_(8, "uname");
   pword = $_(8, "pword");
   checkACForm("form8user", "form8pass");
   restoreForm();
 });
 
 add_task(async function test_form8_blur() {
   checkACForm("", "");
@@ -721,99 +731,77 @@ add_task(async function test_form8_blur(
 add_task(async function test_form8_2() {
   checkACForm("", "");
   restoreForm();
 });
 
 add_task(async function test_form8_3() {
   checkACForm("", "");
   setupScript.sendSyncMessage("removeLogin", "login7");
-  setupScript.sendSyncMessage("addLogin", "login8A");
-  setupScript.sendSyncMessage("addLogin", "login8B");
 });
 
 add_task(async function test_form9_filtering() {
-  await setFormAndWaitForFieldFilled(`
-    <!-- test autocomplete dropdown -->
-    <form id="form9" action="https://autocomplete5" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: ""});
-
   // Turn our attention to form9 to test the dropdown - bug 497541
   uname = $_(9, "uname");
   pword = $_(9, "pword");
   uname.focus();
   let shownPromise = promiseACShown();
   sendString("form9userAB");
   await shownPromise;
 
   checkACForm("form9userAB", "");
   uname.focus();
   synthesizeKey("KEY_ArrowLeft");
   shownPromise = promiseACShown();
   synthesizeKey("A", {shiftKey: true});
   let results = await shownPromise;
 
   checkACForm("form9userAAB", "");
-  checkAutoCompleteResults(results, ["form9userAAB"], "example.com", "Check dropdown is updated after inserting 'A'");
+  checkAutoCompleteResults(results, ["form9userAAB"], "mochi.test", "Check dropdown is updated after inserting 'A'");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("form9userAAB", "form9pass");
 });
 
 add_task(async function test_form9_autocomplete_cache() {
   // Note that this addLogin call will only be seen by the autocomplete
   // attempt for the synthesizeKey if we do not successfully cache the
   // autocomplete results.
   setupScript.sendSyncMessage("addLogin", "login8C");
   uname.focus();
   let promise1 = notifyMenuChanged(1);
   sendString("z");
   let results = await promise1;
-  checkAutoCompleteResults(results, [], "example.com", "Check popup does not have any login items");
+  checkAutoCompleteResults(results, [], "mochi.test", "Check popup does not have any login items");
 
   // check that empty results are cached - bug 496466
   promise1 = notifyMenuChanged(1);
   sendString("z");
   results = await promise1;
-  checkAutoCompleteResults(results, [], "example.com", "Check popup only has the footer when it opens");
+  checkAutoCompleteResults(results, [], "mochi.test", "Check popup only has the footer when it opens");
 });
 
 add_task(async function test_form11_formless() {
-  setupScript.sendSyncMessage("removeLogin", "login8A");
-  setupScript.sendSyncMessage("removeLogin", "login8B");
-  setupScript.sendSyncMessage("removeLogin", "login8C");
-  setupScript.sendSyncMessage("addLogin", "login11");
-  await setFormAndWaitForFieldFilled(`
-    <!-- tests <form>-less autocomplete -->
-    <div id="form11">
-      <input  type="text"       name="uname" id="uname">
-      <input  type="password"   name="pword" id="pword">
-      <button type="submit">Submit</button>
-    </div>`, {fieldSelector: `input[name="uname"]`, fieldValue: "testuser11"});
-
   // Test form-less autocomplete
   uname = $_(11, "uname");
   pword = $_(11, "pword");
   restoreForm();
   checkACForm("", "");
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
   // Trigger autocomplete
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   let processedPromise = promiseFormsProcessed();
   synthesizeKey("KEY_Enter");
   await processedPromise;
-  checkACForm("testuser11", "testpass11");
+  checkACForm("testuser", "testpass");
 });
 
 add_task(async function test_form11_open_on_trusted_focus() {
   uname = $_(11, "uname");
   pword = $_(11, "pword");
   uname.value = "";
   pword.value = "";
 
@@ -830,33 +818,23 @@ add_task(async function test_form11_open
   const shownPromise = promiseACShown();
   synthesizeMouseAtCenter(uname, {});
   await firePrivEventPromise;
   await shownPromise;
   synthesizeKey("KEY_ArrowDown");
   const processedPromise = promiseFormsProcessed();
   synthesizeKey("KEY_Enter");
   await processedPromise;
-  checkACForm("testuser11", "testpass11");
-  setupScript.sendSyncMessage("removeLogin", "login11");
+  checkACForm("testuser", "testpass");
 });
 
 add_task(async function test_form12_recipes() {
-  setupScript.sendSyncMessage("addLogin", "login10");
-  await setFormAndWaitForFieldFilled(`
-    <!-- test for onUsernameInput recipe testing -->
-    <form id="form12" action="https://autocomplete7" onsubmit="return false;">
-      <input  type="text"   name="1">
-      <input  type="text"   name="2">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="1"]`, fieldValue: ""});
-
   await loadRecipes({
     siteRecipes: [{
-      "hosts": ["example.com"],
+      "hosts": ["mochi.test:8888"],
       "usernameSelector": "input[name='1']",
       "passwordSelector": "input[name='2']",
     }],
   });
   uname = $_(12, "1");
   pword = $_(12, "2");
 
   // First test DOMAutocomplete
@@ -883,24 +861,16 @@ add_task(async function test_form12_reci
   checkACForm("testuser10", "");
   synthesizeKey("KEY_Tab");
   await promiseFormsProcessed();
   checkACForm("testuser10", "testpass10");
   await resetRecipes();
 });
 
 add_task(async function test_form13_stays_open_upon_empty_search() {
-  await setFormAndWaitForFieldFilled(`
-    <!-- test not closing when the search string (.value) becomes empty -->
-    <form id="form13" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
-      <input  type="text"       name="uname" value="prefilled">
-      <input  type="password"   name="pword" value="prefilled">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "prefilled"});
-
   uname = $_(13, "uname");
   pword = $_(13, "pword");
   checkACForm("prefilled", "prefilled");
 
   uname.scrollIntoView();
   let shownPromise = promiseACShown();
   synthesizeMouseAtCenter(uname, {});
   await shownPromise;
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete_formSubmitURL.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test that logins with non-matching formSubmitURL appear in autocomplete dropdown</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="text/javascript" src="/tests/SimpleTest/AddTask.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>
-<body>
-Login Manager test: logins with non-matching formSubmitURL appear in autocomplete dropdown
-
-<script>
-var chromeScript = runChecksAfterCommonInit();
-
-runInParent(function setup() {
-  const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-  // Create some logins just for this form, since we'll be deleting them.
-  var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
-                                           Ci.nsILoginInfo, "init");
-  assert.ok(nsLoginInfo != null, "nsLoginInfo constructor");
-
-  var login1 = new nsLoginInfo("https://example.com", "https://differentFormSubmitURL", null,
-                               "dfsu1", "dfsp1", "uname", "pword");
-
-  Services.logins.addLogin(login1);
-});
-</script>
-<p id="display"></p>
-
-<!-- we presumably can't hide the content for this test. -->
-<div id="content">
-
-  <!-- form1 tests multiple matching logins -->
-  <form id="form1" action="https://autocomplete:8888/formtest.js" onsubmit="return false;">
-    <input  type="text"       name="uname">
-    <input  type="password"   name="pword">
-    <button type="submit">Submit</button>
-  </form>
-</div>
-<pre id="test">
-<script class="testbody" type="text/javascript">
-
-/** Test for Login Manager: multiple login autocomplete. **/
-
-var uname = $_(1, "uname");
-var pword = $_(1, "pword");
-
-// Restore the form to the default state.
-function restoreForm() {
-  uname.value = "";
-  pword.value = "";
-  uname.focus();
-}
-
-// Check for expected username/password in form.
-function checkACForm(expectedUsername, expectedPassword) {
-  var formID = uname.parentNode.id;
-  is(uname.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername);
-  is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword);
-}
-
-function spinEventLoop() {
-  return Promise.resolve();
-}
-
-add_task(async function setup() {
-  listenForUnexpectedPopupShown();
-});
-
-add_task(async function test_form1_initial_empty() {
-  await SimpleTest.promiseFocus(window);
-
-  // Make sure initial form is empty.
-  checkACForm("", "");
-  let popupState = await getPopupState();
-  is(popupState.open, false, "Check popup is initially closed");
-});
-
-/* For this testcase, the only login that exists for this origin
- * is one with a different formSubmitURL, so the login will appear
- * in the autocomplete popup.
- */
-add_task(async function test_form1_menu_shows_logins_for_different_formSubmitURL() {
-  await SimpleTest.promiseFocus(window);
-  // Trigger autocomplete popup
-  restoreForm();
-  let shownPromise = promiseACShown();
-  synthesizeKey("KEY_ArrowDown"); // open
-  let results = await shownPromise;
-
-  let popupState = await getPopupState();
-  is(popupState.selectedIndex, -1, "Check no entries are selected upon opening");
-
-  let expectedMenuItems = ["dfsu1"];
-  checkAutoCompleteResults(results, expectedMenuItems, "example.com", "Check all menuitems are displayed correctly.");
-
-  synthesizeKey("KEY_ArrowDown"); // first item
-  checkACForm("", ""); // value shouldn't update just by selecting
-
-  synthesizeKey("KEY_Enter");
-  await promiseFormsProcessed();
-  checkACForm("dfsu1", "dfsp1");
-});
-</script>
-</pre>
-</body>
-</html>
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html
@@ -6,32 +6,37 @@ https://bugzilla.mozilla.org/show_bug.cg
 <head>
   <meta charset="utf-8"/>
   <title>Test for Bug 355063</title>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="pwmgr_common.js"></script>
   <script type="application/javascript">
   /** Test for Bug 355063 **/
-  gTestDependsOnDeprecatedLogin = true;
-  runChecksAfterCommonInit(async function startTest() {
+
+  runChecksAfterCommonInit(function startTest() {
     info("startTest");
     // Password Manager's own listener should always have been added first, so
     // the test's listener should be called after the pwmgr's listener fills in
     // a login.
     //
     SpecialPowers.addChromeEventListener("DOMFormHasPassword", function eventFired() {
       SpecialPowers.removeChromeEventListener("DOMFormHasPassword", eventFired);
       var passField = $("p1");
       passField.addEventListener("input", checkForm);
     });
-    await setFormAndWaitForFieldFilled("<form id=form1>form1: <input id=u1><input type=password id=p1></form><br>",
-                                       {fieldSelector: "#u1", fieldValue: "testuser"});
+    addForm();
   });
 
+  function addForm() {
+    info("addForm");
+    var c = document.getElementById("content");
+    c.innerHTML = "<form id=form1>form1: <input id=u1><input type=password id=p1></form><br>";
+  }
+
   function checkForm() {
     info("checkForm");
     var userField = document.getElementById("u1");
     var passField = document.getElementById("p1");
     is(userField.value, "testuser", "checking filled username");
     is(passField.value, "testpass", "checking filled password");
 
     SimpleTest.finish();
--- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html
@@ -5,17 +5,16 @@
   <title>Test forms and logins without a username</title>
   <script type="text/javascript" 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>
 Login Manager test: forms and logins without a username.
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 runInParent(() => {
   const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
   var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
 
   // pwlogin1 uses a unique formSubmitURL, to check forms where no other logins
   // will apply. pwlogin2 uses the normal formSubmitURL, so that we can test
   // forms with a mix of username and non-username logins that might apply.
--- a/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html
@@ -18,23 +18,23 @@ runChecksAfterCommonInit(false);
 
 SpecialPowers.loadChromeScript(function addLogins() {
   const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
   // Create some logins just for this form, since we'll be deleting them.
   var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
                                            Ci.nsILoginInfo, "init");
 
-  var login0 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "name", "pass", "uname", "pword");
 
-  var login1 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "Name", "Pass", "uname", "pword");
 
-  var login2 = new nsLoginInfo("https://example.com", "https://autocomplete:8888", null,
+  var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                "USER", "PASS", "uname", "pword");
 
   try {
     Services.logins.addLogin(login0);
     Services.logins.addLogin(login1);
     Services.logins.addLogin(login2);
   } catch (e) {
     assert.ok(false, "addLogin threw: " + e);
@@ -42,17 +42,17 @@ SpecialPowers.loadChromeScript(function 
 });
 </script>
 <p id="display"></p>
 
 <!-- we presumably can't hide the content for this test. -->
 <div id="content">
 
   <!-- form1 tests multiple matching logins -->
-  <form id="form1" action="https://autocomplete:8888/formtest.js" onsubmit="return false;">
+  <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
     <input  type="text"       name="uname">
     <input  type="password"   name="pword">
     <button type="submit">Submit</button>
   </form>
 
 </div>
 
 <pre id="test">
@@ -85,17 +85,17 @@ add_task(async function test_empty_first
   restoreForm();
   let popupState = await getPopupState();
   is(popupState.open, false, "Check popup is initially closed");
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown");
   let results = await shownPromise;
   popupState = await getPopupState();
   is(popupState.selectedIndex, -1, "Check no entries are selected");
-  checkAutoCompleteResults(results, ["name", "Name", "USER"], "example.com", "initial");
+  checkAutoCompleteResults(results, ["name", "Name", "USER"], "mochi.test", "initial");
 
   // Check first entry
   let index0Promise = notifySelectedIndex(0);
   synthesizeKey("KEY_ArrowDown");
   await index0Promise;
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
--- a/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html
@@ -5,17 +5,16 @@
   <title>Test for considering form action</title>
   <script type="text/javascript" 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>
 Login Manager test: Bug 360493
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 <div id="content" style="display: none">
 
   <!-- normal form with normal relative action. -->
   <form id="form1" action="formtest.js">
     <input  type="text"       name="uname">
--- a/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html
@@ -5,17 +5,16 @@
   <title>Test for considering form action</title>
   <script type="text/javascript" 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>
 Login Manager test: Bug 360493
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 <div id="content" style="display: none">
 
   <!-- The tests in this page exercise things that shouldn't work. -->
 
   <!-- Change port # of action URL from 8888 to 7777 -->
--- a/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html
@@ -8,17 +8,17 @@
   <script src="pwmgr_common.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script type="application/javascript">
 document.addEventListener("DOMContentLoaded", () => {
   document.getElementById("loginFrame").addEventListener("load", (evt) => {
     // Tell the parent to setup test logins.
-    PWMGR_COMMON_PARENT.sendAsyncMessage("setupParent", { selfFilling: true, testDependsOnDeprecatedLogin: true });
+    PWMGR_COMMON_PARENT.sendAsyncMessage("setupParent", { selfFilling: true });
   });
 });
 
 let doneSetupPromise = new Promise(resolve => {
   // When the setup is done, load a recipe for this test.
   PWMGR_COMMON_PARENT.addMessageListener("doneSetup", function doneSetup() {
     resolve();
   });
--- a/toolkit/components/passwordmgr/test/mochitest/test_input_events.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_input_events.html
@@ -6,17 +6,16 @@
   <script type="text/javascript" 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 onload="onNewEvent(event)">
 Login Manager test: input events should fire.
 
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit();
 
 SimpleTest.requestFlakyTimeout("untriaged");
 
 /** Test for Login Manager: form fill, should get input events. **/
 
 var usernameInputFired = false;
 var passwordInputFired = false;
--- a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html
@@ -35,17 +35,16 @@ var setupScript = runInParent(function s
                                   "testuser2", "testpass2", "uname", "pword");
 
   logins.login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                   "testuser3", "testpass3", "uname", "pword");
 
   logins.login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null,
                                   "zzzuser4", "zzzpass4", "uname", "pword");
 
-  // The following logins are added later
   // login 5 only used in the single-user forms
   logins.login5 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete2", null,
                                   "singleuser5", "singlepass5", "uname", "pword");
 
   logins.login6A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null,
                                    "form7user1", "form7pass1", "uname", "pword");
   logins.login6B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null,
                                    "form7user2", "form7pass2", "uname", "pword");
@@ -66,16 +65,24 @@ var setupScript = runInParent(function s
 
   // try/catch in case someone runs the tests manually, twice.
   try {
     Services.logins.addLogin(logins.login0);
     Services.logins.addLogin(logins.login1);
     Services.logins.addLogin(logins.login2);
     Services.logins.addLogin(logins.login3);
     Services.logins.addLogin(logins.login4);
+    Services.logins.addLogin(logins.login5);
+    Services.logins.addLogin(logins.login6A);
+    Services.logins.addLogin(logins.login6B);
+    Services.logins.addLogin(logins.login7);
+    Services.logins.addLogin(logins.login8A);
+    Services.logins.addLogin(logins.login8B);
+    // login8C is added later
+    Services.logins.addLogin(logins.login10);
   } catch (e) {
     assert.ok(false, "addLogin threw: " + e);
   }
 
   addMessageListener("addLogin", loginVariableName => {
     let login = logins[loginVariableName];
     assert.ok(!!login, "Login to add is defined: " + loginVariableName);
     Services.logins.addLogin(login);
@@ -94,16 +101,89 @@ var setupScript = runInParent(function s
 
   <!-- form1 tests multiple matching logins -->
   <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
     <input  type="text"       name="uname">
     <input  type="password"   name="pword">
     <button type="submit">Submit</button>
   </form>
 
+  <!-- other forms test single logins, with autocomplete=off set -->
+  <form id="form2" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword" autocomplete="off">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form3" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname" autocomplete="off">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <form id="form5" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname" autocomplete="off">
+    <input  type="password"   name="pword" autocomplete="off">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- control -->
+  <form id="form6" action="http://autocomplete2" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- This form will be manipulated to insert a different username field. -->
+  <form id="form7" action="http://autocomplete3" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test for no autofill after onblur with blank username -->
+  <form id="form8" action="http://autocomplete4" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test autocomplete dropdown -->
+  <form id="form9" action="http://autocomplete5" onsubmit="return false;">
+    <input  type="text"       name="uname">
+    <input  type="password"   name="pword">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- test for onUsernameInput recipe testing -->
+  <form id="form11" action="http://autocomplete7" onsubmit="return false;">
+    <input  type="text"   name="1">
+    <input  type="text"   name="2">
+    <button type="submit">Submit</button>
+  </form>
+
+  <!-- tests <form>-less autocomplete -->
+  <div id="form12">
+     <input  type="text"       name="uname" id="uname">
+     <input  type="password"   name="pword" id="pword">
+     <button type="submit">Submit</button>
+  </div>
+
+  <!-- test not closing when the search string (.value) becomes empty -->
+  <form id="form13" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
+    <input  type="text"       name="uname" value="prefilled">
+    <input  type="password"   name="pword" value="prefilled">
+    <button type="submit">Submit</button>
+  </form>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Login Manager: multiple login autocomplete. **/
 
 SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal", true]]});
@@ -396,28 +476,28 @@ add_task(async function test_form1_delet
   // filtering, but had no luck. Seemed like the character was getting lost.
   // Setting uname.value didn't seem to work either. This works with a human
   // driver, so I'm not sure what's up.
 
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   // Delete the first entry (of 4), "tempuser1"
   synthesizeKey("KEY_ArrowDown");
   var numLogins;
-  numLogins = LoginManager.countLogins("http://mochi.test:8888", "", null);
+  numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 5, "Correct number of logins before deleting one");
 
   let countChangedPromise = notifyMenuChanged(5);
   var deletionPromise = promiseStorageChanged(["removeLogin"]);
   // On OS X, shift-backspace and shift-delete work, just delete does not.
   // On Win/Linux, shift-backspace does not work, delete and shift-delete do.
   synthesizeKey("KEY_Delete", {shiftKey: true});
   await deletionPromise;
 
   checkACForm("", "");
-  numLogins = LoginManager.countLogins("http://mochi.test:8888", "", null);
+  numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 4, "Correct number of logins after deleting one");
   await countChangedPromise;
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("testuser2", "testpass2");
 });
 
 add_task(async function test_form1_first_after_deletion() {
@@ -441,17 +521,17 @@ add_task(async function test_form1_delet
   await shownPromise;
 
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   // Delete the second entry (of 3), "testuser3"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 3, "Correct number of logins after deleting one");
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("zzzuser4", "zzzpass4");
 });
 
 add_task(async function test_form1_first_after_deletion2() {
   restoreForm();
@@ -475,17 +555,17 @@ add_task(async function test_form1_delet
 
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   // test 54
   // Delete the last entry (of 2), "zzzuser4"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 2, "Correct number of logins after deleting one");
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("testuser2", "testpass2");
 });
 
@@ -510,34 +590,25 @@ add_task(async function test_form1_check
   await shownPromise;
 
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   // test 56
   // Delete the only remaining entry, "testuser2"
   synthesizeKey("KEY_ArrowDown");
   synthesizeKey("KEY_Delete", {shiftKey: true});
   checkACForm("", "");
-  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "", null);
+  let numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null);
   is(numLogins, 1, "Correct number of logins after deleting one");
 
   // remove the login that's not shown in the list.
   setupScript.sendSyncMessage("removeLogin", "login0");
 });
 
 // Tests for single-user forms for ignoring autocomplete=off
 add_task(async function test_form2() {
-  setupScript.sendSyncMessage("addLogin", "login5");
-  await setFormAndWaitForFieldFilled(`
-    <!-- other forms test single logins, with autocomplete=off set -->
-    <form id="form2" action="http://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword" autocomplete="off">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   // Turn our attention to form2
   uname = $_(2, "uname");
   pword = $_(2, "pword");
   checkACForm("singleuser5", "singlepass5");
 
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
@@ -548,23 +619,16 @@ add_task(async function test_form2() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form3() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form3" action="http://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname" autocomplete="off">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(3, "uname");
   pword = $_(3, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -573,23 +637,16 @@ add_task(async function test_form3() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form4() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(4, "uname");
   pword = $_(4, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -598,23 +655,16 @@ add_task(async function test_form4() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form5() {
-  await setFormAndWaitForFieldFilled(`
-    <form id="form5" action="http://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname" autocomplete="off">
-      <input  type="password"   name="pword" autocomplete="off">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   uname = $_(5, "uname");
   pword = $_(5, "pword");
   checkACForm("singleuser5", "singlepass5");
   restoreForm();
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
@@ -623,24 +673,16 @@ add_task(async function test_form5() {
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   synthesizeKey("KEY_Enter");
   await promiseFormsProcessed();
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form6() {
-  await setFormAndWaitForFieldFilled(`
-    <!-- control -->
-    <form id="form6" action="http://autocomplete2" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "singleuser5"});
-
   // (this is a control, w/o autocomplete=off, to ensure the login
   // that was being suppressed would have been filled in otherwise)
   uname = $_(6, "uname");
   pword = $_(6, "pword");
   checkACForm("singleuser5", "singlepass5");
 });
 
 add_task(async function test_form6_changeUsername() {
@@ -648,32 +690,21 @@ add_task(async function test_form6_chang
   // the username.
   uname.focus();
   synthesizeKey("KEY_ArrowRight");
   synthesizeKey("X", {shiftKey: true});
   // Trigger the 'blur' event on uname
   pword.focus();
   await spinEventLoop();
   checkACForm("singleuser5X", "singlepass5");
-  uname.focus();
 
   setupScript.sendSyncMessage("removeLogin", "login5");
 });
 
 add_task(async function test_form7() {
-  setupScript.sendSyncMessage("addLogin", "login6A");
-  setupScript.sendSyncMessage("addLogin", "login6B");
-  await setFormAndWaitForFieldFilled(`
-    <!-- This form will be manipulated to insert a different username field. -->
-    <form id="form7" action="http://autocomplete3" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: ""});
-
   uname = $_(7, "uname");
   pword = $_(7, "pword");
   checkACForm("", "");
 
   // Insert a new username field into the form. We'll then make sure
   // that invoking the autocomplete doesn't try to fill the form.
   var newField = document.createElement("input");
   newField.setAttribute("type", "text");
@@ -705,32 +736,16 @@ add_task(async function test_form7_2() {
   checkACForm("form7user1", "");
   is($_(7, "uname2").value, "", "Verifying empty uname2");
   restoreForm(); // clear field, so reloading test doesn't fail
 
   setupScript.sendSyncMessage("removeLogin", "login6A");
 });
 
 add_task(async function test_form8() {
-  setupScript.sendSyncMessage("addLogin", "login7");
-  await setFormAndWaitForFieldFilled(`
-    <!-- This form will be manipulated to insert a different username field. -->
-    <form id="form7" action="http://autocomplete3" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>
-    <!-- test for no autofill after onblur with blank username -->
-    <form id="form8" action="http://autocomplete4" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>
-    `, {fieldSelector: `#form8 input[name="uname"]`, fieldValue: "form8user"});
-
   uname = $_(8, "uname");
   pword = $_(8, "pword");
   checkACForm("form8user", "form8pass");
   restoreForm();
 });
 
 add_task(async function test_form8_blur() {
   checkACForm("", "");
@@ -744,26 +759,16 @@ add_task(async function test_form8_2() {
 });
 
 add_task(async function test_form8_3() {
   checkACForm("", "");
   setupScript.sendSyncMessage("removeLogin", "login7");
 });
 
 add_task(async function test_form9_filtering() {
-  setupScript.sendSyncMessage("addLogin", "login8A");
-  setupScript.sendSyncMessage("addLogin", "login8B");
-  await setFormAndWaitForFieldFilled(`
-    <!-- test autocomplete dropdown -->
-    <form id="form9" action="http://autocomplete5" onsubmit="return false;">
-      <input  type="text"       name="uname">
-      <input  type="password"   name="pword">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: ""});
-
   // Turn our attention to form9 to test the dropdown - bug 497541
   uname = $_(9, "uname");
   pword = $_(9, "pword");
   uname.focus();
   let shownPromise = promiseACShown();
   sendString("form9userAB");
   await shownPromise;
 
@@ -804,38 +809,26 @@ add_task(async function test_form9_autoc
   // check that empty results are cached - bug 496466
   promise2 = notifyMenuChanged(2);
   sendString("z");
   results = await promise2;
   checkAutoCompleteResults(results,
                            ["This connection is not secure. Logins entered here could be compromised. Learn More"],
                            "mochi.test",
                            "Check popup only has the footer and insecure warning");
-  setupScript.sendSyncMessage("removeLogin", "login8A");
-  setupScript.sendSyncMessage("removeLogin", "login8B");
-  setupScript.sendSyncMessage("removeLogin", "login8C");
 });
 
 add_task(async function test_form11_recipes() {
-  setupScript.sendSyncMessage("addLogin", "login10");
   await loadRecipes({
     siteRecipes: [{
       "hosts": ["mochi.test:8888"],
       "usernameSelector": "input[name='1']",
       "passwordSelector": "input[name='2']",
     }],
   });
-  await setFormAndWaitForFieldFilled(`
-    <!-- test for onUsernameInput recipe testing -->
-    <form id="form11" action="http://autocomplete7" onsubmit="return false;">
-      <input  type="text"   name="1">
-      <input  type="text"   name="2">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="1"]`, fieldValue: ""});
-
   uname = $_(11, "1");
   pword = $_(11, "2");
 
   // First test DOMAutocomplete
   // Switch the password field to type=password so _fillForm marks the username
   // field for autocomplete.
   pword.type = "password";
   await promiseFormsProcessed();
@@ -860,51 +853,35 @@ add_task(async function test_form11_reci
   synthesizeKey("KEY_Tab");
   await promiseFormsProcessed();
   checkACForm("testuser10", "testpass10");
   await resetRecipes();
 });
 
 add_task(async function test_form12_formless() {
   // Test form-less autocomplete
-  await setFormAndWaitForFieldFilled(`
-    <!-- tests <form>-less autocomplete -->
-    <div id="form12">
-      <input  type="text"       name="uname" id="uname">
-      <input  type="password"   name="pword" id="pword">
-      <button type="submit">Submit</button>
-    </div>`, {fieldSelector: `input[name="uname"]`, fieldValue: ""});
-
   uname = $_(12, "uname");
   pword = $_(12, "pword");
   restoreForm();
   checkACForm("", "");
   let shownPromise = promiseACShown();
   synthesizeKey("KEY_ArrowDown"); // open
   await shownPromise;
 
   synthesizeKey("KEY_ArrowDown"); // skip insecure warning
   // Trigger autocomplete
   synthesizeKey("KEY_ArrowDown");
   checkACForm("", ""); // value shouldn't update
   let processedPromise = promiseFormsProcessed();
   synthesizeKey("KEY_Enter");
   await processedPromise;
-  checkACForm("testuser10", "testpass10");
+  checkACForm("testuser", "testpass");
 });
 
 add_task(async function test_form13_stays_open_upon_empty_search() {
-  await setFormAndWaitForFieldFilled(`
-    <!-- test not closing when the search string (.value) becomes empty -->
-    <form id="form13" action="http://autocomplete:8888/formtest.js" onsubmit="return false;">
-      <input  type="text"       name="uname" value="prefilled">
-      <input  type="password"   name="pword" value="prefilled">
-      <button type="submit">Submit</button>
-    </form>`, {fieldSelector: `input[name="uname"]`, fieldValue: "prefilled"});
-
   uname = $_(13, "uname");
   pword = $_(13, "pword");
   checkACForm("prefilled", "prefilled");
 
   uname.scrollIntoView();
   let shownPromise = promiseACShown();
   synthesizeMouseAtCenter(uname, {});
   await shownPromise;
--- a/toolkit/components/passwordmgr/test/mochitest/test_master_password.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_master_password.html
@@ -24,17 +24,16 @@ Login Manager test: master password.
 "use strict";
 
 // Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
 isTabModal = false;
 
 var exampleCom = "https://example.com/tests/toolkit/components/passwordmgr/test/mochitest/";
 var exampleOrg = "https://example.org/tests/toolkit/components/passwordmgr/test/mochitest/";
 
-gTestDependsOnDeprecatedLogin = true;
 var chromeScript = runChecksAfterCommonInit();
 
 runInParent(() => {
   const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
   var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
 
   var login1 = new nsLoginInfo();
--- a/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html
@@ -5,17 +5,16 @@
   <title>Test for maxlength attributes</title>
   <script type="text/javascript" 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>
 Login Manager test: Bug 391514
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 <div id="content" style="display: none">
   <!-- normal form. -->
   <form id="form1" action="formtest.js">
     <input  type="text"     name="uname">
     <input  type="password" name="pword">
--- a/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html
@@ -5,17 +5,16 @@
   <title>Test that passwords only get filled in type=password</title>
   <script type="text/javascript" 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>
 Login Manager test: Bug 242956
 <script>
-gTestDependsOnDeprecatedLogin = true;
 runChecksAfterCommonInit(() => startTest());
 </script>
 <p id="display"></p>
 <div id="content" style="display: none">
   <!-- pword is not a type=password input -->
   <form id="form1" action="formtest.js">
     <input  type="text" name="uname">
     <input  type="text" name="pword">
--- a/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html
@@ -5,17 +5,16 @@
   <title>Test for recipes overriding login fields</title>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <script src="/tests/SimpleTest/AddTask.js"></script>
   <script src="pwmgr_common.js"></script>
   <link rel="stylesheet" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script>
-gTestDependsOnDeprecatedLogin = true;
 var chromeScript = runChecksAfterCommonInit();
 
 let fillPromiseResolvers = [];
 
 function waitForFills(fillCount) {
   let promises = [];
   while (fillCount--) {
     let promise = new Promise(resolve => fillPromiseResolvers.push(resolve));