Bug 1673196 - NewPasswordModel: Don't assume @aria-labelledBy refers to an ID present in the document. r=sfoster

Differential Revision: https://phabricator.services.mozilla.com/D94687
This commit is contained in:
Matthew Noorenberghe 2020-10-27 22:40:55 +00:00
Родитель 21fd55f3a4
Коммит 246ca6e02b
2 изменённых файлов: 51 добавлений и 18 удалений

Просмотреть файл

@ -31,7 +31,7 @@ const {
* ----- Start of model -----
*
* Everything below this comment up to the "End of model" comment is copied from:
* https://github.com/mozilla-services/fathom-login-forms/blob/c1e5136/new-password/rulesets.js#L14-L539
* https://github.com/mozilla-services/fathom-login-forms/blob/3a2f8806cc8c3716be2aa426a6e9a6d2bebd737d/new-password/rulesets.js#L14-L540
* Deviations from that file:
* - Remove import statements, instead using ``ChromeUtils.defineModuleGetter`` and destructuring assignments above.
* - Set ``DEVELOPMENT`` constant to ``false``.
@ -138,7 +138,8 @@ function makeRuleset(coeffs, biases) {
if (labelledBy !== null) {
labelledBy = labelledBy
.split(" ")
.map(id => element.ownerDocument.getElementById(id));
.map(id => element.getRootNode().getElementById(id))
.filter(el => el);
if (labelledBy.length === 1) {
return regex.test(labelledBy[0].textContent);
} else if (labelledBy.length > 1) {

Просмотреть файл

@ -8,6 +8,21 @@ const LoginAutoComplete = Cc[
"@mozilla.org/login-manager/autocompletesearch;1"
].getService(Ci.nsILoginAutoCompleteSearch).wrappedJSObject;
function labelledByDocument() {
let doc = MockDocument.createTestDocument(
"http://localhost:8080/test/",
`<div>
<label id="paper-input-label-2">Password</label>
<input aria-labelledby="paper-input-label-2" type="password">
</div>`
);
let div = doc.querySelector("div");
// Put the div contents inside shadow DOM.
div.attachShadow({ mode: "open" }).append(...div.children);
return doc;
}
const LABELLEDBY_SHADOW_TESTCASE = labelledByDocument();
const TESTCASES = [
// Note there is no test case for `<input type="password" autocomplete="new-password">`
// since _isProbablyANewPasswordField explicitly does not run in that case.
@ -79,6 +94,14 @@ const TESTCASES = [
`,
expectedResult: [false, true, true],
},
{
description: "Password field with aria-labelledby inside shadow DOM",
document: LABELLEDBY_SHADOW_TESTCASE,
inputs: LABELLEDBY_SHADOW_TESTCASE.querySelector(
"div"
).shadowRoot.querySelectorAll("input[type='password']"),
expectedResult: [false],
},
];
add_task(async function test_returns_false_when_pref_disabled() {
@ -92,17 +115,22 @@ add_task(async function test_returns_false_when_pref_disabled() {
// Use registration form test case, where we know it should return true if enabled
const testcase = TESTCASES[1];
info("Starting testcase: " + testcase.description);
const document = MockDocument.createTestDocument(
"http://localhost:8080/test/",
testcase.document
);
const input = document.querySelectorAll(`input[type="password"]`);
const result = LoginAutoComplete._isProbablyANewPasswordField(input);
Assert.strictEqual(
result,
false,
`When the pref is set to disable, the result is always false, e.g. for the testcase, ${testcase.description} `
);
const document =
testcase.document instanceof Document
? testcase.document
: MockDocument.createTestDocument(
"http://localhost:8080/test/",
testcase.document
);
for (let [i, input] of testcase.inputs ||
document.querySelectorAll(`input[type="password"]`).entries()) {
const result = LoginAutoComplete._isProbablyANewPasswordField(input);
Assert.strictEqual(
result,
false,
`When the pref is set to disable, the result is always false, e.g. for the testcase, ${testcase.description} ${i}`
);
}
info("Re-enabling new-password heuristic pref");
Services.prefs.setStringPref(NEW_PASSWORD_HEURISTIC_ENABLED_PREF, threshold);
@ -114,13 +142,17 @@ for (let testcase of TESTCASES) {
(function() {
add_task(async function() {
info("Starting testcase: " + testcase.description);
let document = MockDocument.createTestDocument(
"http://localhost:8080/test/",
testcase.document
);
let document =
testcase.document instanceof Document
? testcase.document
: MockDocument.createTestDocument(
"http://localhost:8080/test/",
testcase.document
);
const results = [];
for (let input of document.querySelectorAll(`input[type="password"]`)) {
for (let input of testcase.inputs ||
document.querySelectorAll(`input[type="password"]`)) {
const result = LoginAutoComplete._isProbablyANewPasswordField(input);
results.push(result);
}