Backed out changesets 5115d7a4ff78 and 21e02fc102b4 (bug 1255265) for test_notifications_popup.html timeouts.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 10 Mar 2016 22:28:52 -0500
changeset 288069 79256f612a533ea5b5556ed7ff79ed854803ecc7
parent 288068 af1e95751534576a804b4dd5e9f39950a2684b69
child 288070 14c09980119bfa4e09ee5895ffd60678777c190f
child 288083 102886e9ac63b3fa33a6f1b394aea054abce2dfd
push id18127
push userryanvm@gmail.com
push dateFri, 11 Mar 2016 03:29:22 +0000
treeherderfx-team@79256f612a53 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1255265
milestone48.0a1
backs out5115d7a4ff786a07d82f16733c3aa7a4ece12318
21e02fc102b4e8f4e56ce649e89723f25b446c5a
Backed out changesets 5115d7a4ff78 and 21e02fc102b4 (bug 1255265) for test_notifications_popup.html timeouts.
toolkit/components/passwordmgr/test/LoginTestUtils.jsm
toolkit/components/passwordmgr/test/browser/browser.ini
toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js
toolkit/components/passwordmgr/test/browser/browser_context_menu.js
toolkit/components/passwordmgr/test/browser/browser_filldoorhanger.js
toolkit/components/passwordmgr/test/browser/browser_notifications.js
toolkit/components/passwordmgr/test/browser/head.js
toolkit/components/passwordmgr/test/mochitest.ini
toolkit/components/passwordmgr/test/notification_common.js
toolkit/components/passwordmgr/test/subtst_notifications_7.html
toolkit/components/passwordmgr/test/test_notifications.html
--- a/toolkit/components/passwordmgr/test/LoginTestUtils.jsm
+++ b/toolkit/components/passwordmgr/test/LoginTestUtils.jsm
@@ -238,20 +238,8 @@ this.LoginTestUtils.testData = {
 
       new LoginInfo("chrome://example_extension", null, "Example Login One",
                     "the username", "the password one", "", ""),
       new LoginInfo("chrome://example_extension", null, "Example Login Two",
                     "the username", "the password two", "", ""),
     ];
   },
 };
-
-this.LoginTestUtils.recipes = {
-  getRecipeParent() {
-    let { LoginManagerParent } = Cu.import("resource://gre/modules/LoginManagerParent.jsm", {});
-    if (!LoginManagerParent.recipeParentPromise) {
-      return null;
-    }
-    return LoginManagerParent.recipeParentPromise.then((recipeParent) => {
-      return recipeParent;
-    });
-  },
-};
--- a/toolkit/components/passwordmgr/test/browser/browser.ini
+++ b/toolkit/components/passwordmgr/test/browser/browser.ini
@@ -1,31 +1,17 @@
 [DEFAULT]
 support-files =
-  ../formsubmit.sjs
-  ../subtst_notifications_1.html
-  ../subtst_notifications_2.html
-  ../subtst_notifications_2pw_0un.html
-  ../subtst_notifications_2pw_1un_1text.html
-  ../subtst_notifications_3.html
-  ../subtst_notifications_4.html
-  ../subtst_notifications_5.html
-  ../subtst_notifications_6.html
-  ../subtst_notifications_8.html
-  ../subtst_notifications_9.html
-  ../subtst_notifications_10.html
   authenticate.sjs
   form_basic.html
-  head.js
   insecure_test.html
   insecure_test_subframe.html
   multiple_forms.html
   streamConverter_content.sjs
 
-[browser_capture_doorhanger.js]
 [browser_DOMFormHasPassword.js]
 [browser_DOMInputPasswordAdded.js]
 [browser_filldoorhanger.js]
 [browser_hasInsecureLoginForms.js]
 [browser_hasInsecureLoginForms_streamConverter.js]
 [browser_notifications.js]
 skip-if = true # Intermittent failures: Bug 1182296, bug 1148771
 [browser_passwordmgr_editing.js]
--- a/toolkit/components/passwordmgr/test/browser/browser_context_menu.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_context_menu.js
@@ -1,14 +1,16 @@
 /*
  * Test the password manager context menu.
  */
 
 "use strict";
 
+Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
+
 // The hostname for the test URIs.
 const TEST_HOSTNAME = "https://example.com";
 const MULTIPLE_FORMS_PAGE_PATH = "/browser/toolkit/components/passwordmgr/test/browser/multiple_forms.html";
 
 /**
  * Initialize logins needed for the tests and disable autofill
  * for login forms for easier testing of manual fill.
  */
