Bug 1269039 - Make test_master_password.html work with e10s. r=dolske
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Fri, 29 Apr 2016 17:26:59 -0700
changeset 515248 f9282e1de3b7057de3434e36da7f9e23f301c3f9
parent 515247 ce50b241dbe2663535efce3e11ebf80c115985cf
child 515249 c82a419aff342341f3ffa6e0acd581d9833fdd48
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs1269039
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1269039 - Make test_master_password.html work with e10s. r=dolske MozReview-Commit-ID: 2LZ4EjI8MHW
testing/mochitest/tests/SimpleTest/AddTask.js
toolkit/components/passwordmgr/test/mochitest/mochitest.ini
toolkit/components/passwordmgr/test/mochitest/test_master_password.html
toolkit/components/passwordmgr/test/pwmgr_common.js
toolkit/components/prompts/test/prompt_common.js
--- a/testing/mochitest/tests/SimpleTest/AddTask.js
+++ b/testing/mochitest/tests/SimpleTest/AddTask.js
@@ -70,19 +70,19 @@ var add_task = (function () {
               let result = await task();
               if (isGenerator(result)) {
                 ok(false, "Task returned a generator");
               }
               info("AddTask.js | Leaving test " + name);
             }
           } catch (ex) {
             try {
-              ok(false, "" + ex, "Should not throw any errors", ex.stack);
+              SimpleTest.record(false, "" + ex, "Should not throw any errors", ex.stack);
             } catch (ex2) {
-              ok(false, "(The exception cannot be converted to string.)",
+              SimpleTest.record(false, "(The exception cannot be converted to string.)",
                  "Should not throw any errors", ex.stack);
             }
           }
           // All tasks are finished.
           SimpleTest.finish();
         })();
       });
     }
--- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
+++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini
@@ -58,17 +58,18 @@ skip-if = toolkit == 'android' # autocom
 skip-if = toolkit == 'android' && debug # bug 1397615
 [test_formless_submit_navigation.html]
 skip-if = toolkit == 'android' && debug # bug 1397615
 [test_formless_submit_navigation_negative.html]
 skip-if = toolkit == 'android' && debug # bug 1397615
 [test_input_events.html]
 [test_input_events_for_identical_values.html]
 [test_master_password.html]
-skip-if = toolkit == 'android' || e10s # Tests desktop prompts
+scheme = https
+skip-if = toolkit == 'android' # Tests desktop prompts
 support-files =
   chrome_timeout.js
   subtst_master_pass.html
 [test_maxlength.html]
 [test_onsubmit_value_change.html]
 [test_passwords_in_type_password.html]
 [test_prompt.html]
 skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
--- a/toolkit/components/passwordmgr/test/mochitest/test_master_password.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_master_password.html
@@ -12,56 +12,61 @@
 <body>
 Login Manager test: master password.
 <script>
 "use strict";
 
 // Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
 isTabModal = false;
 
-commonInit();
+var chromeScript = runChecksAfterCommonInit();
 SimpleTest.requestFlakyTimeout("untriaged");
 
 var pwmgr   = SpecialPowers.Services.logins;
-var pwcrypt = SpecialPowers.Cc["@mozilla.org/login-manager/crypto/SDR;1"]
-                           .getService(Ci.nsILoginManagerCrypto);
 
 var nsLoginInfo = new SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
 
-var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/mochitest/";
-var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/mochitest/";
+var exampleCom = "https://example.com/tests/toolkit/components/passwordmgr/test/mochitest/";
+var exampleOrg = "https://example.org/tests/toolkit/components/passwordmgr/test/mochitest/";
 
