366 lines
12 KiB
JavaScript
366 lines
12 KiB
JavaScript
"use strict";
|
|
|
|
var { FormAutofillHeuristics } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/shared/FormAutofillHeuristics.sys.mjs"
|
|
);
|
|
var { LabelUtils } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/shared/LabelUtils.sys.mjs"
|
|
);
|
|
var { FormAutofill } = ChromeUtils.importESModule(
|
|
"resource://autofill/FormAutofill.sys.mjs"
|
|
);
|
|
|
|
const TESTCASES = [
|
|
{
|
|
description: "Input element in a label element",
|
|
document: `<form>
|
|
<label> E-Mail
|
|
<input id="targetElement" type="text">
|
|
</label>
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description:
|
|
"A label element is out of the form contains the related input",
|
|
document: `<label for="targetElement"> E-Mail</label>
|
|
<form>
|
|
<input id="targetElement" type="text">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: "A label element contains span element",
|
|
document: `<label for="targetElement">FOO<span>E-Mail</span>BAR</label>
|
|
<form>
|
|
<input id="targetElement" type="text">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: "The signature in 'name' attr of an input",
|
|
document: `<input id="targetElement" name="email" type="text">`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: "The signature in 'id' attr of an input",
|
|
document: `<input id="targetElement_email" name="tel" type="text">`,
|
|
elementId: "targetElement_email",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: "Select element in a label element",
|
|
document: `<form>
|
|
<label> State
|
|
<select id="targetElement"></select>
|
|
</label>
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["address-level1", {}],
|
|
},
|
|
{
|
|
description: "A select element without a form wrapped",
|
|
document: `<label for="targetElement">State</label>
|
|
<select id="targetElement"></select>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["address-level1", {}],
|
|
},
|
|
{
|
|
description: "address line input",
|
|
document: `<label for="targetElement">street</label>
|
|
<input id="targetElement" type="text">`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["street-address", {}],
|
|
},
|
|
{
|
|
description: "CJK character - Traditional Chinese",
|
|
document: `<label> 郵遞區號
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["postal-code", {}],
|
|
},
|
|
{
|
|
description: "CJK character - Japanese",
|
|
document: `<label> 郵便番号
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["postal-code", {}],
|
|
},
|
|
{
|
|
description: "CJK character - Korean",
|
|
document: `<label> 우편 번호
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["postal-code", {}],
|
|
},
|
|
{
|
|
description: "",
|
|
document: `<input id="targetElement" name="fullname">`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["name", {}],
|
|
},
|
|
{
|
|
description: 'input element with "submit" type',
|
|
document: `<input id="targetElement" type="submit" />`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: [[], {}],
|
|
},
|
|
{
|
|
description: "The signature in 'name' attr of an email input",
|
|
document: `<input id="targetElement" name="email" type="number">`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: 'input element with "email" type',
|
|
document: `<input id="targetElement" type="email" />`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["email", {}],
|
|
},
|
|
{
|
|
description: "Exclude United State string",
|
|
document: `<label>United State
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: [[], {}],
|
|
},
|
|
{
|
|
description: '"County" field with "United State" string',
|
|
document: `<label>United State County
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["address-level1", {}],
|
|
},
|
|
{
|
|
description: '"city" field with double "United State" string',
|
|
document: `<label>United State united sTATE city
|
|
<input id="targetElement" />
|
|
</label>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["address-level2", {}],
|
|
},
|
|
{
|
|
description: "Verify credit card number",
|
|
document: `<form>
|
|
<label for="targetElement"> Card Number</label>
|
|
<input id="targetElement" type="text">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: [
|
|
"cc-number",
|
|
{ fathomLabel: "cc-number", fathomConfidence: 1 },
|
|
],
|
|
},
|
|
{
|
|
description: "Identify credit card type field",
|
|
document: `<form>
|
|
<label for="targetElement">Card Type</label>
|
|
<input id="targetElement" type="text">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["cc-type", {}],
|
|
},
|
|
{
|
|
description: `Identify address field when contained in a form with autocomplete="off"`,
|
|
document: `<form autocomplete="off">
|
|
<input id="given-name">
|
|
</form>`,
|
|
elementId: "given-name",
|
|
expectedReturnValue: ["given-name", {}],
|
|
},
|
|
{
|
|
description: `Identify address field that has a placeholder but no label associated with it`,
|
|
document: `<form>
|
|
<input id="targetElement" placeholder="Name">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["name", {}],
|
|
},
|
|
{
|
|
description: `Identify address field that has a placeholder, no associated label, and its autocomplete attribute is "off"`,
|
|
document: `<form>
|
|
<input id="targetElement" placeholder="Address" autocomplete="off">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["street-address", {}],
|
|
},
|
|
{
|
|
description: `Identify address field that has a placeholder, no associated label, and the form's autocomplete attribute is "off"`,
|
|
document: `<form autocomplete="off">
|
|
<input id="targetElement" placeholder="Country">
|
|
</form>`,
|
|
elementId: "targetElement",
|
|
expectedReturnValue: ["country", {}],
|
|
},
|
|
];
|
|
|
|
add_setup(async function () {
|
|
Services.prefs.setStringPref(
|
|
"extensions.formautofill.creditCards.heuristics.fathom.testConfidence",
|
|
"1"
|
|
);
|
|
|
|
registerCleanupFunction(() => {
|
|
Services.prefs.clearUserPref(
|
|
"extensions.formautofill.creditCards.heuristics.fathom.testConfidence"
|
|
);
|
|
});
|
|
});
|
|
|
|
TESTCASES.forEach(testcase => {
|
|
add_task(async function () {
|
|
info("Starting testcase: " + testcase.description);
|
|
|
|
let doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
testcase.document
|
|
);
|
|
|
|
let element = doc.getElementById(testcase.elementId);
|
|
let value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, testcase.expectedReturnValue);
|
|
LabelUtils.clearLabelMap();
|
|
});
|
|
});
|
|
|
|
add_task(async function test_regexp_list() {
|
|
info("Verify the fieldName support for select element.");
|
|
let SUPPORT_LIST = {
|
|
email: null, // email
|
|
"tel-extension": null, // tel-extension
|
|
phone: null, // tel
|
|
organization: null, // organization
|
|
"street-address": null, // street-address
|
|
address1: null, // address-line1
|
|
address2: null, // address-line2
|
|
address3: null, // address-line3
|
|
city: "address-level2",
|
|
region: "address-level1",
|
|
"postal-code": null, // postal-code
|
|
country: "country",
|
|
fullname: null, // name
|
|
fname: null, // given-name
|
|
mname: null, // additional-name
|
|
lname: null, // family-name
|
|
cardholder: null, // cc-name
|
|
"cc-number": null, // cc-number
|
|
addmonth: "cc-exp-month",
|
|
addyear: "cc-exp-year",
|
|
};
|
|
for (let label of Object.keys(SUPPORT_LIST)) {
|
|
let testcase = {
|
|
description: `A select element supports ${label} or not`,
|
|
document: `<select id="${label}"></select>`,
|
|
elementId: label,
|
|
expectedReturnValue: SUPPORT_LIST[label]
|
|
? [SUPPORT_LIST[label], {}]
|
|
: [[], {}],
|
|
};
|
|
info(testcase.description);
|
|
info(testcase.document);
|
|
let doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
testcase.document
|
|
);
|
|
|
|
let element = doc.getElementById(testcase.elementId);
|
|
let value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, testcase.expectedReturnValue, label);
|
|
}
|
|
LabelUtils.clearLabelMap();
|
|
});
|
|
|
|
add_task(async function test_autofill_creditCards_autocomplete_off_pref() {
|
|
let document = `<form autocomplete="off">
|
|
<label for="targetElement"> Card Number</label>
|
|
<input id="targetElement" type="text">
|
|
</form>`;
|
|
let expected = [[], {}];
|
|
info(`Set pref so that credit card autofill respects autocomplete="off"`);
|
|
Services.prefs.setBoolPref(
|
|
FormAutofill.AUTOFILL_CREDITCARDS_AUTOCOMPLETE_OFF_PREF,
|
|
false
|
|
);
|
|
let doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
document
|
|
);
|
|
let element = doc.getElementById("targetElement");
|
|
let value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, expected);
|
|
document = `<form>
|
|
<label for="targetElement"> Card Number</label>
|
|
<input id="targetElement" type="text">
|
|
</form>`;
|
|
expected = ["cc-number", { fathomLabel: "cc-number", fathomConfidence: 1 }];
|
|
info(
|
|
`Set pref so that credit card autofill does not respect autocomplete="off"`
|
|
);
|
|
Services.prefs.setBoolPref(
|
|
FormAutofill.AUTOFILL_CREDITCARDS_AUTOCOMPLETE_OFF_PREF,
|
|
true
|
|
);
|
|
doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
document
|
|
);
|
|
element = doc.getElementById("targetElement");
|
|
value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, expected);
|
|
Services.prefs.clearUserPref(
|
|
FormAutofill.AUTOFILL_CREDITCARDS_AUTOCOMPLETE_OFF_PREF
|
|
);
|
|
});
|
|
|
|
add_task(async function test_autofill_addresses_autocomplete_off_pref() {
|
|
let document = `<form autocomplete="off">
|
|
<input id="given-name">
|
|
</form>`;
|
|
let expected = [[], {}];
|
|
info(`Set pref so that address autofill respects autocomplete="off"`);
|
|
Services.prefs.setBoolPref(
|
|
FormAutofill.AUTOFILL_ADDRESSES_AUTOCOMPLETE_OFF_PREF,
|
|
false
|
|
);
|
|
let doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
document
|
|
);
|
|
let element = doc.getElementById("given-name");
|
|
let value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, expected);
|
|
document = `<form>
|
|
<input id="given-name">
|
|
</form>`;
|
|
expected = ["given-name", {}];
|
|
info(`Set pref so that address autofill does not respect autocomplete="off"`);
|
|
Services.prefs.setBoolPref(
|
|
FormAutofill.AUTOFILL_ADDRESSES_AUTOCOMPLETE_OFF_PREF,
|
|
true
|
|
);
|
|
doc = MockDocument.createTestDocument(
|
|
"http://localhost:8080/test/",
|
|
document
|
|
);
|
|
element = doc.getElementById("given-name");
|
|
value = FormAutofillHeuristics.inferFieldInfo(element);
|
|
|
|
Assert.deepEqual(value, expected);
|
|
Services.prefs.clearUserPref(
|
|
FormAutofill.AUTOFILL_ADDRESSES_AUTOCOMPLETE_OFF_PREF
|
|
);
|
|
});
|