rename from toolkit/components/passwordmgr/test/test_master_password.html
rename to toolkit/components/passwordmgr/test/mochitest/test_master_password.html
--- a/toolkit/components/passwordmgr/test/test_master_password.html
+++ b/toolkit/components/passwordmgr/test/mochitest/test_master_password.html
@@ -1,36 +1,39 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for master password</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>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<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();
-SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"]
.getService(SpecialPowers.Ci.nsILoginManager);
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/";
-var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/";
+var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/mochitest/";
+var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/mochitest/";
var login1 = new nsLoginInfo();
var login2 = new nsLoginInfo();
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");
@@ -43,259 +46,237 @@ pwmgr.addLogin(login2);
<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 testNum = 1;
var iframe1 = document.getElementById("iframe1");
var iframe2 = document.getElementById("iframe2");
-// A couple of tests have to wait until the password manager gets around to
-// filling in the password in the subtest (after we dismiss the master
-// password dialog). In order to accomplish this, the test waits for an event
-// and then posts a message back up to us telling us to continue.
-var continuation = null;
-addEventListener("message", () => {
- if (continuation) {
- var c = continuation;
- continuation = null;
- c();
- }
-});
-
-/*
- * handleDialog
- *
- * Invoked a short period of time after calling startCallbackTimer(), and
- * allows testing the actual auth dialog while it's being displayed. Tests
- * should call startCallbackTimer() each time the auth dialog is expected (the
- * timer is a one-shot).
- */
-function handleDialog(doc, testNum) {
- ok(true, "handleDialog running for test " + testNum);
-
- var clickOK = true;
- var doNothing = false;
- var passfield = doc.getElementById("password1Textbox");
- var dialog = doc.getElementById("commonDialog");
-
- switch(testNum) {
- case 1:
- is(passfield.getAttribute("value"), "", "Checking empty prompt");
- passfield.setAttribute("value", masterPassword);
- is(passfield.getAttribute("value"), masterPassword, "Checking filled prompt");
- break;
-
- case 2:
- clickOK = false;
- break;
-
- case 3:
- is(passfield.getAttribute("value"), "", "Checking empty prompt");
- passfield.setAttribute("value", masterPassword);
- break;
-
- case 4:
- doNothing = true;
- break;
-
- case 5:
- is(passfield.getAttribute("value"), "", "Checking empty prompt");
- passfield.setAttribute("value", masterPassword);
- break;
-
- default:
- ok(false, "Uhh, unhandled switch for testNum #" + testNum);
- break;
- }
-
- didDialog = true;
-
- if (!doNothing) {
- SpecialPowers.addObserver(outerWindowObserver, "outer-window-destroyed", false);
- if (clickOK)
- dialog.acceptDialog();
- else
- dialog.cancelDialog();
- }
-
- ok(true, "handleDialog done for test " + testNum);
-
- if (testNum == 4)
- checkTest4A();
-}
-
-var outerWindowObserver = {
- observe: function(id) {
- SpecialPowers.removeObserver(outerWindowObserver, "outer-window-destroyed");
- var func;
- if (testNum == 1)
- func = startTest2;
- else if (testNum == 2)
- func = startTest3;
-
- // For tests 3 and 4C, we use the 'continuation' mechanism, described
- // above.
- if (func)
- setTimeout(func, 300);
- }
-};
-
-
-function startTest1() {
+add_task(function* test_1() {
ok(pwcrypt.isLoggedIn, "should be initially logged in (no MP)");
enableMasterPassword();
ok(!pwcrypt.isLoggedIn, "should be logged out after setting MP");
- // --- Test 1 ---
// Trigger a MP prompt via the API
- startCallbackTimer();
+ var state = {
+ msg : "Please enter the master password for the Software Security Device.",
+ title : "the title",
+ textValue : "",
+ passValue : "",
+ iconClass : "authentication-icon question-icon",
+ titleHidden : true,
+ textHidden : true,
+ passHidden : false,
+ checkHidden : true,
+ checkMsg : "",
+ checked : false,
+ focused : "passField",
+ defButton : "button0",
+ };
+ var action = {
+ buttonClick : "ok",
+ passField : masterPassword,
+ };
+ var promptDone = handlePrompt(state, action);
+
var logins = pwmgr.getAllLogins();
- ok(didDialog, "handleDialog was invoked");
+
+ yield promptDone;
is(logins.length, 3, "expected number of logins");
ok(pwcrypt.isLoggedIn, "should be logged in after MP prompt");
logoutMasterPassword();
ok(!pwcrypt.isLoggedIn, "should be logged out");
-}
+});
-function startTest2() {
+add_task(function* test_2() {
// Try again but click cancel.
- testNum++;
- startCallbackTimer();
+ var state = {
+ msg : "Please enter the master password for the Software Security Device.",
+ title : "the title",
+ textValue : "",
+ passValue : "",
+ iconClass : "authentication-icon question-icon",
+ titleHidden : true,
+ textHidden : true,
+ passHidden : false,
+ checkHidden : true,
+ checkMsg : "",
+ checked : false,
+ focused : "passField",
+ defButton : "button0",
+ };
+ var action = {
+ buttonClick : "cancel",
+ };
+ var promptDone = handlePrompt(state, action);
+
var failedAsExpected = false;
- logins = null;
+ var logins = null;
try {
logins = pwmgr.getAllLogins();
} catch (e) { failedAsExpected = true; }
- ok(didDialog, "handleDialog was invoked");
+ yield promptDone;
ok(failedAsExpected, "getAllLogins should have thrown");
is(logins, null, "shouldn't have gotten logins");
ok(!pwcrypt.isLoggedIn, "should still be logged out");
-}
+});
-function startTest3() {
- // Load a single iframe to trigger a MP
- testNum++;
+add_task(function* test_3() {
+ var state = {
+ msg : "Please enter the master password for the Software Security Device.",
+ title : "the title",
+ textValue : "",
+ passValue : "",
+ iconClass : "authentication-icon question-icon",
+ titleHidden : true,
+ textHidden : true,
+ passHidden : false,
+ checkHidden : true,
+ checkMsg : "",
+ checked : false,
+ focused : "passField",
+ defButton : "button0",
+ };
+ var action = {
+ buttonClick : "ok",
+ passField : masterPassword,
+ };
+ var promptDone = handlePrompt(state, action);
+
+ var fillPromise = new Promise(resolve => {
+ addEventListener("message", resolve);
+ });
+
+ info("Load a single iframe to trigger a MP");
iframe1.src = exampleCom + "subtst_master_pass.html";
- continuation = checkTest3;
- startCallbackTimer();
-}
-function checkTest3() {
- ok(true, "checkTest3 starting");
- ok(didDialog, "handleDialog was invoked");
+ yield promptDone;
+ info("promptDone");
+ yield 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");
logoutMasterPassword();
ok(!pwcrypt.isLoggedIn, "should be logged out");
-
+});
- // --- Test 4 ---
+add_task(function* test_4() {
+ var state = {
+ msg : "Please enter the master password for the Software Security Device.",
+ title : "the title",
+ textValue : "",
+ passValue : "",
+ iconClass : "authentication-icon question-icon",
+ titleHidden : true,
+ textHidden : true,
+ passHidden : false,
+ checkHidden : true,
+ checkMsg : "",
+ checked : false,
+ focused : "passField",
+ defButton : "button0",
+ };
+ var action = {
+ buttonClick : "none",
+ };
+ var promptDone = handlePrompt(state, action);
+
// first part of loading 2 MP-triggering iframes
- testNum++;
iframe1.src = exampleOrg + "subtst_master_pass.html";
- // start the callback, but we'll not enter the MP, just call checkTest4A
- startCallbackTimer();
-}
-
-function checkTest4A() {
- ok(true, "checkTest4A starting");
- ok(didDialog, "handleDialog was invoked");
+ // The MP prompt is open but don't take any action yet.
+ yield 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");
// 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. The load event will fire (note that when pwmgr is
- // driven from DOMContentLoaded, if that blocks due to prompting for a MP,
- // the load even will also be blocked until the prompt is dismissed).
- iframe2.onload = checkTest4B_delay;
+ // put up a second one.
+ var loadPromise = new Promise(resolve => {
+ iframe2.addEventListener("load", function onload() {
+ iframe2.removeEventListener("load", onload);
+ resolve();
+ });
+ });
+
iframe2.src = exampleCom + "subtst_master_pass.html";
-}
+ yield loadPromise;
-function checkTest4B_delay() {
// Testing a negative, wait a little to give the login manager a chance to
// (incorrectly) fill in the form.
- setTimeout(checkTest4B, 500);
-}
+ yield new Promise(resolve => setTimeout(resolve, 500));
-function checkTest4B() {
- ok(true, "checkTest4B starting");
// iframe2 should load without having triggered a MP prompt (because one
// is already waiting)
// check contents of iframe2 fields
- var u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
- var p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
+ 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");
- continuation = checkTest4C;
+ // Ok, now enter the MP. The MP prompt is already up.
+
+ var fillPromise = new Promise(resolve => {
+ addEventListener("message", resolve);
+ });
- // Ok, now enter the MP. The MP prompt is already up, but we'll just reuse startCallBackTimer.
- // --- Test 5 ---
- testNum++;
- startCallbackTimer();
-}
-
-function checkTest4C() {
- ok(true, "checkTest4C starting");
- ok(didDialog, "handleDialog was invoked");
+ // fill existing MP dialog with MP.
+ action = {
+ buttonClick : "ok",
+ passField : masterPassword,
+ };
+ yield handlePrompt(state, action);
+ yield 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 (which is blocking its load event).
+ // processing the form.
ok(pwcrypt.isLoggedIn, "should be logged in");
// check contents of iframe1 fields
- var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
- var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
+ 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
u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
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");
-
- SimpleTest.finish();
-}
+});
// XXX do a test5ABC with clicking cancel?
SimpleTest.registerCleanupFunction(function finishTest() {
disableMasterPassword();
pwmgr.removeLogin(login1);
pwmgr.removeLogin(login2);
});
-window.addEventListener("runTests", startTest1);
</script>
</pre>
</body>
</html>
-