Bug 1298543 - Fix test_prompt_http.html for e10s. r=dolske draft
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Thu, 08 Sep 2016 02:12:25 -0700
changeset 413347 a069824d8eca91e57b9f406848a05cf746746081
parent 413272 82d0a583a9a39bf0b0000bccbf6d5c9ec2596bcc
child 413348 a8ded35039e204fe7004455226117d4eecb47465
push id29421
push usermozilla@noorenberghe.ca
push dateWed, 14 Sep 2016 06:15:42 +0000
reviewersdolske
bugs1298543
milestone51.0a1
Bug 1298543 - Fix test_prompt_http.html for e10s. r=dolske Don't actually test doorhanger notifications since they are only on the desktop browser and browser chrome tests already check them. The Android notifyObservers additions aren't used in this patch but I added them for consistency and because we should start to use them for cross-platform tests that check if a doorhanger appears. MozReview-Commit-ID: B5wK8oqu0h7
mobile/android/components/LoginManagerPrompter.js
toolkit/components/passwordmgr/nsLoginManagerPrompter.js
toolkit/components/passwordmgr/test/chrome/chrome.ini
toolkit/components/passwordmgr/test/chrome/notification_common.js
toolkit/components/passwordmgr/test/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html
toolkit/components/passwordmgr/test/notification_common.js
toolkit/components/passwordmgr/test/pwmgr_common.js
--- a/mobile/android/components/LoginManagerPrompter.js
+++ b/mobile/android/components/LoginManagerPrompter.js
@@ -124,16 +124,17 @@ LoginManagerPrompter.prototype = {
 
   /*
    * promptToSavePassword
    *
    */
   promptToSavePassword : function (aLogin) {
     this._showSaveLoginNotification(aLogin);
       Services.telemetry.getHistogramById("PWMGR_PROMPT_REMEMBER_ACTION").add(PROMPT_DISPLAYED);
+    Services.obs.notifyObservers(aLogin, "passwordmgr-prompt-save", null);
   },
 
   /*
    * _showLoginNotification
    *
    * Displays a notification doorhanger.
    * @param aBody
    *        String message to be displayed in the doorhanger
@@ -223,16 +224,18 @@ LoginManagerPrompter.prototype = {
    * Called when we think we detect a password change for an existing
    * login, when the form being submitted contains multiple password
    * fields.
    *
    */
   promptToChangePassword : function (aOldLogin, aNewLogin) {
     this._showChangeLoginNotification(aOldLogin, aNewLogin.password);
     Services.telemetry.getHistogramById("PWMGR_PROMPT_UPDATE_ACTION").add(PROMPT_DISPLAYED);
+    let oldGUID = aOldLogin.QueryInterface(Ci.nsILoginMetaInfo).guid;
+    Services.obs.notifyObservers(aNewLogin, "passwordmgr-prompt-change", oldGUID);
   },
 
   /*
    * _showChangeLoginNotification
    *
    * Shows the Change Password notification doorhanger.
    *
    */
--- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
+++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js
@@ -1060,16 +1060,18 @@ LoginManagerPrompter.prototype = {
           popup:     null,
           callback:  function() { /* NOP */ }
         }
       ];
 
       this._showLoginNotification(aNotifyObj, "password-save",
                                   notificationText, buttons);
     }
