From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../test/unit/test_collectFormFields.js | 638 +++++++++++++++++++++ 1 file changed, 638 insertions(+) create mode 100644 browser/extensions/formautofill/test/unit/test_collectFormFields.js (limited to 'browser/extensions/formautofill/test/unit/test_collectFormFields.js') diff --git a/browser/extensions/formautofill/test/unit/test_collectFormFields.js b/browser/extensions/formautofill/test/unit/test_collectFormFields.js new file mode 100644 index 0000000000..ac56d29c69 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/test_collectFormFields.js @@ -0,0 +1,638 @@ +/* + * Test for form auto fill content helper collectFormFields functions. + */ + +"use strict"; + +var FormAutofillHandler; +add_setup(async () => { + ({ FormAutofillHandler } = ChromeUtils.importESModule( + "resource://gre/modules/shared/FormAutofillHandler.sys.mjs" + )); +}); + +const TESTCASES = [ + { + description: "Form without autocomplete property", + document: `
+ + + + + + + +
`, + sections: [ + [ + { fieldName: "given-name" }, + { fieldName: "family-name" }, + { fieldName: "address-line1" }, + { fieldName: "address-level2" }, + { fieldName: "country" }, + { fieldName: "email" }, + { fieldName: "tel" }, + ], + ], + ids: [ + "given-name", + "family-name", + "street-addr", + "city", + "country", + "email", + "phone", + ], + }, + { + description: + "An address and credit card form with autocomplete properties and 1 token", + document: `
+ + + + + + + + + + + +
`, + sections: [ + [ + { fieldName: "given-name" }, + { fieldName: "family-name" }, + { fieldName: "street-address" }, + { fieldName: "address-level2" }, + { fieldName: "country" }, + { fieldName: "email" }, + { fieldName: "tel" }, + ], + [ + { fieldName: "cc-number" }, + { fieldName: "cc-name" }, + { fieldName: "cc-exp-month" }, + { fieldName: "cc-exp-year" }, + ], + ], + }, + { + description: "An address form with autocomplete properties and 2 tokens", + document: `
+ + + + + +
`, + sections: [ + [ + { addressType: "shipping", fieldName: "given-name" }, + { addressType: "shipping", fieldName: "family-name" }, + { addressType: "shipping", fieldName: "street-address" }, + { addressType: "shipping", fieldName: "address-level2" }, + { addressType: "shipping", fieldName: "country" }, + { addressType: "shipping", fieldName: "email" }, + { addressType: "shipping", fieldName: "tel" }, + ], + ], + }, + { + description: + "Form with autocomplete properties and profile is partly matched", + document: `
+ + + + + +
`, + sections: [ + [ + { addressType: "shipping", fieldName: "given-name" }, + { addressType: "shipping", fieldName: "family-name" }, + { addressType: "shipping", fieldName: "street-address" }, + { addressType: "shipping", fieldName: "address-level2" }, + { addressType: "shipping", fieldName: "country" }, + { addressType: "shipping", fieldName: "email" }, + { addressType: "shipping", fieldName: "tel" }, + ], + ], + }, + { + description: "It's a valid address and credit card form.", + document: `
+ + + + +
`, + sections: [ + [ + { addressType: "shipping", fieldName: "given-name" }, + { addressType: "shipping", fieldName: "family-name" }, + { addressType: "shipping", fieldName: "street-address" }, + ], + [{ addressType: "shipping", fieldName: "cc-number" }], + ], + }, + { + description: "An invalid address form due to less than 3 fields.", + document: `
+ + +
`, + sections: [], + }, + /* + * Valid Credit Card Form with autocomplete attribute + */ + { + description: "@autocomplete - A valid credit card form", + document: `
+ + + +
`, + sections: [ + [ + { fieldName: "cc-number" }, + { fieldName: "cc-name" }, + { fieldName: "cc-exp" }, + ], + ], + }, + { + description: "@autocomplete - A valid credit card form without cc-numner", + document: `
+ + +
`, + sections: [[{ fieldName: "cc-name" }, { fieldName: "cc-exp" }]], + }, + { + description: "@autocomplete - A valid cc-number only form", + document: `
`, + sections: [[{ fieldName: "cc-number" }]], + }, + { + description: "@autocomplete - A valid cc-name only form", + document: `
`, + sections: [[{ fieldName: "cc-name" }]], + }, + { + description: "@autocomplete - A valid cc-exp only form", + document: `
`, + sections: [[{ fieldName: "cc-exp" }]], + }, + { + description: "@autocomplete - A valid cc-exp-month + cc-exp-year form", + document: `
+ + +
`, + sections: [[{ fieldName: "cc-exp-month" }, { fieldName: "cc-exp-year" }]], + }, + { + description: "@autocomplete - A valid cc-exp-month only form", + document: `
`, + sections: [[{ fieldName: "cc-exp-month" }]], + }, + { + description: "@autocomplete - A valid cc-exp-year only form", + document: `
`, + sections: [[{ fieldName: "cc-exp-year" }]], + }, + /* + * Valid Credit Card Form when cc-number or cc-name is detected by fathom + */ + { + description: + "A valid credit card form without autocomplete attribute (cc-number is detected by fathom)", + document: `
+ + + +
`, + sections: [ + [ + { fieldName: "cc-number" }, + { fieldName: "cc-name" }, + { fieldName: "cc-exp" }, + ], + ], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.8", + ], + ], + }, + { + description: + "A valid credit card form without autocomplete attribute (only cc-number is detected by fathom)", + document: `
+ + + +
`, + sections: [ + [ + { fieldName: "cc-number" }, + { fieldName: "cc-name" }, + { fieldName: "cc-exp" }, + ], + ], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.8", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.types", + "cc-number", + ], + ], + }, + { + description: + "A valid credit card form without autocomplete attribute (only cc-name is detected by fathom)", + document: `
+ + +
`, + sections: [[{ fieldName: "cc-name" }, { fieldName: "cc-exp" }]], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.8", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.types", + "cc-name", + ], + ], + }, + /* + * Invalid Credit Card Form when a cc-number or cc-name is detected by fathom + */ + { + description: + "A credit card form is invalid when a fathom detected cc-number field is the only field in the form", + document: `
`, + sections: [], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.highConfidenceThreshold", + "0.9", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.8", + ], + ], + }, + { + description: + "A credit card form is invalid when a fathom detected cc-name field is the only field in the form", + document: `
`, + sections: [], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.highConfidenceThreshold", + "0.9", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.8", + ], + ], + }, + /* + * Valid Credit Card Form when a cc-number or cc-name only form is detected by fathom (field is high confidence) + */ + { + description: + "A cc-number only form is considered a valid credit card form when fathom is confident and there is no other in the form", + document: `
`, + sections: [[{ fieldName: "cc-number" }]], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.highConfidenceThreshold", + "0.95", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.99", + ], + ], + }, + { + description: + "A cc-name only form is considered a valid credit card form when fathom is confident and there is no other in the form", + document: `
`, + sections: [[{ fieldName: "cc-name" }]], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.highConfidenceThreshold", + "0.95", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.99", + ], + ], + }, + /* + * Invalid Credit Card Form when none of the fields is identified by fathom + */ + { + description: + "A credit card form is invalid when none of the fields are identified by fathom or autocomplete", + document: `
+ + + +
`, + sections: [], + prefs: [ + ["extensions.formautofill.creditCards.heuristics.fathom.types", ""], + ], + }, + // Special Cases + { + description: + "A credit card form with a high-confidence cc-name field is still considered invalid when there is another field", + document: `
+ + +
`, + sections: [], + prefs: [ + [ + "extensions.formautofill.creditCards.heuristics.fathom.highConfidenceThreshold", + "0.95", + ], + [ + "extensions.formautofill.creditCards.heuristics.fathom.testConfidence", + "0.96", + ], + ], + }, + { + description: "A valid credit card form with multiple cc-number fields", + document: `
+ + + + + + +
`, + sections: [ + [ + { fieldName: "cc-number" }, + { fieldName: "cc-number" }, + { fieldName: "cc-number" }, + { fieldName: "cc-number" }, + { fieldName: "cc-exp-month" }, + { fieldName: "cc-exp-year" }, + ], + ], + ids: [ + "cc-number1", + "cc-number2", + "cc-number3", + "cc-number4", + "cc-exp-month", + "cc-exp-year", + ], + }, + { + description: "Three sets of adjacent phone number fields", + document: `
+ + + + + + + + + + + + + +
`, + sections: [ + [ + { fieldName: "tel-area-code" }, + { fieldName: "tel-local-prefix" }, + { fieldName: "tel-local-suffix" }, + { fieldName: "tel-extension" }, + ], + [ + { fieldName: "tel-area-code" }, + { fieldName: "tel-local-prefix" }, + { fieldName: "tel-local-suffix" }, + + // TODO Bug 1421181 - "tel-country-code" field should belong to the next + // section. There should be a way to group the related fields during the + // parsing stage. + { fieldName: "tel-country-code" }, + ], + [ + { fieldName: "tel-area-code" }, + { fieldName: "tel-local-prefix" }, + { fieldName: "tel-local-suffix" }, + ], + ], + ids: [ + "shippingAC", + "shippingPrefix", + "shippingSuffix", + "shippingTelExt", + "billingAC", + "billingPrefix", + "billingSuffix", + "otherCC", + "otherAC", + "otherPrefix", + "otherSuffix", + ], + }, + { + description: + "Do not dedup the same field names of the different telephone fields.", + document: `
+ + + + + + + + +
`, + sections: [ + [ + { fieldName: "given-name" }, + { fieldName: "family-name" }, + { fieldName: "street-address" }, + { fieldName: "email" }, + { fieldName: "tel" }, + { fieldName: "tel" }, + { fieldName: "tel" }, + ], + ], + ids: ["i1", "i2", "i3", "i4", "homePhone", "mobilePhone", "officePhone"], + }, + { + description: + "The duplicated phones of a single one and a set with ac, prefix, suffix.", + document: `
+ + + + + + + + +
`, + sections: [ + [ + { addressType: "shipping", fieldName: "given-name" }, + { addressType: "shipping", fieldName: "family-name" }, + { addressType: "shipping", fieldName: "street-address" }, + { addressType: "shipping", fieldName: "email" }, + + // NOTES: Ideally, there is only one full telephone field(s) in a form for + // this case. We can see if there is any better solution later. + { addressType: "shipping", fieldName: "tel" }, + { addressType: "shipping", fieldName: "tel-area-code" }, + { addressType: "shipping", fieldName: "tel-local-prefix" }, + { addressType: "shipping", fieldName: "tel-local-suffix" }, + ], + ], + ids: [ + "i1", + "i2", + "i3", + "i4", + "singlePhone", + "shippingAreaCode", + "shippingPrefix", + "shippingSuffix", + ], + }, + { + description: "Always adopt the info from autocomplete attribute.", + document: `
+ + + + + +
`, + sections: [ + [ + { addressType: "shipping", fieldName: "given-name" }, + { addressType: "shipping", fieldName: "family-name" }, + { addressType: "shipping", fieldName: "tel" }, + { addressType: "shipping", fieldName: "tel" }, + { addressType: "shipping", fieldName: "tel" }, + ], + ], + ids: [ + "given-name", + "family-name", + "dummyAreaCode", + "dummyPrefix", + "dummySuffix", + ], + }, +]; + +function verifyDetails(handlerDetails, testCaseDetails) { + if (handlerDetails === null) { + Assert.equal(handlerDetails, testCaseDetails); + return; + } + Assert.equal(handlerDetails.length, testCaseDetails.length, "field count"); + handlerDetails.forEach((detail, index) => { + Assert.equal( + detail.fieldName, + testCaseDetails[index].fieldName, + "fieldName" + ); + Assert.equal( + detail.section, + testCaseDetails[index].section ?? "", + "section" + ); + Assert.equal( + detail.addressType, + testCaseDetails[index].addressType ?? "", + "addressType" + ); + Assert.equal( + detail.contactType, + testCaseDetails[index].contactType ?? "", + "contactType" + ); + Assert.equal( + detail.elementWeakRef.get(), + testCaseDetails[index].elementWeakRef.get(), + "DOM reference" + ); + }); +} + +for (let tc of TESTCASES) { + (function () { + let testcase = tc; + add_task(async function () { + info("Starting testcase: " + testcase.description); + + if (testcase.prefs) { + testcase.prefs.forEach(pref => SetPref(pref[0], pref[1])); + } + + let doc = MockDocument.createTestDocument( + "http://localhost:8080/test/", + testcase.document + ); + testcase.sections.flat().forEach((field, idx) => { + let elementRef = doc.getElementById( + testcase.ids?.[idx] ?? field.fieldName + ); + field.elementWeakRef = Cu.getWeakReference(elementRef); + }); + + let form = doc.querySelector("form"); + let formLike = FormLikeFactory.createFromForm(form); + + let handler = new FormAutofillHandler(formLike); + let validFieldDetails = handler.collectFormFields(); + + Assert.equal( + handler.sections.length, + testcase.sections.length, + "section count" + ); + for (let i = 0; i < handler.sections.length; i++) { + let section = handler.sections[i]; + verifyDetails(section.fieldDetails, testcase.sections[i]); + } + verifyDetails(validFieldDetails, testcase.sections.flat()); + + if (testcase.prefs) { + testcase.prefs.forEach(pref => Services.prefs.clearUserPref(pref[0])); + } + }); + })(); +} -- cgit v1.2.3