--- a/toolkit/components/passwordmgr/test/browser/browser_filldoorhanger.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_filldoorhanger.js
@@ -1,8 +1,13 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
+
 /**
  * All these tests require the experimental login fill UI to be enabled. We also
  * disable autofill for login forms for easier testing of manual fill.
  */
 add_task(function* test_initialize() {
   Services.prefs.setBoolPref("signon.ui.experimental", true);
   Services.prefs.setBoolPref("signon.autofillForms", false);
   registerCleanupFunction(function () {
--- a/toolkit/components/passwordmgr/test/browser/browser_notifications.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_notifications.js
@@ -1,9 +1,13 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
 Cu.import("resource://testing-common/ContentTaskUtils.jsm", this);
+Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
 /**
  * Test that the doorhanger notification for password saving is populated with
  * the correct values in various password capture cases.
  */
 add_task(function* test_save_change() {
   let testCases = [{
     username: "username",
     password: "password",
deleted file mode 100644
--- a/toolkit/components/passwordmgr/test/browser/head.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const DIRECTORY_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";
-
-Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
-
-registerCleanupFunction(function* cleanup_removeAllLoginsAndResetRecipes() {
-  Services.logins.removeAllLogins();
-  let recipeParent = LoginTestUtils.recipes.getRecipeParent();
-  if (!recipeParent) {
-    // No need to reset the recipes if the recipe module wasn't even loaded.
-    return;
-  }
-  yield recipeParent.then(recipeParent => recipeParent.reset());
-});
-
-/**
- * Loads a test page in `DIRECTORY_URL` which automatically submits to formsubmit.sjs and returns a
- * promise resolving with the field values when the optional `aTaskFn` is done.
- *
- * @param {String} aPageFile - test page file name which auto-submits to formsubmit.sjs
- * @param {Function} aTaskFn - task which can be run before the tab closes.
- * @param {String} [aOrigin="http://mochi.test:8888"] - origin of the server to
- *                                                      use to load `aPageFile`.
- */
-function testSubmittingLoginForm(aPageFile, aTaskFn, aOrigin = "http://mochi.test:8888") {
-  return BrowserTestUtils.withNewTab({
-    gBrowser,
-    url: aOrigin + DIRECTORY_PATH + aPageFile,
-  }, function*(browser) {
-    ok(true, "loaded " + aPageFile);
-    let fieldValues = yield ContentTask.spawn(browser, undefined, function*() {
-      yield ContentTaskUtils.waitForCondition(() => {
-        return content.location.pathname.endsWith("/formsubmit.sjs") &&
-          content.document.readyState == "complete";
-      }, "Wait for form submission load (formsubmit.sjs)");
-      let username = content.document.getElementById("user").textContent;
-      let password = content.document.getElementById("pass").textContent;
-      return {
-        username,
-        password,
-      };
-    });
-    ok(true, "form submission loaded");
-    if (aTaskFn) {
-      yield* aTaskFn(fieldValues);
-    }
-    return fieldValues;
-  });
-}
-
-function checkOnlyLoginWasUsedTwice({ justChanged }) {
-  // Check to make sure we updated the timestamps and use count on the
-  // existing login that was submitted for the test.
-  let logins = Services.logins.getAllLogins();
-  is(logins.length, 1, "Should only have 1 login");
-  ok(logins[0] instanceof Ci.nsILoginMetaInfo, "metainfo QI");
-  is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
-  ok(logins[0].timeCreated < logins[0].timeLastUsed, "timeLastUsed bumped");
-  if (justChanged) {
-    is(logins[0].timeLastUsed, logins[0].timePasswordChanged, "timeLastUsed == timePasswordChanged");
-  } else {
-    is(logins[0].timeCreated, logins[0].timePasswordChanged, "timeChanged not updated");
-  }
-}
-
-// Begin popup notification (doorhanger) functions //
-
-const REMEMBER_BUTTON = 0;
-const NEVER_BUTTON = 1;
-
-const CHANGE_BUTTON = 0;
-const DONT_CHANGE_BUTTON = 1;
-
-/**
- * Checks if we have a password capture popup notification
- * of the right type and with the right label.
- *
- * @param {String} aKind The desired `passwordNotificationType`
- * @return the found password popup notification.
- */
-function getCaptureDoorhanger(aKind) {
-  ok(true, "Looking for " + aKind + " popup notification");
-  let notification = PopupNotifications.getNotification("password");
-  if (notification) {
-    is(notification.options.passwordNotificationType, aKind, "Notification type matches.");
-    if (aKind == "password-change") {
-      is(notification.mainAction.label, "Update", "Main action label matches update doorhanger.");
-    } else if (aKind == "password-save") {
-      is(notification.mainAction.label, "Remember", "Main action label matches save doorhanger.");
-    }
-  }
-  return notification;
-}
-
-/**
- * Clicks the specified popup notification button.
- *
- * @param {Element} aPopup Popup Notification element
- * @param {Number} aButtonIndex Number indicating which button to click.
- *                              See the constants in this file.
- */
-function clickDoorhangerButton(aPopup, aButtonIndex) {
-  ok(true, "Looking for action at index " + aButtonIndex);
-
-  let notifications = aPopup.owner.panel.childNodes;
-  ok(notifications.length > 0, "at least one notification displayed");
-  ok(true, notifications.length + " notification(s)");
-  let notification = notifications[0];
-
-  if (aButtonIndex == 0) {
-    ok(true, "Triggering main action");
-    notification.button.doCommand();
-  } else if (aButtonIndex <= aPopup.secondaryActions.length) {
-    ok(true, "Triggering secondary action " + aButtonIndex);
-    notification.childNodes[aButtonIndex].doCommand();
-  }
-}
-
-// End popup notification (doorhanger) functions //
--- a/toolkit/components/passwordmgr/test/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest.ini
@@ -4,18 +4,30 @@ support-files =
   authenticate.sjs
   blank.html
   formsubmit.sjs
   notification_common.js
   privbrowsing_perwindowpb_iframe.html
   prompt_common.js
   pwmgr_common.js
   subtst_master_pass.html
+  subtst_notifications_1.html
+  subtst_notifications_10.html
   subtst_notifications_11.html
   subtst_notifications_11_popup.html
+  subtst_notifications_2.html
+  subtst_notifications_2pw_0un.html
+  subtst_notifications_2pw_1un_1text.html
+  subtst_notifications_3.html
+  subtst_notifications_4.html
+  subtst_notifications_5.html
+  subtst_notifications_6.html
+  subtst_notifications_7.html
+  subtst_notifications_8.html
+  subtst_notifications_9.html
   subtst_privbrowsing_1.html
   subtst_privbrowsing_2.html
   subtst_privbrowsing_3.html
   subtst_privbrowsing_4.html
   subtst_prompt_async.html
   auth2/authenticate.sjs
 
 [test_autofill_before_load.html]
@@ -44,16 +56,18 @@ skip-if = toolkit == 'android' #TIMED_OU
 [test_form_action_javascript.html]
 [test_input_events.html]
 [test_input_events_for_identical_values.html]
 [test_master_password.html]
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_master_password_cleanup.html]
 skip-if = toolkit == 'android'
 [test_maxlength.html]
+[test_notifications.html]
+skip-if = toolkit == 'android'
 [test_notifications_popup.html]
 skip-if = os == "linux" || toolkit == 'android' # bug 934057
 [test_passwords_in_type_password.html]
 [test_prompt.html]
 skip-if = os == "linux" || toolkit == 'android' #TIMED_OUT
 [test_prompt_async.html]
 skip-if = toolkit == 'android' #TIMED_OUT
 [test_xhr.html]
--- a/toolkit/components/passwordmgr/test/notification_common.js
+++ b/toolkit/components/passwordmgr/test/notification_common.js
@@ -32,17 +32,16 @@ function getPopupNotifications(aWindow) 
     return popupNotifications;
 }
 
 
 /**
  * Checks if we have a password popup notification
  * of the right type and with the right label.
  *
- * @deprecated Write a browser-chrome test instead and use the fork of this method there.
  * @returns the found password popup notification.
  */
 function getPopup(aPopupNote, aKind) {
     ok(true, "Looking for " + aKind + " popup notification");
     var notification = aPopupNote.getNotification("password");
     if (notification) {
       is(notification.options.passwordNotificationType, aKind, "Notification type matches.");
       if (aKind == "password-change") {
@@ -50,18 +49,18 @@ function getPopup(aPopupNote, aKind) {
       } else if (aKind == "password-save") {
         is(notification.mainAction.label, "Remember", "Main action label matches save doorhanger.");
       }
     }
     return notification;
 }
 
 
-/**
- * @deprecated - Use a browser chrome test instead.
+/*
+ * clickPopupButton
  *
  * Clicks the specified popup notification button.
  */
 function clickPopupButton(aPopup, aButtonIndex) {
     ok(true, "Looking for action at index " + aButtonIndex);
 
     var notifications = SpecialPowers.wrap(aPopup.owner).panel.childNodes;
     ok(notifications.length > 0, "at least one notification displayed");
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/subtst_notifications_7.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Subtest for Login Manager notifications</title>
+</head>
+<body>
+<h2>Subtest 7</h2>
+<form id="form" action="formsubmit.sjs">
+  <input id="user" name="user">
+  <input id="pass" name="pass" type="password">
+  <button type='submit'>Submit</button>
+</form>
+
+<script>
+function submitForm() {
+  userField.value = "nowisthetimeforallgoodmentocometotheaidoftheircountry";
+  passField.value = "notifyp1";
+  form.submit();
+}
+
+window.onload = submitForm;
+var form      = document.getElementById("form");
+var userField = document.getElementById("user");
+var passField = document.getElementById("pass");
+
+</script>
+</body>
+</html>
rename from toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js
rename to toolkit/components/passwordmgr/test/test_notifications.html
--- a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js
+++ b/toolkit/components/passwordmgr/test/test_notifications.html
@@ -1,410 +1,619 @@
-/*
- * Test capture popup notifications
- */
-
-const BRAND_BUNDLE = Services.strings.createBundle("chrome://branding/locale/brand.properties");
-const BRAND_SHORT_NAME = BRAND_BUNDLE.GetStringFromName("brandShortName");
-
-let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
-                                             Ci.nsILoginInfo, "init");
-let login1 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
-                             "notifyu1", "notifyp1", "user", "pass");
-let login2 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
-                             "", "notifyp1", "", "pass");
-let login1B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
-                              "notifyu1B", "notifyp1B", "user", "pass");
-let login2B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
-                              "", "notifyp1B", "", "pass");
-
-requestLongerTimeout(2);
-
-add_task(function* setup() {
-  // Load recipes for this test.
-  let recipeParent = yield LoginManagerParent.recipeParentPromise;
-  yield recipeParent.load({
-    siteRecipes: [{
-      hosts: ["example.org"],
-      usernameSelector: "#user",
-      passwordSelector: "#pass",
-    }],
-  });
-});
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Login Manager</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="pwmgr_common.js"></script>
+  <script type="text/javascript" src="notification_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+Login Manager test: notifications
+<p id="display"></p>
 
-add_task(function* test_remember_opens() {
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-});
+<div id="content" style="display: none">
+  <iframe id="iframe"></iframe>
+</div>
 
-add_task(function* test_clickNever() {
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    is(true, Services.logins.getLoginSavingEnabled("http://mochi.test:8888"),
-       "Checking for login saving enabled");
-    clickDoorhangerButton(notif, NEVER_BUTTON);
-  });
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.8">
 
-  info("Make sure Never took effect");
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-    is(false, Services.logins.getLoginSavingEnabled("http://mochi.test:8888"),
-       "Checking for login saving disabled");
-    Services.logins.setLoginSavingEnabled("http://mochi.test:8888", true);
-  });
-});
+/** Test for Login Manager: notifications. **/
+
+const { Services } = SpecialPowers.Cu.import("resource://gre/modules/Services.jsm");
 
