Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android'
- Manifest: toolkit/components/passwordmgr/test/unit/xpcshell.toml
/**
* Test for LoginFormState.getUserNameAndPasswordFields
*/
"use strict";
const { LoginManagerChild } = ChromeUtils.importESModule(
"resource://gre/modules/LoginManagerChild.sys.mjs"
);
const TESTCASES = [
{
description: "1 password field outside of a <form>",
document: `<input id="pw1" type=password>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description: "1 text field in a <form> without a password field",
document: `<form>
<input id="un1">
</form>`,
returnedFieldIDs: [null, null, null],
},
{
description: "1 text field outside of a <form> without a password field",
document: `<input id="un1">`,
returnedFieldIDs: [null, null, null],
},
{
description: "1 username & password field outside of a <form>",
document: `<input id="un1">
<input id="pw1" type=password>`,
returnedFieldIDs: ["un1", "pw1", null],
},
{
description: "1 username & password field in a <form>",
document: `<form>
<input id="un1">
<input id="pw1" type=password>
</form>`,
returnedFieldIDs: ["un1", "pw1", null],
},
{
description: "5 empty password fields outside of a <form>",
document: `<input id="pw1" type=password>
<input id="pw2" type=password>
<input id="pw3" type=password>
<input id="pw4" type=password>
<input id="pw5" type=password>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description: "6 empty password fields outside of a <form>",
document: `<input id="pw1" type=password>
<input id="pw2" type=password>
<input id="pw3" type=password>
<input id="pw4" type=password>
<input id="pw5" type=password>
<input id="pw6" type=password>`,
returnedFieldIDs: [null, null, null],
},
{
description: "Form with 1 password field",
document: `<form><input id="pw1" type=password></form>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description: "Form with 2 password fields",
document: `<form><input id="pw1" type=password><input id='pw2' type=password></form>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description: "1 password field in a form, 1 outside (not processed)",
document: `<form><input id="pw1" type=password></form><input id="pw2" type=password>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description:
"1 password field in a form, 1 text field outside (not processed)",
document: `<form><input id="pw1" type=password></form><input>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description:
"1 text field in a form, 1 password field outside (not processed)",
document: `<form><input></form><input id="pw1" type=password>`,
returnedFieldIDs: [null, null, null],
},
{
description:
"2 password fields outside of a <form> with 1 linked via @form",
document: `<input id="pw1" type=password><input id="pw2" type=password form='form1'>
<form id="form1"></form>`,
returnedFieldIDs: [null, "pw1", null],
},
{
description: "1 username field in a <form>",
document: `<form>
<input id="un1" autocomplete=username>
</form>`,
returnedFieldIDs: ["un1", null, null],
},
{
description: "1 username field outside of a <form>",
document: `<input id="un1" autocomplete=username>`,
returnedFieldIDs: ["un1", null, null],
},
{
description: "username with type=user",
document: `<form><input id="un1" type="user"><input id="pwd" type="password"></form>`,
returnedFieldIDs: ["un1", "pwd", null],
},
{
description: "username with type=username",
document: `<form><input id="un1" type="username"><input id="pwd" type="password"></form>`,
returnedFieldIDs: ["un1", "pwd", null],
},
];
function _setPrefs() {
Services.prefs.setBoolPref("signon.usernameOnlyForm.enabled", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("signon.usernameOnlyForm.enabled");
});
}
_setPrefs();
for (let tc of TESTCASES) {
info("Sanity checking the testcase: " + tc.description);
(function () {
let testcase = tc;
add_task(async function () {
info("Starting testcase: " + testcase.description);
let document = MockDocument.createTestDocument(
testcase.document
);
let input = document.querySelector("input");
MockDocument.mockOwnerDocumentProperty(
input,
document,
);
MockDocument.mockNodePrincipalProperty(
input,
);
// Additional mock to cache recipes
let win = {};
Object.defineProperty(document, "defaultView", {
value: win,
});
let formOrigin = LoginHelper.getLoginOrigin(document.documentURI);
LoginRecipesContent.cacheRecipes(formOrigin, win, new Set());
const loginManagerChild = new LoginManagerChild();
const docState = loginManagerChild.stateForDocument(document);
let actual = docState.getUserNameAndPasswordFields(input);
Assert.strictEqual(
testcase.returnedFieldIDs.length,
3,
"getUserNameAndPasswordFields returns 3 elements"
);
for (let i = 0; i < testcase.returnedFieldIDs.length; i++) {
let expectedID = testcase.returnedFieldIDs[i];
if (expectedID === null) {
Assert.strictEqual(
actual[i],
expectedID,
"Check returned field " + i + " is null"
);
} else {
Assert.strictEqual(
actual[i].id,
expectedID,
"Check returned field " + i + " ID"
);
}
}
});
})();
}