diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html')
-rw-r--r-- | toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html new file mode 100644 index 0000000000..54cb450815 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html @@ -0,0 +1,380 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Test filling generated passwords into confirm password fields</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script src="pwmgr_common.js"></script> + <script src="../../../satchel/test/satchel_common.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content"></div> +<pre id="test"> +Login Manager test: filling generated passwords into confirm password fields + +<template id="form1-template"> + <form id="form1" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form2-template"> + <form id="form2" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext" value="initial value"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form3-template"> + <form id="form3" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext" readonly> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form4-template"> + <form id="form4" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext" disabled> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form5-template"> + <form id="form5" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordBetween"> + <input type="password" name="pwordNext" autocomplete="new-password"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form6-template"> + <form id="form6" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext"> + <input type="password" name="pwordAfter" autocomplete="new-password" disabled> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form7-template"> + <form id="form7" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="junk0"> + <input type="password" name="junk1"> + <input type="password" name="junk2"> + <input type="password" name="junk3"> + <input type="password" name="junk4"> + <input type="password" name="pwordNext" autocomplete="new-password"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form8-template"> + <form id="form8" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="junk0" disabled> + <input type="password" name="junk1" disabled> + <input type="password" name="junk2" disabled> + <input type="password" name="junk3" disabled> + <input type="password" name="junk4" disabled> + <input type="password" name="pwordNext" autocomplete="new-password"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form9-template"> + <form id="form9" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="hidden" name="junk0"> + <input type="hidden" name="junk1"> + <input type="hidden" name="junk2"> + <input type="hidden" name="junk3"> + <input type="hidden" name="junk4"> + <input type="password" name="pwordNext" autocomplete="new-password"> + <button type="submit">Submit</button> + </form> +</template> + +<template id="form10-template"> + <form id="form10" action="https://example.com"> + <input type="text" name="uname"> + <input type="password" name="pword" autocomplete="new-password"> + <input type="password" name="pwordNext" autocomplete="new-password"> + <input type="password" name="pwordExtra" autocomplete="new-password"> + <button type="submit">Submit</button> + </form> +</template> + +<script class="testbody" type="text/javascript"> + const formTemplates = { + form1: document.getElementById("form1-template"), + form2: document.getElementById("form2-template"), + form3: document.getElementById("form3-template"), + form4: document.getElementById("form4-template"), + form5: document.getElementById("form5-template"), + form6: document.getElementById("form6-template"), + form7: document.getElementById("form7-template"), + form8: document.getElementById("form8-template"), + form9: document.getElementById("form9-template"), + form10: document.getElementById("form10-template"), + }; + + const setupScript = runInParent(function parentTestSetup() { + const { LoginTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/LoginTestUtils.sys.mjs" + ); + + addMessageListener( + "resetLoginsAndGeneratedPasswords", () => { + LoginTestUtils.clearData(); + LoginTestUtils.resetGeneratedPasswordsCache(); + } + ); + }); + + function resetLoginsAndGeneratedPasswords() { + return setupScript.sendAsyncMessage("resetLoginsAndGeneratedPasswords"); + } + + async function triggerPasswordGeneration(form) { + await openPopupOn(form.pword); + synthesizeKey("KEY_ArrowDown"); + synthesizeKey("KEY_Enter"); + await SimpleTest.promiseWaitForCondition(() => !!form.pword.value, "Wait for generated password to get filled"); + } + + add_named_task("autocomplete menu contains option to generate password", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + + const { items } = await openPopupOn(form.pword); + + checkAutoCompleteResults(items, [ + "Use a Securely Generated Password" + ], location.host, "Check all rows are correct"); + }); + + add_named_task("username field highlight", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + ok(!form.uname.matches(":autofill"), "Highlight was not applied to the username field"); + }); + + add_named_task("password field highlight", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + ok(form.pword.matches(":autofill"), "Highlight was applied to the password field"); + }); + + add_named_task("username field is left untouched", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + is(form.uname.value, "", "Value is still empty") + }); + + add_named_task("generated password looks like a generated password", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + const generatedPassword = form.pword.value; + is(generatedPassword.length, GENERATED_PASSWORD_LENGTH, "Generated password length matches"); + ok(generatedPassword.match(GENERATED_PASSWORD_REGEX), "Generated password format matches"); + }); + + add_named_task("password confirmation also gets filled with the generated password", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, form.pword.value, "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password field is not masked initially after password generation", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "password field is not masked after password generation"); + LOGIN_FIELD_UTILS.checkPasswordMasked(form.pwordNext, true, "password confirmation field is masked after user input"); + }); + + add_named_task("password field is masked after user input", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + form.pwordNext.focus(); + form.pwordNext.select(); + synthesizeKey("KEY_Backspace"); + synthesizeKey("a"); + form.pwordNext.blur(); + LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "password field is masked after user input"); + LOGIN_FIELD_UTILS.checkPasswordMasked(form.pwordNext, true, "password confirmation field is also masked after user input"); + }); + + add_named_task("password field highlight is cleared after user input", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + form.pwordNext.focus(); + form.pwordNext.select(); + synthesizeKey("KEY_Backspace"); + synthesizeKey("a"); + form.pwordNext.blur(); + await SimpleTest.promiseWaitForCondition(() => !form.pwordNext.matches(":autofill"), "Highlight was cleared"); + }); + + add_named_task("generated password can be changed", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + const generatedPassword = form.pword.value; + form.pword.focus(); + synthesizeKey("KEY_End"); + synthesizeKey("@"); + is(form.pword.value, `${generatedPassword}@`, "Value of the password field changed"); + }); + + add_named_task("password confirmation field does not receive changes from password field", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + const generatedPassword = form.pword.value; + + // changing the password field value should result in a message sent to the parent process + const messageSentPromise = getPasswordEditedMessage(); + + form.pword.focus(); + synthesizeKey("KEY_End"); + synthesizeKey("@"); + + // bluring results in a "change" event + form.pword.blur(); + await messageSentPromise; + + is(form.pwordNext.value, generatedPassword, "Value of the confirm field still holds the original generated password"); + ok(form.pwordNext.matches(":autofill"), "Highlight is still applied to password confirmation field"); + }); + + add_named_task("password confirmation field behaves like a normal password field once changed", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + await triggerPasswordGeneration(form); + + form.pwordNext.focus(); + form.pwordNext.select(); + synthesizeKey("KEY_Backspace"); + + // verify the focused confirm field now masks its input like a normal, + // non-generated password field after being emptied + form.pwordNext.focus(); + synthesizeKey("a"); + form.pwordNext.blur(); + + LOGIN_FIELD_UTILS.checkPasswordMasked(form.pwordNext, true, "password confirmation field is masked"); + await SimpleTest.promiseWaitForCondition(() => !form.pwordNext.matches(":autofill"), "highlight was cleared"); + }); + + add_named_task("password confirmation also gets filled with the generated password, even if it has been changed to be of type text", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + form.pwordNext.type = "text"; + await triggerPasswordGeneration(form); + is(form.pwordNext.value, form.pword.value, "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation does not get filled with the generated password if it is not empty", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form2); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "initial value", "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation does not get filled with the generated password if it has been edited", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form1); + form.pwordNext.focus() + sendString("edited value"); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "edited value", "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation does not get filled with the generated password if its readonly", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form3); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "", "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation does not get filled with the generated password if its disabled", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form4); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "", "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation matching autocomplete info gets filled with the generated password", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form5); + await triggerPasswordGeneration(form); + is(form.pwordBetween.value, "", "Value of the between field has not been filled"); + is(form.pwordNext.value, form.pword.value, "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("password confirmation matching autocomplete info gets ignored if its disabled, even if has autocomplete info", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form6); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, form.pword.value, "Value of the confirm field has been filled with generated password"); + is(form.pwordAfter.value, "", "Value of the disabled confirmation field has not been filled"); + }); + + add_named_task("password confirmation matching autocomplete info gets ignored there are too many fields in between, even if has autocomplete info", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form7); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "", "Value of the confirm field has not been filled"); + }); + + add_named_task("password confirmation matching autocomplete info gets ignored there are too many disabled fields in between, even if has autocomplete info", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form8); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, "", "Value of the confirm field has not been filled"); + }); + + add_named_task("password confirmation matching autocomplete info gets filled even if there are many hidden fields in between", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form9); + await triggerPasswordGeneration(form); + is(form.pwordNext.value, form.pword.value, "Value of the confirm field has been filled with generated password"); + }); + + add_named_task("do not fill third password field after the confirm-password field", async () => { + await resetLoginsAndGeneratedPasswords(); + const form = setContentForTask(formTemplates.form10); + await triggerPasswordGeneration(form); + is(form.pwordExtra.value, "", "Value of the additional confirm field has not been filled"); + }); +</script> +</pre> +</body> +</html> |