-add_task(function* test_clickRemember() {
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
+const BRAND_BUNDLE = "chrome://branding/locale/brand.properties";
 
-    is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet");
-    clickDoorhangerButton(notif, REMEMBER_BUTTON);
-  });
+// Set testpath to the directory where we live. Used to load tests from
+// alternate Mochitest servers (different hostnames, same content).
+var testpath = document.location.pathname + "/../";
 
-  info("Make sure Remember took effect and we don't prompt for an existing login");
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-  });
-
-  checkOnlyLoginWasUsedTwice({ justChanged: false });
-
-  // remove that login
-  Services.logins.removeLogin(login1);
-});
-
-/* signons.rememberSignons pref tests... */
-
-add_task(function* test_rememberSignonsFalse() {
-  info("Make sure we don't prompt with rememberSignons=false");
-  Services.prefs.setBoolPref("signon.rememberSignons", false);
-
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-  });
-});
-
-add_task(function* test_rememberSignonsTrue() {
-  info("Make sure we prompt with rememberSignons=true");
-  Services.prefs.setBoolPref("signon.rememberSignons", true);
+var subtests = [
+                   "subtst_notifications_1.html", // 1
+                   "subtst_notifications_1.html", // 2
+                   "subtst_notifications_1.html", // 3
+                   "subtst_notifications_1.html", // 4
+                   "subtst_notifications_1.html", // 5
+                   "subtst_notifications_1.html", // 6
+                   "subtst_notifications_1.html", // 7
+                   "subtst_notifications_1.html", // 8
+                   "subtst_notifications_2.html", // 9
+                   "subtst_notifications_3.html", // 10
+                   "subtst_notifications_4.html", // 11
+                   "subtst_notifications_5.html", // 12
+                   "subtst_notifications_1.html", // 13
+                   "subtst_notifications_6.html", // 14
+                   "subtst_notifications_1.html", // 15
+                   "subtst_notifications_6.html", // 16
+                   "subtst_notifications_8.html", // 17
+                   "subtst_notifications_8.html", // 18
+                   "subtst_notifications_9.html", // 19
+                   "subtst_notifications_10.html",  // 20
+                   "http://test1.example.org:80" + testpath + "subtst_notifications_1.html", // 21
+                   "http://test1.example.org:80" + testpath + "subtst_notifications_7.html", // 22
+                   "http://test1.example.org:80" + testpath + "subtst_notifications_6.html", // 23
+                   "subtst_notifications_2pw_0un.html",  // 24
+                   "subtst_notifications_2pw_0un.html",  // 25
+                   "subtst_notifications_2pw_0un.html",  // 26
+                   "subtst_notifications_2pw_0un.html",  // 27
+                   "subtst_notifications_2pw_0un.html",  // 28
+                   "http://example.org" + testpath + "subtst_notifications_2pw_1un_1text.html", // 29
+                   "http://example.org" + testpath + "subtst_notifications_2pw_1un_1text.html", // 30
+                   "subtst_notifications_1.html", // 31
+               ];
 
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-});
 