-var login1 = new nsLoginInfo();
-var login2 = new nsLoginInfo();
+runInParent(() => {
+    const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+    var pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
+
+    var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
 
-login1.init("http://example.com", "http://example.com", null,
-            "user1", "pass1", "uname", "pword");
-login2.init("http://example.org", "http://example.org", null,
-            "user2", "pass2", "uname", "pword");
+    var login1 = new nsLoginInfo();
+    var login2 = new nsLoginInfo();
 
-pwmgr.addLogin(login1);
-pwmgr.addLogin(login2);
+    login1.init("https://example.com", "https://example.com", null,
+                "user1", "pass1", "uname", "pword");
+    login2.init("https://example.org", "https://example.org", null,
+                "user2", "pass2", "uname", "pword");
+
+    pwmgr.addLogin(login1);
+    pwmgr.addLogin(login2);
+});
 </script>
 
 <p id="display"></p>
 
 <div id="content" style="display: none">
 <iframe id="iframe1"></iframe>
 <iframe id="iframe2"></iframe>
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 var iframe1 = document.getElementById("iframe1");
 var iframe2 = document.getElementById("iframe2");
 
 add_task(async function test_1() {
-    ok(pwcrypt.isLoggedIn, "should be initially logged in (no MP)");
+    ok(isLoggedIn(), "should be initially logged in (no MP)");
     enableMasterPassword();
-    ok(!pwcrypt.isLoggedIn, "should be logged out after setting MP");
+    ok(!isLoggedIn(), "should be logged out after setting MP");
 
     // Trigger a MP prompt via the API
     var state = {
         msg         : "Please enter your master password.",
         title       : "the title",
         textValue   : "",
         passValue   : "",
         iconClass   : "authentication-icon question-icon",
@@ -75,24 +80,24 @@ add_task(async function test_1() {
         defButton   : "button0",
     };
     var action = {
         buttonClick : "ok",
         passField   : masterPassword,
     };
     var promptDone = handlePrompt(state, action);
 
-    var logins = pwmgr.getAllLogins();
+    var logins = LoginManager.getAllLogins()
 
     await promptDone;
     is(logins.length, 3, "expected number of logins");
 
-    ok(pwcrypt.isLoggedIn, "should be logged in after MP prompt");
+    ok(isLoggedIn(), "should be logged in after MP prompt");
     logoutMasterPassword();
-    ok(!pwcrypt.isLoggedIn, "should be logged out");
+    ok(!isLoggedIn(), "should be logged out");
 });
 
 add_task(async function test_2() {
     // Try again but click cancel.
     var state = {
         msg         : "Please enter your master password.",
         title       : "the title",
         textValue   : "",
@@ -110,22 +115,22 @@ add_task(async function test_2() {
     var action = {
         buttonClick : "cancel",
     };
     var promptDone = handlePrompt(state, action);
 
     var failedAsExpected = false;
     var logins = null;
     try {
-        logins = pwmgr.getAllLogins();
+      logins = LoginManager.getAllLogins();
     } catch (e) { failedAsExpected = true; }
     await promptDone;
     ok(failedAsExpected, "getAllLogins should have thrown");
     is(logins, null, "shouldn't have gotten logins");
-    ok(!pwcrypt.isLoggedIn, "should still be logged out");
+    ok(!isLoggedIn(), "should still be logged out");
 });
 
 add_task(async function test_3() {
     var state = {
         msg         : "Please enter your master password.",
         title       : "the title",
         textValue   : "",
         passValue   : "",
@@ -140,37 +145,35 @@ add_task(async function test_3() {
         defButton   : "button0",
     };
     var action = {
         buttonClick : "ok",
         passField   : masterPassword,
     };
     var promptDone = handlePrompt(state, action);
 
-    var fillPromise = new Promise(resolve => {
-        addEventListener("message", resolve);
-    });
+    var fillPromise = promiseFormsProcessed();
 
     info("Load a single iframe to trigger a MP");
     iframe1.src = exampleCom + "subtst_master_pass.html";
 
     await promptDone;
     info("promptDone");
     await fillPromise;
     info("filled");
 
   // check contents of iframe1 fields
   var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
   var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
   is(u.value, "user1", "checking expected user to have been filled in");
   is(p.value, "pass1", "checking expected pass to have been filled in");
 
-    ok(pwcrypt.isLoggedIn, "should be logged in");
+    ok(isLoggedIn(), "should be logged in");
     logoutMasterPassword();
-    ok(!pwcrypt.isLoggedIn, "should be logged out");
+    ok(!isLoggedIn(), "should be logged out");
 });
 
 add_task(async function test_4() {
     var state = {
         msg         : "Please enter your master password.",
         title       : "the title",
         textValue   : "",
         passValue   : "",
@@ -195,17 +198,17 @@ add_task(async function test_4() {
     await promptDone;
 
   // check contents of iframe1 fields
   var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
   var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
   is(u.value, "", "checking expected empty user");
   is(p.value, "", "checking expected empty pass");
 
-    ok(!pwcrypt.isLoggedIn, "should be logged out");
+    ok(!isLoggedIn(), "should be logged out");
 
   // XXX check that there's 1 MP window open
 
     // Load another iframe with a login form
     // This should detect that there's already a pending MP prompt, and not
     // put up a second one.
     var loadPromise = new Promise(resolve => {
         iframe2.addEventListener("load", function onload() {
@@ -220,52 +223,50 @@ add_task(async function test_4() {
     await new Promise(resolve => {
       // Testing a negative, wait a little to give the login manager a chance to
       // (incorrectly) fill in the form.  Note, we cannot use setTimeout()
       // here because the modal window suspends all window timers.  Instead we
       // must use a chrome script to use nsITimer directly.
       let chromeURL = SimpleTest.getTestFileURL("chrome_timeout.js");
       let script = SpecialPowers.loadChromeScript(chromeURL);
       script.addMessageListener("ready", _ => {
-        script.sendAsyncMessage("setTimeout", { delay: 500 });
+          script.sendAsyncMessage("setTimeout", { delay: 500 });
       });
       script.addMessageListener("timeout", resolve);
     });
 
     // iframe2 should load without having triggered a MP prompt (because one
     // is already waiting)
 
     // check contents of iframe2 fields
     u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
     p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
     is(u.value, "", "checking expected empty user");
     is(p.value, "", "checking expected empty pass");
 
-  // XXX check that there's 1 MP window open
-  ok(!pwcrypt.isLoggedIn, "should be logged out");
+    // XXX check that there's 1 MP window open
+    ok(!isLoggedIn(), "should be logged out");
 
     // Ok, now enter the MP. The MP prompt is already up.
 
-    var fillPromise = new Promise(resolve => {
-        addEventListener("message", resolve);
-    });
+    var fillPromise = promiseFormsProcessed(2);
 
     // fill existing MP dialog with MP.
     action = {
         buttonClick : "ok",
         passField   : masterPassword,
     };
     await handlePrompt(state, action);
     await fillPromise;
 
     // We shouldn't have to worry about iframe1's load event racing with
     // filling of iframe2's data. We notify observers synchronously, so
     // iframe2's observer will process iframe2 before iframe1 even finishes
     // processing the form.
-    ok(pwcrypt.isLoggedIn, "should be logged in");
+    ok(isLoggedIn(), "should be logged in");
 
     // check contents of iframe1 fields
     u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
     p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
     is(u.value, "user2", "checking expected user to have been filled in");
     is(p.value, "pass2", "checking expected pass to have been filled in");
 
     // check contents of iframe2 fields
@@ -273,18 +274,15 @@ add_task(async function test_4() {
     p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
     is(u.value, "user1", "checking expected user to have been filled in");
     is(p.value, "pass1", "checking expected pass to have been filled in");
 });
 
 // XXX do a test5ABC with clicking cancel?
 
 SimpleTest.registerCleanupFunction(function finishTest() {
-  disableMasterPassword();
-
-  pwmgr.removeLogin(login1);
-  pwmgr.removeLogin(login2);
+    disableMasterPassword();
 });
 
 </script>
 </pre>
 </body>
 </html>
--- a/toolkit/components/passwordmgr/test/pwmgr_common.js
+++ b/toolkit/components/passwordmgr/test/pwmgr_common.js
@@ -195,38 +195,29 @@ function enableMasterPassword() {
   setMasterPassword(true);
 }
 
 function disableMasterPassword() {
   setMasterPassword(false);
 }
 
 function setMasterPassword(enable) {
-  var oldPW, newPW;
-  if (enable) {
-    oldPW = "";
-    newPW = masterPassword;
-  } else {
-    oldPW = masterPassword;
-    newPW = "";
-  }
-  // Set master password. Note that this logs in the user if no password was
-  // set before. But after logging out the next invocation of pwmgr can
-  // trigger a MP prompt.
+  chromeScript.sendSyncMessage("setMasterPassword", { enable });
+}
 
-  var pk11db = Cc["@mozilla.org/security/pk11tokendb;1"].getService(Ci.nsIPK11TokenDB);
-  var token = pk11db.getInternalKeyToken();
-  info("MP change from " + oldPW + " to " + newPW);
-  token.changePassword(oldPW, newPW);
-  token.logoutSimple();
+function isLoggedIn() {
+  return chromeScript.sendSyncMessage("isLoggedIn")[0][0];
 }
 
 function logoutMasterPassword() {
-  var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
-  sdr.logoutAndTeardown();
+  runInParent(function parent_logoutMasterPassword() {
+    const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+    var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing);
+    sdr.logoutAndTeardown();
+  });
 }
 
 function dumpLogins(pwmgr) {
   var logins = pwmgr.getAllLogins();
   ok(true, "----- dumpLogins: have " + logins.length + " logins. -----");
   for (var i = 0; i < logins.length; i++) {
     dumpLogin("login #" + i + " --- ", logins[i]);
   }
@@ -415,20 +406,47 @@ if (this.addMessageListener) {
       }
 
       return arg;
     });
 
     let rv = Services.logins[msg.methodName](...recreatedArgs);
     if (rv instanceof Ci.nsILoginInfo) {
       rv = LoginHelper.loginToVanillaObject(rv);
+    } else if (Array.isArray(rv) && rv.length > 0 && rv[0] instanceof Ci.nsILoginInfo) {
+      rv = rv.map(login => LoginHelper.loginToVanillaObject(login));
     }
     return rv;
   });
 
+  addMessageListener("isLoggedIn", () => {
+    // This can't use the LoginManager proxy below since it's not a method.
+    return Services.logins.isLoggedIn;
+  });
+
+  addMessageListener("setMasterPassword", ({ enable }) => {
+    let oldPW, newPW;
+    if (enable) {
+      oldPW = "";
+      newPW = masterPassword;
+    } else {
+      oldPW = masterPassword;
+      newPW = "";
+    }
+    // Set master password. Note that this logs in the user if no password was
+    // set before. But after logging out the next invocation of pwmgr can
+    // trigger a MP prompt.
+
+    var pk11db = Cc["@mozilla.org/security/pk11tokendb;1"].getService(Ci.nsIPK11TokenDB);
+    var token = pk11db.getInternalKeyToken();
+    dump("MP change from " + oldPW + " to " + newPW + "\n");
+    token.changePassword(oldPW, newPW);
+    token.logoutSimple();
+  });
+
   Services.mm.addMessageListener("RemoteLogins:onFormSubmit", function onFormSubmit(message) {
     sendAsyncMessage("formSubmissionProcessed", message.data, message.objects);
   });
 } else {
   // Code to only run in the mochitest pages (not in the chrome script).
   SpecialPowers.pushPrefEnv({"set": [["signon.rememberSignons", true],
                                      ["signon.autofillForms.http", true],
                                      ["security.insecure_field_warning.contextual.enabled", false],
--- a/toolkit/components/prompts/test/prompt_common.js
+++ b/toolkit/components/prompts/test/prompt_common.js
@@ -1,12 +1,9 @@
-const Ci = SpecialPowers.Ci;
-const Cc = SpecialPowers.Cc;
-ok(Ci != null, "Access Ci");
-ok(Cc != null, "Access Cc");
+const { Cc, Ci } = SpecialPowers;
 
 function hasTabModalPrompts() {
   var prefName = "prompts.tab_modal.enabled";
   var Services = SpecialPowers.Cu.import("resource://gre/modules/Services.jsm").Services;
   return Services.prefs.getPrefType(prefName) == Services.prefs.PREF_BOOL &&
          Services.prefs.getBoolPref(prefName);
 }
 var isTabModal = hasTabModalPrompts();