Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android' OR verify OR xorigin
- Manifest: toolkit/components/passwordmgr/test/mochitest/mochitest.toml
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for primary password</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<script type="text/javascript" src="../../../prompts/test/prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Login Manager test: primary password.
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
"use strict";
// Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
modalType = Ci.nsIPrompt.MODAL_TYPE_WINDOW;
const win = window.open("about:blank");
SimpleTest.registerCleanupFunction(() => win.close());
add_setup(async () => {
await setStoredLoginsAsync(
["http://mochi.test:8888", "http://mochi.test:8888", null, "testuser", "testpass", "uname", "pword"],
);
ok(await isLoggedIn(), "should be initially logged in (no PP)");
enablePrimaryPassword();
ok(!await isLoggedIn(), "should be logged out after setting PP");
});
add_task(async function test_1() {
// Trigger a MP prompt via the API
const state = {
msg: "Please enter your Primary Password.",
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",
};
const action = {
buttonClick: "ok",
passField: LoginTestUtils.primaryPassword.primaryPassword,
};
const promptDone = handlePrompt(state, action);
const logins = await LoginManager.getAllLogins();
await promptDone;
is(logins.length, 3, "expected number of logins");
ok(await isLoggedIn(), "should be logged in after MP prompt");
logoutPrimaryPassword();
ok(!await isLoggedIn(), "should be logged out");
});
add_task(async function test_2() {
// Try again but click cancel.
const state = {
msg: "Please enter your Primary Password.",
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",
};
const action = {
buttonClick: "cancel",
};
const promptDone = handlePrompt(state, action);
const logins = await LoginManager.getAllLogins().catch(() => {});
await promptDone;
is(logins, undefined, "shouldn't have gotten logins");
ok(!await isLoggedIn(), "should still be logged out");
});
add_task(async function test_3() {
const state = {
msg: "Please enter your Primary Password.",
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",
};
const action = {
buttonClick: "ok",
passField: LoginTestUtils.primaryPassword.primaryPassword,
};
const promptDone = handlePrompt(state, action);
const fillPromise = promiseFormsProcessed();
info("Load a single window to trigger a MP");
await SimpleTest.promiseFocus(win, true);
win.location = exampleCom + "subtst_primary_pass.html";
await promptDone;
info("promptDone");
await fillPromise;
info("filled");
// check contents of win fields
await SpecialPowers.spawn(win, [], function() {
const u = this.content.document.getElementById("userfield");
const p = this.content.document.getElementById("passfield");
Assert.equal(u.value, "user1", "checking expected user to have been filled in");
Assert.equal(p.value, "pass1", "checking expected pass to have been filled in");
u.value = "";
p.value = "";
});
ok(await isLoggedIn(), "should be logged in");
logoutPrimaryPassword();
ok(!await isLoggedIn(), "should be logged out");
});
add_task(async function test_4() {
const state = {
msg: "Please enter your Primary Password.",
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",
};
let action = {
buttonClick: "none",
};
const promptDone = handlePrompt(state, action);
// first part of loading 2 MP-triggering windows
await SimpleTest.promiseFocus(win);
win.location = exampleOrg + "subtst_primary_pass.html";
// The MP prompt is open but don't take any action yet.
await promptDone;
// check contents of win fields
await SpecialPowers.spawn(win, [], function() {
const u = this.content.document.getElementById("userfield");
const p = this.content.document.getElementById("passfield");
Assert.equal(u.value, "", "checking expected empty user");
Assert.equal(p.value, "", "checking expected empty pass");
});
ok(!await isLoggedIn(), "should be logged out");
// XXX check that there's 1 MP window open
// Load a second login form in an iframe
// This should detect that there's already a pending MP prompt, and not
// put up a second one.
// Since the Primary Password prompt is open, we can't focus another tab
// to load the second form. Instead, we load the same form into an iframe.
const url = exampleOrg + "subtst_primary_pass.html";
await SpecialPowers.spawn(win, [url], async function(urlF) {
const iframe = this.content.document.querySelector("iframe");
const loadPromise = new Promise(resolve => {
iframe.addEventListener("load", function onload() {
resolve();
}, { once: true });
});
// Use the same origin as the top level to ensure we would autofill
// if we could (we don't fill in cross-origin iframes).
iframe.src = urlF;
await loadPromise;
});
// We can't use promiseFormsProcessed* here, because _fillForm doesn't
// run if Primary Password is locked.
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.
const chromeURL = SimpleTest.getTestFileURL("chrome_timeout.js");
const script = SpecialPowers.loadChromeScript(chromeURL);
script.addMessageListener("ready", _ => {
script.sendAsyncMessage("setTimeout", { delay: 500 });
});
script.addMessageListener("timeout", resolve);
});
// iframe should load without having triggered a MP prompt (because one
// is already waiting)
// check contents of iframe fields
await SpecialPowers.spawn(win, [], function() {
const iframe = this.content.document.querySelector("iframe");
const frameDoc = iframe.contentDocument;
const u = frameDoc.getElementById("userfield");
const p = frameDoc.getElementById("passfield");
Assert.equal(u.value, "", "checking expected empty user");
Assert.equal(p.value, "", "checking expected empty pass");
});
// XXX check that there's 1 MP window open
ok(!await isLoggedIn(), "should be logged out");
// Ok, now enter the MP. The MP prompt is already up.
const fillPromise = promiseFormsProcessed(2);
// fill existing MP dialog with MP.
action = {
buttonClick: "ok",
passField: LoginTestUtils.primaryPassword.primaryPassword,
};
await handlePrompt(state, action);
await fillPromise;
// We shouldn't have to worry about win's load event racing with
// filling of the iframe's data. We notify observers synchronously, so
// the iframe's observer will process the iframe before win even finishes
// processing the form.
ok(await isLoggedIn(), "should be logged in");
// check contents of win fields
await SpecialPowers.spawn(win, [], function() {
const u = this.content.document.getElementById("userfield");
const p = this.content.document.getElementById("passfield");
Assert.equal(u.value, "user2", "checking expected user to have been filled in");
Assert.equal(p.value, "pass2", "checking expected pass to have been filled in");
// clearing fields to not cause a submission when the next document is loaded
u.value = "";
p.value = "";
});
// check contents of iframe fields
await SpecialPowers.spawn(win, [], function() {
const iframe = this.content.document.querySelector("iframe");
const frameDoc = iframe.contentDocument;
const u = frameDoc.getElementById("userfield");
const p = frameDoc.getElementById("passfield");
Assert.equal(u.value, "user2", "checking expected user to have been filled in");
Assert.equal(p.value, "pass2", "checking expected pass to have been filled in");
// clearing fields to not cause a submission when the next document is loaded
u.value = "";
p.value = "";
});
});
// XXX do a test5ABC with clicking cancel?
SimpleTest.registerCleanupFunction(function finishTest() {
disablePrimaryPassword();
});
</script>
</pre>
</body>
</html>