-/* autocomplete=off tests... */
-
-add_task(function* test_autocompleteOffUsername() {
-  info("Check for notification popup when autocomplete=off present on username");
-
-  yield testSubmittingLoginForm("subtst_notifications_2.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "checking for notification popup");
-    notif.remove();
-  });
-});
+var ignoreLoad = false;
+function handleLoad(aEvent) {
+    // ignore every other load event ... We get one for loading the subtest (which
+    // we want to ignore), and another when the subtest's form submits itself
+    // (which we want to handle, to start the next test).
+    ignoreLoad = !ignoreLoad;
+    if (ignoreLoad) {
+        ok(true, "Ignoring load of subtest #" + testNum);
+        return;
+    }
+    ok(true, "Processing submission of subtest #" + testNum);
 
-add_task(function* test_autocompleteOffPassword() {
-  info("Check for notification popup when autocomplete=off present on password");
+    checkTest();
 
-  yield testSubmittingLoginForm("subtst_notifications_3.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "checking for notification popup");
-    notif.remove();
-  });
-});
+    testNum++;
 
-add_task(function* test_autocompleteOffForm() {
-  info("Check for notification popup when autocomplete=off present on form");
-
-  yield testSubmittingLoginForm("subtst_notifications_4.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "checking for notification popup");
-    notif.remove();
-  });
-});
+    if (testNum <= subtests.length) {
+        ok(true, "Starting test #" + testNum);
+        iframe.src = subtests[testNum-1];
+    } else {
+        ok(true, "notification tests finished.");
+        SimpleTest.finish();
+    }
+}
 
 
-add_task(function* test_noPasswordField() {
-  info("Check for no notification popup when no password field present");
+// Remember, Never for This Site, Not Now
+function checkTest() {
+    var popup, notificationText, expectedText;
+
+    // The document generated from formsubmit.sjs contains the user/pass it
+    // received inside <span id="blah">value</span>
+    var gotUser = SpecialPowers.wrap(iframe).contentDocument.getElementById("user").textContent;
+    var gotPass = SpecialPowers.wrap(iframe).contentDocument.getElementById("pass").textContent;
+
+    let brandBundle = Services.strings.createBundle(BRAND_BUNDLE);
+    let brandShortName = brandBundle.GetStringFromName("brandShortName");
+
+    switch(testNum) {
+
+      /* Basic Yes/No/Never tests... */
+
+      case 1:
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        popup.remove();
+        break;
+
+      case 2:
+        // Same subtest, this time click Never
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        is(true, pwmgr.getLoginSavingEnabled("http://mochi.test:8888"),
+           "Checking for login saving enabled");
+        clickPopupButton(popup, kNeverButton);
+        break;
+
+      case 3:
+        // Same subtest, make sure Never took effect
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+        is(false, pwmgr.getLoginSavingEnabled("http://mochi.test:8888"),
+           "Checking for login saving disabled");
+        // reenable login saving.
+        pwmgr.setLoginSavingEnabled("http://mochi.test:8888", true);
+        break;
+
+      case 4:
+        // Same subtest, this time click Remember
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+
+        // Sanity check, no logins should exist yet.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 0, "Should not have any logins yet");
+
+        clickPopupButton(popup, kRememberButton);
+        break;
+
+      case 5:
+        // Same subtest, make sure we didn't prompt for an existing login.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+
+        // Check to make sure we updated the timestamps and use count on the
+        // existing login that was submitted for this form.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
+        ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
+        ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
+
+        // remove that login
+        pwmgr.removeLogin(login1);
+        break;
+
+      /* signons.rememberSignons pref tests... */
+
+      case 6:
+        // Same subtest, make sure we're getting the popup again.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        popup.remove();
+        // Change prefs to no longer remember signons
+        prefs.setBoolPref("rememberSignons", false);
+        break;
+
+      case 7:
+        // Same subtest, make sure we're not prompting.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+        // Change prefs to remember signons again
+        prefs.setBoolPref("rememberSignons", true);
+        break;
+
+      case 8:
+        // Same subtest, make sure we're getting the popup again.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        popup.remove();
+        break;
+
+      /* autocomplete=off tests... */
+
+      case 9:
+        // Check for notification popup when autocomplete=off present
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "checking for notification popup");
+        popup.remove();
+        break;
 
-  yield testSubmittingLoginForm("subtst_notifications_5.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "null", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-  });
-});
+      case 10:
+        // Check for notification popup when autocomplete=off present
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "checking for notification popup");
+        popup.remove();
+        break;
+
+      case 11:
+        // Check for notification popup when autocomplete=off present
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "checking for notification popup");
+        popup.remove();
+        break;
+
+      /* no password field test... */
+
+      case 12:
+        // Check for no notification popup when no password field present
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "null",     "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+
+        // Add login for the next test.
+        pwmgr.addLogin(login2);
+        break;
+
+      case 13:
+        // Check for update popup when existing pw-only login matches form.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "checking for notification popup");
+        popup.remove();
+        pwmgr.removeLogin(login2);
+
+        // Add login for the next test
+        pwmgr.addLogin(login1);
+        break;
+
+      case 14:
+        // Check for no notification popup when pw-only form matches existing login.
+        is(gotUser, "null",     "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+        pwmgr.removeLogin(login1);
+
+        // Add login for the next test
+        pwmgr.addLogin(login2B);
+        break;
+
+      case 15:
+        // Check for notification popup when existing pw-only login doesn't match form.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        pwmgr.removeLogin(login2B);
+        popup.remove();
 
-add_task(function* test_pwOnlyLoginMatchesForm() {
-  info("Check for update popup when existing pw-only login matches form.");
-  Services.logins.addLogin(login2);
+        // Add login for the next test
+        pwmgr.addLogin(login1B);
+        break;
+
+      case 16:
+        // Check for notification popup when pw-only form doesn't match existing login.
+        is(gotUser, "null",     "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        pwmgr.removeLogin(login1B);
+        popup.remove();
+
+        // Add login for the next tests
+        pwmgr.addLogin(login1);
+        break;
+
+      case 17:
+        // Check for change-password popup, u+p login on u+p form. (not changed)
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "pass2",    "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        clickPopupButton(popup, kDontChangeButton);
+        break;
+
+      case 18:
+        // Check for change-password popup, u+p login on u+p form.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "pass2",    "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        clickPopupButton(popup, kChangeButton);
+
+        // Check to make sure we updated the timestamps and use count for
+        // the login being changed with this form.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].timesUsed, 2, "check .timesUsed incremented on change");
+        ok(logins[0].timeCreated < logins[0].timeLastUsed, "timeLastUsed bumped");
+        ok(logins[0].timeLastUsed == logins[0].timePasswordChanged, "timeUsed == timeChanged");
+
+        // cleanup
+        login1.password = "pass2";
+        pwmgr.removeLogin(login1);
+        login1.password = "notifyp1";
+
+        // Add login for the next test
+        pwmgr.addLogin(login2);
+        break;
+
+      // ...can't change a u+p login on a p-only form...
+
+      case 19:
+        // Check for change-password popup, p-only login on u+p form.
+        // (needed a different subtest for this because the login created in
+        // test_0init was interfering)
+        is(gotUser, "",         "Checking submitted username");
+        is(gotPass, "pass2",    "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        clickPopupButton(popup, kChangeButton);
+        break;
 
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "checking for notification popup");
-    notif.remove();
-  });
+      case 20:
+        // Check for change-password popup, p-only login on p-only form.
+        is(gotUser, "null",     "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        clickPopupButton(popup, kChangeButton);
+
+        pwmgr.removeLogin(login2);
+        break;
+
+      case 21:
+        // Check text on a user+pass notification popup
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        // Check the text, which comes from the localized saveLoginText string.
+        notificationText = popup.message;
+        expectedText = "Would you like " + brandShortName + " to remember this login?";
+        is(expectedText, notificationText, "Checking text: " + notificationText);
+        popup.remove();
+        break;
+
+      case 22:
+        // Check text on a user+pass notification popup, username is really long
+        is(gotUser, "nowisthetimeforallgoodmentocometotheaidoftheircountry", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        // Check the text, which comes from the localized saveLoginText string.
+        notificationText = popup.message;
+        expectedText = "Would you like " + brandShortName + " to remember this login\?";
+        is(expectedText, notificationText, "Checking text: " + notificationText);
+        popup.remove();
+        break;
+
+      case 23:
+        // Check text on a pass-only notification popup
+        is(gotUser, "null",     "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        // Check the text, which comes from the localized saveLoginTextNoUser string.
+        notificationText = popup.message;
+        expectedText = "Would you like " + brandShortName + " to remember this password\?";
+        is(expectedText, notificationText, "Checking text: " + notificationText);
+        popup.remove();
+        break;
+
+      case 24:
+        // Check for notification popup when a form with 2 password fields (no username) is
+        // submitted and there are no saved logins.
+        is(gotUser, "null", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+        popup.remove();
+
+        // Add login for the next test
+        pwmgr.addLogin(login1B);
+        break;
 
-  Services.logins.removeLogin(login2);
-});
+      case 25:
+        // Check for notification popup when a form with 2 password fields (no username) is
+        // submitted and there is a saved login with a username and different password.
+        is(gotUser, "null", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        popup.remove();
+        // remove that login
+        pwmgr.removeLogin(login1B);
+
+        // Add login for the next test
+        pwmgr.addLogin(login2B);
+        break;
+
+      case 26:
+        // Check for notification popup when a form with 2 password fields (no username) is
+        // submitted and there is a saved login with no username and a different password.
+        is(gotUser, "null", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(popup, "got notification popup");
+        popup.remove();
+        // remove that login
+        pwmgr.removeLogin(login2B);
+
+        // Add login for the next test
+        pwmgr.addLogin(login1);
+
+        break;
+
+      case 27:
+        // Check for no notification popup when a form with 2 password fields (no username) is
+        // submitted and there is a saved login with a username and the same password.
+        is(gotUser, "null", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(!popup, "checking for no notification popup");
+
+        // Check to make sure we updated the timestamps and use count on the
+        // existing login that was submitted for this form.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
+        ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
+        ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
+
+        // remove that login
+        pwmgr.removeLogin(login1);
+
+        // Add login for the next test
+        pwmgr.addLogin(login2);
+        break;
+
+      case 28:
+        // Check for no notification popup when a form with 2 password fields (no username) is
+        // submitted and there is a saved login with no username and the same password.
+        is(gotUser, "null", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-change");
+        ok(!popup, "checking for no notification popup");
 
-add_task(function* test_pwOnlyFormMatchesLogin() {
-  info("Check for no notification popup when pw-only form matches existing login.");
-  Services.logins.addLogin(login1);
+        // Check to make sure we updated the timestamps and use count on the
+        // existing login that was submitted for this form.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
+        ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
+        ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
+
+        // remove that login
+        pwmgr.removeLogin(login2);
+        break;
+
+      case 29: {
+        // Check that we capture the proper fields when a field recipe is in use.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(popup, "got notification popup");
+
+        // Sanity check, no logins should exist yet.
+        let logins = pwmgr.getAllLogins();
+        is(logins.length, 0, "Should not have any logins yet");
+
+        clickPopupButton(popup, kRememberButton);
+        break;
+      }
+
+      case 30: {
+        // Same subtest, make sure we didn't prompt for an existing login.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
+
+        // Check to make sure we updated the timestamps and use count on the
+        // existing login that was submitted for this form.
+        let logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].username, "notifyu1", "check .username for existing login submission");
+        is(logins[0].password, "notifyp1", "check .password for existing login submission");
+        is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
+        ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
+        ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
+
+        // remove the added login
+        pwmgr.removeAllLogins();
+
+        // Add login for the next test
+        pwmgr.addLogin(login3);
+
+        break;
+      }
+
+      case 31: {
+        // make sure we didn't prompt for an existing login with different
+        // scheme for formSubmitURL.
+        is(gotUser, "notifyu1", "Checking submitted username");
+        is(gotPass, "notifyp1", "Checking submitted password");
+        popup = getPopup(popupNotifications, "password-save");
+        ok(!popup, "checking for no notification popup");
 
-  yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-  });
+        // Check to make sure we updated the timestamps and use count on the
+        // existing login that was submitted for this form.
+        var logins = pwmgr.getAllLogins();
+        is(logins.length, 1, "Should only have 1 login");
+        ok(SpecialPowers.call_Instanceof(logins[0], Ci.nsILoginMetaInfo), "metainfo QI");
+        is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
+        ok(logins[0].timeLastUsed > logins[0].timeCreated, "timeLastUsed bumped");
+        ok(logins[0].timeCreated == logins[0].timePasswordChanged, "timeChanged not updated");
+
+        // remove that login
+        pwmgr.removeAllLogins();
+        break;
+      }
+      default:
+        ok(false, "Unexpected call to checkTest for test #" + testNum);
+
+    }
+
+    // TODO:
+    // * existing login test, form has different password --> change password, no save prompt
+}
+
+const Ci = SpecialPowers.Ci;
+const Cc = SpecialPowers.Cc;
+ok(Ci != null, "Access Ci");
+ok(Cc != null, "Access Cc");
+
+var pwmgr = Cc["@mozilla.org/login-manager;1"].
+            getService(Ci.nsILoginManager);
+ok(pwmgr != null, "Access pwmgr");
+
+pwmgr.removeAllLogins();
 
-  Services.logins.removeLogin(login1);
+var prefs = Cc["@mozilla.org/preferences-service;1"].
+            getService(Ci.nsIPrefService);
+ok(prefs != null, "Access prefs");
+prefs = prefs.getBranch("signon.");
+ok(prefs != null, "Access pref branch");
+
+var nsLoginInfo = new SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1",
+                                             Ci.nsILoginInfo, "init");
+var login1 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
+                             "notifyu1", "notifyp1", "user", "pass");
+var login2 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
+                             "", "notifyp1", "", "pass");
+var login1B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
+                              "notifyu1B", "notifyp1B", "user", "pass");
+var login2B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
+                              "", "notifyp1B", "", "pass");
+var login3 = new nsLoginInfo("http://mochi.test:8888", "https://mochi.test:8888", null,
+                             "notifyu1", "notifyp1", "user", "pass");
+
+var parentScriptURL = SimpleTest.getTestFileURL("pwmgr_common.js");
+var mm = SpecialPowers.loadChromeScript(parentScriptURL);
+
+var iframe = document.getElementById("iframe");
+iframe.onload = handleLoad;
+
+// popupNotifications (not *popup*) is a constant, per-tab container. So, we
+// only need to fetch it once.
+var popupNotifications = getPopupNotifications(window.top);
+ok(popupNotifications, "Got popupNotifications");
+
+var testNum = 1;
+
+// Load recipes for this test.
+mm.sendAsyncMessage("loadRecipes", {
+  siteRecipes: [{
+    hosts: ["example.org"],
+    usernameSelector: "#user",
+    passwordSelector: "#pass",
+  }],
 });
 
