Source code

Revision control

Other Tools

Test Info:

<!DOCTYPE HTML>
<html>
<head>
<title>Test for unmasking password API</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<input type="text">
<input type="password">
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(() => {
let input = document.getElementsByTagName("input")[0];
let password = document.getElementsByTagName("input")[1];
let editor, passwordEditor;
function updateEditors() {
editor = SpecialPowers.wrap(input).editor;
passwordEditor = SpecialPowers.wrap(password).editor;
}
try {
updateEditors();
editor.mask();
ok(false,
`nsIEditor.mask() should throw exception when called for <input type="text"> before nsIEditor.unmask()`);
} catch (e) {
ok(true,
`nsIEditor.mask() should throw exception when called for <input type="text"> before nsIEditor.unmask() ${e}`);
}
try {
updateEditors();
editor.unmask();
ok(false,
`nsIEditor.unmask() should throw exception when called for <input type="text">`);
} catch (e) {
ok(true,
`nsIEditor.unmask() should throw exception when called for <input type="text"> ${e}`);
}
try {
updateEditors();
editor.unmask(0);
ok(false,
`nsIEditor.unmask(0) should throw exception when called for <input type="text">`);
} catch (e) {
ok(true,
`nsIEditor.unmask(0) should throw exception when called for <input type="text"> ${e}`);
}
input.value = "abcdef";
try {
updateEditors();
editor.unmask();
ok(false,
`nsIEditor.unmask() should throw exception when called for <input type="text" value="abcdef">`);
} catch (e) {
ok(true,
`nsIEditor.unmask() should throw exception when called for <input type="text" value="abcdef"> ${e}`);
}
try {
updateEditors();
editor.mask();
ok(false,
`nsIEditor.mask() should throw exception when called for <input type="text" value="abcdef"> after nsIEditor.unmask()`);
} catch (e) {
ok(true,
`nsIEditor.mask() should throw exception when called for <input type="text" value="abcdef"> after nsIEditor.unmask() ${e}`);
}
try {
updateEditors();
passwordEditor.mask();
ok(true,
`nsIEditor.mask() shouldn't throw exception when called for <input type="password"> before nsIEditor.unmask()`);
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after nsIEditor.mask() for <input type="password"> before nsIEditor.unmask()`);
} catch (e) {
ok(false,
`nsIEditor.mask() shouldn't throw exception when called for <input type="password"> before nsIEditor.unmask() ${e}`);
}
try {
updateEditors();
editor.unmask(5);
ok(false,
`nsIEditor.unmask(5) should throw exception when called for <input type="password" value="">`);
} catch (e) {
ok(true,
`nsIEditor.unmask(5) should throw exception when called for <input type="password" value=""> ${e}`);
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should keep true (<input type="password">)`);
}
try {
updateEditors();
passwordEditor.unmask();
ok(true,
`nsIEditor.unmask() shouldn't throw exception when called for <input type="password">`);
ok(!passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask() for <input type="password">)`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask() for <input type="password">`);
is(passwordEditor.unmaskedEnd, 0,
`nsIEditor.unmaskedEnd should be 0 after nsIEditor.unmask() for <input type="password">`);
} catch (e) {
ok(false,
`nsIEditor.unmask() shouldn't throw exception when called for <input type="password"> ${e}`);
}
password.value = "abcdef";
try {
updateEditors();
passwordEditor.unmask();
ok(true,
`nsIEditor.unmask() shouldn't throw exception when called for <input type="password" value="abcdef">)`);
ok(!passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask() for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask() for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedEnd, 6,
`nsIEditor.unmaskedEnd should be 0 after nsIEditor.unmask() for <input type="password" value="abcdef">`);
} catch (e) {
ok(false,
`nsIEditor.unmask() shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`);
}
try {
updateEditors();
passwordEditor.mask();
ok(true,
`nsIEditor.mask() shouldn't throw exception when called for <input type="password" value="abcdef">`);
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after nsIEditor.mask() for <input type="password" value="abcdef">`);
} catch (e) {
ok(false,
`nsIEditor.mask() shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`);
}
try {
updateEditors();
passwordEditor.unmask(0, 100, 1000);
ok(true,
`nsIEditor.unmask(0, 100, 1000) shouldn't throw exception when called for <input type="password" value="abcdef">`);
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedEnd, 6,
`nsIEditor.unmaskedEnd should be 6 after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`);
} catch (e) {
ok(false,
`nsIEditor.unmask(0, 100, 1000) shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`);
}
try {
updateEditors();
passwordEditor.unmask(3);
ok(true,
`nsIEditor.unmask(3) shouldn't throw exception when called for <input type="password" value="abcdef">`);
ok(!passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask(3) for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedStart, 3,
`nsIEditor.unmaskedStart should be 3 after nsIEditor.unmask(3) for <input type="password" value="abcdef">`);
is(passwordEditor.unmaskedEnd, 6,
`nsIEditor.unmaskedEnd should be 6 after nsIEditor.unmask(3) for <input type="password" value="abcdef">`);
} catch (e) {
ok(false,
`nsIEditor.unmask(3) shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`);
}
try {
updateEditors();
passwordEditor.unmask(0);
password.style.fontSize = "32px"; // reframe the `<input>` element
password.getBoundingClientRect(); // flush pending reflow if there is
// Then, new `TextEditor` should keep unmasked range.
passwordEditor = SpecialPowers.wrap(password).editor;
ok(!passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be false after the password field reframed`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after the password field reframed`);
is(passwordEditor.unmaskedEnd, 6,
`nsIEditor.unmaskedEnd should be 6 after the password field reframed`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after reframing ${e}`);
} finally {
password.style.fontSize = "";
password.getBoundingClientRect();
}
try {
updateEditors();
passwordEditor.unmask(0);
password.style.display = "none"; // Hide the password field temporarily
password.getBoundingClientRect();
password.style.display = "block"; // And show it again
password.getBoundingClientRect();
updateEditors();
// Then, new `TextEditor` should keep unmasked range.
ok(!passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be false after the password field was temporarily hidden`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden`);
is(passwordEditor.unmaskedEnd, 6,
`nsIEditor.unmaskedEnd should be 6 after the password field was temporarily hidden`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field ${e}`);
} finally {
password.style.display = "";
password.getBoundingClientRect();
passwordEditor = SpecialPowers.wrap(password).editor;
}
try {
updateEditors();
passwordEditor.unmask(0);
password.style.display = "none"; // Hide the password field temporarily
password.getBoundingClientRect();
password.value = "ghijkl"; // And modify the value
password.style.display = "block"; // And show it again
password.getBoundingClientRect();
// Then, new `TextEditor` shouldn't keep unmasked range due to the value change.
updateEditors();
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden and changed its value`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden and changed its value`);
is(passwordEditor.unmaskedEnd, 0,
`nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden and changed its value`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field and changing the value ${e}`);
} finally {
password.style.display = "";
password.getBoundingClientRect();
password.value = "abcdef";
passwordEditor = SpecialPowers.wrap(password).editor;
}
try {
updateEditors();
passwordEditor.unmask(0);
password.style.display = "none"; // Hide the password field temporarily
password.getBoundingClientRect();
password.value = "abcdef"; // And overwrite the value with same value
password.style.display = "block"; // And show it again
password.getBoundingClientRect();
// Then, new `TextEditor` shouldn't keep unmasked range due to setting the value.
updateEditors();
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden and changed its value`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden and changed its value`);
is(passwordEditor.unmaskedEnd, 0,
`nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden and changed its value`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field and changing the value ${e}`);
} finally {
password.style.display = "";
password.getBoundingClientRect();
password.value = "abcdef";
passwordEditor = SpecialPowers.wrap(password).editor;
}
try {
updateEditors();
passwordEditor.unmask(0, 6, 10000);
password.style.display = "none"; // Hide the password field temporarily
password.getBoundingClientRect();
password.style.display = "block"; // And show it again
password.getBoundingClientRect();
updateEditors();
// Then, new `TextEditor` should mask all characters since nobody can mask it with the timer.
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden (if auto-masking timer was set)`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden (if auto-masking timer was set)`);
is(passwordEditor.unmaskedEnd, 0,
`nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden (if auto-masking timer was set)`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field whose auto-masking timer was set ${e}`);
} finally {
password.style.display = "";
password.getBoundingClientRect();
passwordEditor = SpecialPowers.wrap(password).editor;
}
try {
updateEditors();
passwordEditor.unmask(0);
password.type = "text";
password.getBoundingClientRect();
password.type = "password";
password.getBoundingClientRect();
updateEditors();
// Then, new `TextEditor` should mask all characters after `type` attribute was changed.
ok(passwordEditor.autoMaskingEnabled,
`nsIEditor.autoMaskingEnabled should be true after "type" attribute of the password field was changed`);
is(passwordEditor.unmaskedStart, 0,
`nsIEditor.unmaskedStart should be 0 after "type" attribute of the password field was changed`);
is(passwordEditor.unmaskedEnd, 0,
`nsIEditor.unmaskedEnd should be 0 after "type" attribute of the password field was changed`);
} catch (e) {
ok(false, `Shouldn't throw exception while testing unmasked range after "type" attribute of the password field was changed ${e}`);
} finally {
password.type = "password";
password.getBoundingClientRect();
passwordEditor = SpecialPowers.wrap(password).editor;
}
SimpleTest.finish();
});
</script>
</body>
</html>