+
+    Services.obs.notifyObservers(aLogin, "passwordmgr-prompt-save", null);
   },
 
   _removeLoginNotifications : function () {
     var popupNote = this._getPopupNote();
     if (popupNote)
       popupNote = popupNote.getNotification("password");
     if (popupNote)
       popupNote.remove();
@@ -1139,16 +1141,18 @@ LoginManagerPrompter.prototype = {
       this._pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
     } else if (userChoice == 0) {
       this.log("Saving login for " + aLogin.hostname);
       this._pwmgr.addLogin(aLogin);
     } else {
       // userChoice == 1 --> just ignore the login.
       this.log("Ignoring login.");
     }
+
+    Services.obs.notifyObservers(aLogin, "passwordmgr-prompt-save", null);
   },
 
 
   /**
    * Called when we think we detect a password or username change for
    * an existing login, when the form being submitted contains multiple
    * password fields.
    *
@@ -1230,16 +1234,19 @@ LoginManagerPrompter.prototype = {
             // do nothing
           }
         }
       ];
 
       this._showLoginNotification(aNotifyObj, "password-change",
                                   notificationText, buttons);
     }
+
+    let oldGUID = aOldLogin.QueryInterface(Ci.nsILoginMetaInfo).guid;
+    Services.obs.notifyObservers(aNewLogin, "passwordmgr-prompt-change", oldGUID);
   },
 
 
   /**
    * Shows the Change Password dialog.
    */
   _showChangeLoginDialog(aOldLogin, aNewLogin) {
     const buttonFlags = Ci.nsIPrompt.STD_YES_NO_BUTTONS;
@@ -1260,16 +1267,19 @@ LoginManagerPrompter.prototype = {
     var ok = !this._promptService.confirmEx(this._chromeWindow,
                             dialogTitle, dialogText, buttonFlags,
                             null, null, null,
                             null, {});
     if (ok) {
       this.log("Updating password for user " + aOldLogin.username);
       this._updateLogin(aOldLogin, aNewLogin);
     }
+
+    let oldGUID = aOldLogin.QueryInterface(Ci.nsILoginMetaInfo).guid;
+    Services.obs.notifyObservers(aNewLogin, "passwordmgr-prompt-change", oldGUID);
   },
 
 
   /**
    * Called when we detect a password change in a form submission, but we
    * don't know which existing login (username) it's for. Asks the user
    * to select a username and confirm the password change.
    *
--- a/toolkit/components/passwordmgr/test/chrome/chrome.ini
+++ b/toolkit/components/passwordmgr/test/chrome/chrome.ini
@@ -1,13 +1,13 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g' || os == 'android'
 
 [test_privbrowsing_perwindowpb.html]
 skip-if = true # Bug 1173337
 support-files =
   ../formsubmit.sjs
-  ../notification_common.js
+  notification_common.js
   privbrowsing_perwindowpb_iframe.html
   subtst_privbrowsing_1.html
   subtst_privbrowsing_2.html
   subtst_privbrowsing_3.html
   subtst_privbrowsing_4.html
rename from toolkit/components/passwordmgr/test/notification_common.js
rename to toolkit/components/passwordmgr/test/chrome/notification_common.js
--- a/toolkit/components/passwordmgr/test/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest.ini
@@ -1,15 +1,14 @@
 [DEFAULT]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
 support-files =
   authenticate.sjs
   blank.html
   formsubmit.sjs
-  notification_common.js
   prompt_common.js
   pwmgr_common.js
   subtst_master_pass.html
   subtst_prompt_async.html
 
 [test_master_password.html]
 skip-if = toolkit == 'android' # Tests desktop prompts
 [test_prompt_async.html]
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -4,17 +4,16 @@ support-files =
   ../../../prompts/test/chromeScript.js
   ../../../prompts/test/prompt_common.js
   ../../../satchel/test/parent_utils.js
   ../../../satchel/test/satchel_common.js
   ../authenticate.sjs
   ../blank.html
   ../browser/form_basic.html
   ../browser/form_cross_origin_secure_action.html
-  ../notification_common.js
   ../pwmgr_common.js
   auth2/authenticate.sjs
 
 [test_autocomplete_https_upgrade.html]
 skip-if = toolkit == 'android' # autocomplete
 [test_autofill_https_upgrade.html]
 skip-if = toolkit == 'android' # Bug 1259768
 [test_autofill_password-only.html]
@@ -44,15 +43,15 @@ skip-if = toolkit == 'android' # autocom
 [test_formless_submit_navigation_negative.html]
 [test_input_events.html]
 [test_input_events_for_identical_values.html]
 [test_maxlength.html]
 [test_passwords_in_type_password.html]
 [test_prompt.html]
 skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_prompt_http.html]
-skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts
+skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_prompt_promptAuth.html]
 skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_prompt_promptAuth_proxy.html]
 skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts
 [test_recipe_login_fields.html]
 [test_xhr_2.html]
--- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html
@@ -2,17 +2,16 @@
 <html>
 <head>
   <meta charset="utf-8">
   <title>Test HTTP auth prompts by loading authenticate.sjs</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="text/javascript" src="pwmgr_common.js"></script>
   <script type="text/javascript" src="prompt_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>
 <p id="display"></p>
 
 <div id="content" style="display: none">
   <iframe id="iframe"></iframe>
 </div>
@@ -141,50 +140,23 @@ add_task(function* test_iframe() {
     defButton   : "button0",
   };
   action = {
     buttonClick : "ok",
     passField   : "mochipass1-new",
   };
   promptDone = handlePrompt(state, action);
   iframeLoaded = onloadPromiseFor("iframe");
+  let promptShownPromise = promisePromptShown("passwordmgr-prompt-change");
   iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1-new";
   yield promptDone;
   yield iframeLoaded;
   checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1-new"},
                       iframe.contentDocument);
-
-
-  var pwchanged = promiseStorageChanged(["modifyLogin"]);
-
-  // Check for the popup notification, and change the password.
-  var popupNotifications = getPopupNotifications(window.top);
-  popup = getPopup(popupNotifications, "password-change");
-  ok(popup, "got popup notification");
-  clickPopupButton(popup, kChangeButton);
-  popup.remove();
-
-  yield pwchanged;
-
-  // Housekeeping: change it back
-  runInParent(() => {
-    const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-    Cu.import("resource://gre/modules/Services.jsm");
-
-    var tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
-                   createInstance(Ci.nsILoginInfo);
-    tmpLogin.init("http://mochi.test:8888", null, "mochitest",
-                  "mochiuser1", "mochipass1-new", "", "");
-    var login3A = Cc["@mozilla.org/login-manager/loginInfo;1"].
-                  createInstance(Ci.nsILoginInfo);
-    login3A.init("http://mochi.test:8888", null, "mochitest",
-                 "mochiuser1", "mochipass1", "", "");
-
-    Services.logins.modifyLogin(tmpLogin, login3A);
-  });
+  yield promptShownPromise;
 
   // Same as last test, but for a realm we haven't already authenticated
   // to (but have an existing saved login for, so that we'll trigger
   // a change-password popup notification.
   state = {
     msg         : "http://mochi.test:8888 is requesting your username and password.\n\nThe site says: “mochitest3”",
     title       : "Authentication Required",
     textValue   : "mochiuser3",
@@ -200,42 +172,33 @@ add_task(function* test_iframe() {
     defButton   : "button0",
   };
   action = {
     buttonClick : "ok",
     passField   : "mochipass3-new",
   };
   promptDone = handlePrompt(state, action);
   iframeLoaded = onloadPromiseFor("iframe");
+  promptShownPromise = promisePromptShown("passwordmgr-prompt-change");
   iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-new&realm=mochitest3";
   yield promptDone;
   yield iframeLoaded;
   checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-new"},
                       iframe.contentDocument);
-
-  pwchanged = promiseStorageChanged(["modifyLogin"]);
+  yield promptShownPromise;
 
-  // Check for the popup notification, and change the password.
-  popup = getPopup(popupNotifications, "password-change");
-  ok(popup, "got popup notification");
-  clickPopupButton(popup, kChangeButton);
-  popup.remove();
-
-  yield pwchanged;
-
-  // Housekeeping: change it back to the original login4. Actually,
-  // just delete it and we'll re-add it as the next test.
+  // Housekeeping: Delete login4 to test the save prompt in the next test.
   runInParent(() => {
     const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
     Cu.import("resource://gre/modules/Services.jsm");
 
     var tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
                    createInstance(Ci.nsILoginInfo);
     tmpLogin.init("http://mochi.test:8888", null, "mochitest3",
-                  "mochiuser3", "mochipass3-new", "", "");
+                  "mochiuser3", "mochipass3-old", "", "");
     Services.logins.removeLogin(tmpLogin);
 
     // Clear cached auth from this subtest, and avoid leaking due to bug 459620.
     var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
                   getService(Ci.nsIHttpAuthManager);
     authMgr.clearAll();
   });
 
@@ -258,27 +221,20 @@ add_task(function* test_iframe() {
     buttonClick : "ok",
     textField   : "mochiuser3",
     passField   : "mochipass3-old",
   };
   // Trigger a new prompt, so we can test adding a new login.
   promptDone = handlePrompt(state, action);
 
   iframeLoaded = onloadPromiseFor("iframe");
+  promptShownPromise = promisePromptShown("passwordmgr-prompt-save");
   iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3";
   yield promptDone;
   yield iframeLoaded;
   checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-old"},
                       iframe.contentDocument);
-
-  var pwsaved = promiseStorageChanged(["addLogin"]);
-
-  // Check for the popup notification, and change the password.
-  popup = getPopup(popupNotifications, "password-save");
-  ok(popup, "got popup notification");
-  clickPopupButton(popup, kRememberButton);
-  popup.remove();
-  yield pwsaved;
+  yield promptShownPromise;
 });
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/components/passwordmgr/test/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/pwmgr_common.js
@@ -315,16 +315,27 @@ function promiseStorageChanged(expectedC
         chromeScript.removeMessageListener("storageChanged", onStorageChanged);
         resolve();
       }
     }
     chromeScript.addMessageListener("storageChanged", onStorageChanged);
   });
 }
 
+function promisePromptShown(expectedTopic) {
+  return new Promise((resolve, reject) => {
+    function onPromptShown({ topic, data }) {
+      is(topic, expectedTopic, "Check expected prompt topic");
+      chromeScript.removeMessageListener("promptShown", onPromptShown);
+      resolve();
+    }
+    chromeScript.addMessageListener("promptShown", onPromptShown);
+  });
+}
+
 /**
  * Run a function synchronously in the parent process and destroy it in the test cleanup function.
  * @param {Function|String} aFunctionOrURL - either a function that will be stringified and run
  *                                           or the URL to a JS file.
  * @return {Object} - the return value of loadChromeScript providing message-related methods.
  *                    @see loadChromeScript in specialpowersAPI.js
  */
 function runInParent(aFunctionOrURL) {
@@ -367,16 +378,25 @@ if (this.addMessageListener) {
   function onStorageChanged(subject, topic, data) {
     sendAsyncMessage("storageChanged", {
       topic,
       data,
     });
   }
   Services.obs.addObserver(onStorageChanged, "passwordmgr-storage-changed", false);
 
+  function onPrompt(subject, topic, data) {
+    sendAsyncMessage("promptShown", {
+      topic,
+      data,
+    });
+  }
+  Services.obs.addObserver(onPrompt, "passwordmgr-prompt-change", false);
+  Services.obs.addObserver(onPrompt, "passwordmgr-prompt-save", false);
+
   addMessageListener("setupParent", ({selfFilling = false} = {selfFilling: false}) => {
     // Force LoginManagerParent to init for the tests since it's normally delayed
     // by apps such as on Android.
     LoginManagerParent.init();
 
     commonInit(selfFilling);
     sendAsyncMessage("doneSetup");
   });
@@ -427,16 +447,28 @@ if (this.addMessageListener) {
 
       let authMgr = Cc["@mozilla.org/network/http-auth-manager;1"].
                     getService(Ci.nsIHttpAuthManager);
       authMgr.clearAll();
 
       if (LoginManagerParent._recipeManager) {
         LoginManagerParent._recipeManager.reset();
       }
+
+      // Cleanup PopupNotifications (if on a relevant platform)
+      let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
+      if (chromeWin && chromeWin.PopupNotifications) {
+        let notes = chromeWin.PopupNotifications._currentNotifications;
+        if (notes.length > 0) {
+          dump("Removing " + notes.length + " popup notifications.\n");
+        }
+        for (let note of notes) {
+	  note.remove();
+        }
+      }
     });
   });
 
 
   let { LoginHelper } = SpecialPowers.Cu.import("resource://gre/modules/LoginHelper.jsm", {});
   /**
    * Proxy for Services.logins (nsILoginManager).
    * Only supports arguments which support structured clone plus {nsILoginInfo}