-add_task(function* test_pwOnlyFormDoesntMatchExisting() {
-  info("Check for notification popup when pw-only form doesn't match existing login.");
-  Services.logins.addLogin(login1B);
-
-  yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-
-  Services.logins.removeLogin(login1B);
-});
-
-add_task(function* test_changeUPLoginOnUPForm_dont() {
-  info("Check for change-password popup, u+p login on u+p form. (not changed)");
-  Services.logins.addLogin(login1);
-
-  yield testSubmittingLoginForm("subtst_notifications_8.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "pass2", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    clickDoorhangerButton(notif, DONT_CHANGE_BUTTON);
-  });
-
-  Services.logins.removeLogin(login1);
-});
-
-add_task(function* test_changeUPLoginOnUPForm_change() {
-  info("Check for change-password popup, u+p login on u+p form.");
-  Services.logins.addLogin(login1);
-
-  yield testSubmittingLoginForm("subtst_notifications_8.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "pass2", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    clickDoorhangerButton(notif, CHANGE_BUTTON);
-    ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
-  });
-
-  checkOnlyLoginWasUsedTwice({ justChanged: true });
-
-  // cleanup
-  login1.password = "pass2";
-  Services.logins.removeLogin(login1);
-  login1.password = "notifyp1";
-});
-
-add_task(function* test_changePLoginOnUPForm() {
-  info("Check for change-password popup, p-only login on u+p form.");
-  Services.logins.addLogin(login2);
-
-  yield testSubmittingLoginForm("subtst_notifications_9.html", function*(fieldValues) {
-    is(fieldValues.username, "", "Checking submitted username");
-    is(fieldValues.password, "pass2", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    clickDoorhangerButton(notif, CHANGE_BUTTON);
-    ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
-  });
-});
-
-add_task(function* test_changePLoginOnPForm() {
-  info("Check for change-password popup, p-only login on p-only form.");
-
-  yield testSubmittingLoginForm("subtst_notifications_10.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    clickDoorhangerButton(notif, CHANGE_BUTTON);
-    ok(!getCaptureDoorhanger("password-change"), "popup should be gone");
-  });
-  Services.logins.removeLogin(login2);
-});
-
-add_task(function* test_checkUPSaveText() {
-  info("Check text on a user+pass notification popup");
-
-  yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    // Check the text, which comes from the localized saveLoginText string.
-    let notificationText = notif.message;
-    let expectedText = "Would you like " + BRAND_SHORT_NAME + " to remember this login?";
-    is(expectedText, notificationText, "Checking text: " + notificationText);
-    notif.remove();
-  });
-});
-
-add_task(function* test_checkPSaveText() {
-  info("Check text on a pass-only notification popup");
+mm.addMessageListener("loadedRecipes", function loadedRecipes() {
+  ok(true, "Starting test #" + testNum);
+  iframe.src = subtests[testNum-1];
+})
 
-  yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    // Check the text, which comes from the localized saveLoginTextNoUser string.
-    let notificationText = notif.message;
-    let expectedText = "Would you like " + BRAND_SHORT_NAME + " to remember this password?";
-    is(expectedText, notificationText, "Checking text: " + notificationText);
-    notif.remove();
-  });
-});
-
-add_task(function* test_capture2pw0un() {
-  info("Check for notification popup when a form with 2 password fields (no username) " +
-       "is submitted and there are no saved logins.");
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-});
-
-add_task(function* test_change2pw0unExistingDifferentUP() {
-  info("Check for notification popup when a form with 2 password fields (no username) " +
-       "is submitted and there is a saved login with a username and different password.");
-
-  Services.logins.addLogin(login1B);
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-
-  Services.logins.removeLogin(login1B);
-});
-
-add_task(function* test_change2pw0unExistingDifferentP() {
-  info("Check for notification popup when a form with 2 password fields (no username) " +
-       "is submitted and there is a saved login with no username and different password.");
-
-  Services.logins.addLogin(login2B);
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(notif, "got notification popup");
-    notif.remove();
-  });
-
-  Services.logins.removeLogin(login2B);
-});
-
-add_task(function* test_change2pw0unExistingWithSameP() {
-  info("Check for no notification popup when a form with 2 password fields (no username) " +
-       "is submitted and there is a saved login with a username and the same password.");
-
-  Services.logins.addLogin(login2);
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) {
-    is(fieldValues.username, "null", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-change");
-    ok(!notif, "checking for no notification popup");
-  });
-
-  checkOnlyLoginWasUsedTwice({ justChanged: false });
-
-  Services.logins.removeLogin(login2);
-});
-
-add_task(function* test_recipeCaptureFields_NewLogin() {
-  info("Check that we capture the proper fields when a field recipe is in use.");
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_1un_1text.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(notif, "got notification popup");
-
-    // Sanity check, no logins should exist yet.
-    let logins = Services.logins.getAllLogins();
-    is(logins.length, 0, "Should not have any logins yet");
-
-    clickDoorhangerButton(notif, REMEMBER_BUTTON);
-  }, "http://example.org"); // The recipe is for example.org
-});
-
-add_task(function* test_recipeCaptureFields_ExistingLogin() {
-  info("Check that we capture the proper fields when a field recipe is in use " +
-       "and there is a matching login");
-
-  yield testSubmittingLoginForm("subtst_notifications_2pw_1un_1text.html", function*(fieldValues) {
-    is(fieldValues.username, "notifyu1", "Checking submitted username");
-    is(fieldValues.password, "notifyp1", "Checking submitted password");
-    let notif = getCaptureDoorhanger("password-save");
-    ok(!notif, "checking for no notification popup");
-  }, "http://example.org");
-
-  checkOnlyLoginWasUsedTwice({ justChanged: false });
-  let logins = Services.logins.getAllLogins();
-  is(logins[0].username, "notifyu1", "check .username for existing login submission");
-  is(logins[0].password, "notifyp1", "check .password for existing login submission");
-
-  Services.logins.removeAllLogins();
-});
-
-// TODO:
-// * existing login test, form has different password --> change password, no save prompt
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>