summaryrefslogtreecommitdiffstats
path: root/browser/extensions/formautofill
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
commitfbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch)
tree4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /browser/extensions/formautofill
parentReleasing progress-linux version 124.0.1-1~progress7.99u1. (diff)
downloadfirefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz
firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/extensions/formautofill')
-rw-r--r--browser/extensions/formautofill/api.js2
-rw-r--r--browser/extensions/formautofill/background.js2
-rw-r--r--browser/extensions/formautofill/content/autofillEditForms.js8
-rw-r--r--browser/extensions/formautofill/content/customElements.js11
-rw-r--r--browser/extensions/formautofill/content/editDialog.js6
-rw-r--r--browser/extensions/formautofill/content/manageCreditCards.xhtml1
-rw-r--r--browser/extensions/formautofill/content/manageDialog.js7
-rw-r--r--browser/extensions/formautofill/locales/en-US/formautofill.properties6
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser.toml2
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_capture_form_removal.js2
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_capture_trimmed_data.js100
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_not_shown.js2
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js103
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_unsupported_region.js4
-rw-r--r--browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js2
-rw-r--r--browser/extensions/formautofill/test/browser/browser.toml3
-rw-r--r--browser/extensions/formautofill/test/browser/browser_active_window_navigation.js6
-rw-r--r--browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js47
-rw-r--r--browser/extensions/formautofill/test/browser/browser_autofill_sandboxed_iframe.js31
-rw-r--r--browser/extensions/formautofill/test/browser/creditCard/browser.toml78
-rw-r--r--browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_form_removal.js2
-rw-r--r--browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_multiple_cc_number.js102
-rw-r--r--browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_not_shown.js2
-rw-r--r--browser/extensions/formautofill/test/browser/head.js14
-rw-r--r--browser/extensions/formautofill/test/browser/heuristics/browser.toml4
-rw-r--r--browser/extensions/formautofill/test/browser/heuristics/browser_ignore_unfocusable_fields.js159
-rw-r--r--browser/extensions/formautofill/test/browser/heuristics/browser_sections_with_invisible_fields.js131
-rw-r--r--browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Euronics.js2
-rw-r--r--browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js11
-rw-r--r--browser/extensions/formautofill/test/fixtures/autocomplete_iframe_sandboxed.html11
-rw-r--r--browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html1
-rw-r--r--browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html1
-rw-r--r--browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html2
-rw-r--r--browser/extensions/formautofill/test/mochitest/formautofill_common.js22
-rw-r--r--browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js34
-rw-r--r--browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html6
-rw-r--r--browser/extensions/formautofill/test/mochitest/test_form_changes.html3
-rw-r--r--browser/extensions/formautofill/test/unit/head.js18
-rw-r--r--browser/extensions/formautofill/test/unit/test_autofillFormFields.js35
-rw-r--r--browser/extensions/formautofill/test/unit/test_getFormInputDetails.js18
-rw-r--r--browser/extensions/formautofill/test/unit/test_markAsAutofillField.js32
-rw-r--r--browser/extensions/formautofill/test/unit/test_onFormSubmitted.js712
-rw-r--r--browser/extensions/formautofill/test/unit/test_phoneNumber.js4
-rw-r--r--browser/extensions/formautofill/test/unit/test_previewFormFields.js2
-rw-r--r--browser/extensions/formautofill/test/unit/test_storage_tombstones.js8
-rw-r--r--browser/extensions/formautofill/test/unit/xpcshell.toml6
46 files changed, 697 insertions, 1068 deletions
diff --git a/browser/extensions/formautofill/api.js b/browser/extensions/formautofill/api.js
index 000c393e8e..967b4a8d63 100644
--- a/browser/extensions/formautofill/api.js
+++ b/browser/extensions/formautofill/api.js
@@ -179,7 +179,7 @@ this.formautofill = class extends ExtensionAPI {
esModuleURI: "resource://autofill/FormAutofillChild.sys.mjs",
events: {
focusin: {},
- DOMFormBeforeSubmit: {},
+ "form-submission-detected": {},
},
},
allFrames: true,
diff --git a/browser/extensions/formautofill/background.js b/browser/extensions/formautofill/background.js
index fe6265415f..199d6fc20a 100644
--- a/browser/extensions/formautofill/background.js
+++ b/browser/extensions/formautofill/background.js
@@ -6,7 +6,7 @@
"use strict";
-browser.runtime.onUpdateAvailable.addListener(details => {
+browser.runtime.onUpdateAvailable.addListener(_details => {
// By listening to but ignoring this event, any updates will
// be delayed until the next browser restart.
// Note that if we ever wanted to change this, we should make
diff --git a/browser/extensions/formautofill/content/autofillEditForms.js b/browser/extensions/formautofill/content/autofillEditForms.js
index fea7a90a0a..290b436a64 100644
--- a/browser/extensions/formautofill/content/autofillEditForms.js
+++ b/browser/extensions/formautofill/content/autofillEditForms.js
@@ -112,10 +112,8 @@ class EditAutofillForm {
/**
* Handle input events
- *
- * @param {DOMEvent} event
*/
- handleInput(event) {}
+ handleInput(_e) {}
/**
* Attach event listener
@@ -140,9 +138,9 @@ class EditAutofillForm {
/**
* Run custom validity routines specific to the field and type of form.
*
- * @param {DOMElement} field The field that will be validated.
+ * @param {DOMElement} _field The field that will be validated.
*/
- updateCustomValidity(field) {}
+ updateCustomValidity(_field) {}
}
class EditAddress extends EditAutofillForm {
diff --git a/browser/extensions/formautofill/content/customElements.js b/browser/extensions/formautofill/content/customElements.js
index 0f1260634d..2f22a8173a 100644
--- a/browser/extensions/formautofill/content/customElements.js
+++ b/browser/extensions/formautofill/content/customElements.js
@@ -287,16 +287,7 @@
this._itemBox.setAttribute("no-warning", "true");
}
- // After focusing a field that was previously filled with cc information,
- // the "ac-image" is falsely set for the listitem-footer. For now it helps us
- // to distinguish between address and cc footer. In the future this false attribute
- // setting should be fixed and the "ac-image" check replaced by a different method.
- const buttonTextBundleKey = !this.getAttribute("ac-image")
- ? "autocompleteManageAddresses"
- : "autocompleteManageCreditCards";
- const buttonText =
- this._stringBundle.GetStringFromName(buttonTextBundleKey);
- this._optionButton.textContent = buttonText;
+ this._optionButton.textContent = value.manageLabel;
}
}
diff --git a/browser/extensions/formautofill/content/editDialog.js b/browser/extensions/formautofill/content/editDialog.js
index 8aad87ceb3..467acbdd07 100644
--- a/browser/extensions/formautofill/content/editDialog.js
+++ b/browser/extensions/formautofill/content/editDialog.js
@@ -8,7 +8,7 @@
"use strict";
ChromeUtils.defineESModuleGetters(this, {
- AutofillTelemetry: "resource://autofill/AutofillTelemetry.sys.mjs",
+ AutofillTelemetry: "resource://gre/modules/shared/AutofillTelemetry.sys.mjs",
formAutofillStorage: "resource://autofill/FormAutofillStorage.sys.mjs",
});
@@ -107,10 +107,8 @@ class AutofillEditDialog {
/**
* Handle input events
- *
- * @param {DOMEvent} event
*/
- handleInput(event) {
+ handleInput(_e) {
this.updateSaveButtonState();
}
diff --git a/browser/extensions/formautofill/content/manageCreditCards.xhtml b/browser/extensions/formautofill/content/manageCreditCards.xhtml
index 2b33f7750f..e7baf9d364 100644
--- a/browser/extensions/formautofill/content/manageCreditCards.xhtml
+++ b/browser/extensions/formautofill/content/manageCreditCards.xhtml
@@ -11,6 +11,7 @@
<head>
<title data-l10n-id="autofill-manage-payment-methods-title"></title>
<link rel="localization" href="browser/preferences/formAutofill.ftl" />
+ <link rel="localization" href="toolkit/formautofill/formAutofill.ftl" />
<link rel="localization" href="toolkit/payments/payments.ftl" />
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
<link
diff --git a/browser/extensions/formautofill/content/manageDialog.js b/browser/extensions/formautofill/content/manageDialog.js
index b6bcb3a77b..ad5cefbb15 100644
--- a/browser/extensions/formautofill/content/manageDialog.js
+++ b/browser/extensions/formautofill/content/manageDialog.js
@@ -17,7 +17,7 @@ const { FormAutofill } = ChromeUtils.importESModule(
"resource://autofill/FormAutofill.sys.mjs"
);
const { AutofillTelemetry } = ChromeUtils.importESModule(
- "resource://autofill/AutofillTelemetry.sys.mjs"
+ "resource://gre/modules/shared/AutofillTelemetry.sys.mjs"
);
ChromeUtils.defineESModuleGetters(this, {
@@ -197,6 +197,9 @@ class ManageRecords {
this._elements.edit.setAttribute("disabled", "disabled");
this._elements.remove.removeAttribute("disabled");
}
+ this._elements.add.disabled = !Services.prefs.getBoolPref(
+ `extensions.formautofill.${this._subStorageName}.enabled`
+ );
}
/**
@@ -265,7 +268,7 @@ class ManageRecords {
}
}
- observe(subject, topic, data) {
+ observe(_subject, topic, _data) {
switch (topic) {
case "formautofill-storage-changed": {
this.loadRecords();
diff --git a/browser/extensions/formautofill/locales/en-US/formautofill.properties b/browser/extensions/formautofill/locales/en-US/formautofill.properties
index 2447b652c8..d3add192d7 100644
--- a/browser/extensions/formautofill/locales/en-US/formautofill.properties
+++ b/browser/extensions/formautofill/locales/en-US/formautofill.properties
@@ -2,12 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-# LOCALIZATION NOTE (autocompleteManageCreditCards):
-# Used as a label for the button, displayed at the bottom of the dropdown suggestion, to open Form Autofill browser preferences.
-autocompleteManageCreditCards = Manage credit cards
-# LOCALIZATION NOTE (autocompleteManageAddresses):
-# Used as a label for the button, displayed at the bottom of the dropdown suggestion, to open Form Autofill browser preferences.
-autocompleteManageAddresses = Manage addresses
# LOCALIZATION NOTE (category.address, category.name, category.organization2, category.tel, category.email):
# Used in autofill drop down suggestion to indicate what other categories Form Autofill will attempt to fill.
category.address = address
diff --git a/browser/extensions/formautofill/test/browser/address/browser.toml b/browser/extensions/formautofill/test/browser/address/browser.toml
index bff24a88b0..8b7f1ec760 100644
--- a/browser/extensions/formautofill/test/browser/address/browser.toml
+++ b/browser/extensions/formautofill/test/browser/address/browser.toml
@@ -18,6 +18,8 @@ support-files = [
["browser_address_capture_page_navigation.js"]
+["browser_address_capture_trimmed_data.js"]
+
["browser_address_doorhanger_confirmation_popup.js"]
["browser_address_doorhanger_display.js"]
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_capture_form_removal.js b/browser/extensions/formautofill/test/browser/address/browser_address_capture_form_removal.js
index f94fc8241f..fed89d4599 100644
--- a/browser/extensions/formautofill/test/browser/address/browser_address_capture_form_removal.js
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_capture_form_removal.js
@@ -118,7 +118,7 @@ add_task(async function test_address_not_captured_without_prior_fetch() {
});
info("Ensure that address doorhanger is not shown");
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
});
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_capture_trimmed_data.js b/browser/extensions/formautofill/test/browser/address/browser_address_capture_trimmed_data.js
new file mode 100644
index 0000000000..c0856dfb8d
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_capture_trimmed_data.js
@@ -0,0 +1,100 @@
+"use strict";
+
+const DEFAULT_TEST_DOC = `
+<form id="form">
+ <input id="street-address" autocomplete="street-address">
+ <select id="address-level1" autocomplete="address-level1">
+ <option value=""></option>
+ <option value="AL">Alabama</option>
+ <option value="AK">Alaska</option>
+ <option value="AP">Armed Forces Pacific</option>
+
+ <option value="ca">california</option>
+ <option value="AR">US-Arkansas</option>
+ <option value="US-CA">California</option>
+ <option value="CA">California</option>
+ <option value="US-AZ">US_Arizona</option>
+ <option value="Ariz">Arizonac</option>
+</select>
+<input id="city" autocomplete="address-level2">
+<input id="country" autocomplete="country">
+<input id="email" autocomplete="email">
+<input id="tel" autocomplete="tel">
+<input type="submit"/>
+</form>`;
+
+const TESTCASES = [
+ {
+ description: "Save address with trimmed address data",
+ document: DEFAULT_TEST_DOC,
+ targetElementId: "street-address",
+ formValue: {
+ "#street-address": "331 E. Evelyn Avenue ",
+ "#country": "US",
+ "#email": " ",
+ "#tel": "1-650-903-0800",
+ },
+ expected: [
+ {
+ "street-address": "331 E. Evelyn Avenue",
+ country: "US",
+ email: "",
+ tel: "+16509030800",
+ },
+ ],
+ },
+];
+
+async function expectSavedAddresses(expectedAddresses) {
+ const addresses = await getAddresses();
+ is(
+ addresses.length,
+ expectedAddresses.length,
+ `${addresses.length} address in the storage`
+ );
+
+ for (let i = 0; i < expectedAddresses.length; i++) {
+ for (const [key, value] of Object.entries(expectedAddresses[i])) {
+ is(addresses[i][key] ?? "", value, `field ${key} should be equal`);
+ }
+ }
+ return addresses;
+}
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["extensions.formautofill.addresses.enabled", true],
+ ["extensions.formautofill.addresses.supported", "on"],
+ ["extensions.formautofill.addresses.capture.enabled", true],
+ ],
+ });
+});
+
+add_task(async function test_address_capture_trimmed_data() {
+ for (const TEST of TESTCASES) {
+ info(`Test ${TEST.description}`);
+
+ const onChanged = waitForStorageChangedEvents("add");
+ await BrowserTestUtils.withNewTab(EMPTY_URL, async function (browser) {
+ await SpecialPowers.spawn(browser, [TEST.document], doc => {
+ content.document.body.innerHTML = doc;
+ });
+
+ await SimpleTest.promiseFocus(browser);
+
+ const onPopupShown = waitForPopupShown();
+ await focusUpdateSubmitForm(browser, {
+ focusSelector: `#${TEST.targetElementId}`,
+ newValues: TEST.formValue,
+ });
+
+ await onPopupShown;
+ await clickDoorhangerButton(MAIN_BUTTON, 0);
+ });
+ await onChanged;
+
+ await expectSavedAddresses(TEST.expected);
+ await removeAllRecords();
+ }
+});
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_not_shown.js b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_not_shown.js
index b1b8a6b9d2..84508189bd 100644
--- a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_not_shown.js
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_not_shown.js
@@ -87,7 +87,7 @@ add_task(async function test_save_doorhanger_not_shown() {
newValues: TEST.formValue,
});
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
});
if (TEST.prefs) {
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js
index a247341fef..f3b04d7f9c 100644
--- a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js
@@ -1,4 +1,5 @@
"use strict";
+requestLongerTimeout(3);
async function expectSavedAddresses(expectedAddresses) {
const addresses = await getAddresses();
@@ -18,7 +19,11 @@ async function expectSavedAddresses(expectedAddresses) {
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
- set: [["extensions.formautofill.addresses.capture.enabled", true]],
+ set: [
+ ["extensions.formautofill.addresses.enabled", true],
+ ["extensions.formautofill.addresses.supported", "on"],
+ ["extensions.formautofill.addresses.capture.enabled", true],
+ ],
});
});
@@ -102,6 +107,7 @@ add_task(async function test_save_doorhanger_state_valid() {
for (const TEST of TEST_CASES) {
await expectSavedAddresses([]);
+ const onChanged = waitForStorageChangedEvents("add");
await BrowserTestUtils.withNewTab(
{ gBrowser, url: ADDRESS_FORM_URL },
async function (browser) {
@@ -122,8 +128,103 @@ add_task(async function test_save_doorhanger_state_valid() {
await clickDoorhangerButton(MAIN_BUTTON, 0);
}
);
+ await onChanged;
await expectSavedAddresses([Object.assign(DEFAULT, TEST.expected)]);
await removeAllRecords();
}
});
+
+add_task(async function test_save_doorhanger_state_is_select() {
+ const DEFAULT_TEST_DOC = `
+ <form id="form">
+ <input id="name" autocomplete="name">
+ <input id="street-address" autocomplete="street-address">
+ <select id="address-level1" autocomplete="address-level1">
+ <option value=""></option>
+ <option value="AL">Alabama</option>
+ <option value="AK">Alaska</option>
+ <option value="AP">Armed Forces Pacific</option>
+
+ <option value="ca">california</option>
+ <option value="AR">US-Arkansas</option>
+ <option value="US-CA">California</option>
+ <option value="CA">California</option>
+ <option value="US-AZ">US_Arizona</option>
+ <option value="Ariz">Arizonac</option>
+ </select>
+ <input id="city" autocomplete="address-level2">
+ <input id="country" autocomplete="country">
+ <input id="submit" type="submit">
+ </form>`;
+
+ const TEST_CASES = [
+ {
+ description: "Save state with regular select option",
+ filled: { "address-level1": "CA" },
+ expected: { "address-level1": "CA" },
+ },
+ {
+ description: "Save state with lowercase value",
+ filled: { "address-level1": "ca" },
+ expected: { "address-level1": "CA" },
+ },
+ {
+ description: "Save state with a country code prefixed to the label",
+ filled: { "address-level1": "AR" },
+ expected: { "address-level1": "AR" },
+ },
+ {
+ description: "Save state with a country code prefixed to the value",
+ filled: { "address-level1": "US-CA" },
+ expected: { "address-level1": "CA" },
+ },
+ {
+ description:
+ "Save state with a country code prefixed to the value and label",
+ filled: { "address-level1": "US-AZ" },
+ expected: { "address-level1": "AZ" },
+ },
+ {
+ description: "Should not save when failed to abbreviate the value",
+ filled: { "address-level1": "Ariz" },
+ expected: { "address-level1": "" },
+ },
+ {
+ description: "Should not save select with multiple selections",
+ filled: { "address-level1": ["AL", "AK", "AP"] },
+ expected: { "address-level1": "" },
+ },
+ ];
+
+ for (const TEST of TEST_CASES) {
+ const onChanged = waitForStorageChangedEvents("add");
+ await BrowserTestUtils.withNewTab(EMPTY_URL, async function (browser) {
+ info(`Test ${TEST.description}`);
+
+ await SpecialPowers.spawn(browser, [DEFAULT_TEST_DOC], doc => {
+ content.document.body.innerHTML = doc;
+ });
+
+ await SimpleTest.promiseFocus(browser);
+
+ const onPopupShown = waitForPopupShown();
+ await focusUpdateSubmitForm(browser, {
+ focusSelector: "#name",
+ newValues: {
+ "#name": "John Doe",
+ "#street-address": "Main Street",
+ "#country": "US",
+ "#address-level1": TEST.filled["address-level1"],
+ },
+ });
+
+ await onPopupShown;
+ await clickDoorhangerButton(MAIN_BUTTON, 0);
+ });
+ await onChanged;
+
+ await expectSavedAddresses([TEST.expected]);
+ await removeAllRecords();
+ }
+});
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_unsupported_region.js b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_unsupported_region.js
index fc3d1c7cf4..243f857fbb 100644
--- a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_unsupported_region.js
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_unsupported_region.js
@@ -53,7 +53,7 @@ add_task(async function test_save_doorhanger_unsupported_region_from_record() {
},
});
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
});
@@ -79,7 +79,7 @@ add_task(async function test_save_doorhanger_unsupported_region_from_pref() {
},
});
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js b/browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js
index acd7a7c364..b55abd6c72 100644
--- a/browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js
+++ b/browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js
@@ -7,7 +7,7 @@ const { TelemetryTestUtils } = ChromeUtils.importESModule(
);
const { AddressTelemetry } = ChromeUtils.importESModule(
- "resource://autofill/AutofillTelemetry.sys.mjs"
+ "resource://gre/modules/shared/AutofillTelemetry.sys.mjs"
);
// Telemetry definitions
diff --git a/browser/extensions/formautofill/test/browser/browser.toml b/browser/extensions/formautofill/test/browser/browser.toml
index 2c9a995e67..7e7f0b8b68 100644
--- a/browser/extensions/formautofill/test/browser/browser.toml
+++ b/browser/extensions/formautofill/test/browser/browser.toml
@@ -4,6 +4,7 @@ support-files = [
"./fathom/**",
"../fixtures/autocomplete_basic.html",
"../fixtures/autocomplete_iframe.html",
+ "../fixtures/autocomplete_iframe_sandboxed.html",
"../fixtures/autocomplete_simple_basic.html",
"../fixtures/page_navigation.html",
"./empty.html",
@@ -26,6 +27,8 @@ skip-if = [
["browser_autofill_duplicate_fields.js"]
+["browser_autofill_sandboxed_iframe.js"]
+
["browser_check_installed.js"]
["browser_dropdown_layout.js"]
diff --git a/browser/extensions/formautofill/test/browser/browser_active_window_navigation.js b/browser/extensions/formautofill/test/browser/browser_active_window_navigation.js
index 17cda3137d..6c69b9d63e 100644
--- a/browser/extensions/formautofill/test/browser/browser_active_window_navigation.js
+++ b/browser/extensions/formautofill/test/browser/browser_active_window_navigation.js
@@ -69,7 +69,7 @@ add_task(
});
info("Ensure address doorhanger not shown");
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
}
@@ -124,7 +124,7 @@ add_task(
});
info("Ensure address doorhanger not shown");
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
}
@@ -238,7 +238,7 @@ add_task(
});
info("Ensure address doorhanger not shown");
- await ensureNoDoorhanger;
+ await ensureNoDoorhanger();
ok(true, "Address doorhanger is not shown");
}
diff --git a/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js b/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js
index fde34a0a32..1e7ba523e8 100644
--- a/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js
+++ b/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js
@@ -2,12 +2,57 @@
const URL = BASE_URL + "autocomplete_basic.html";
+const l10n = new Localization(["toolkit/formautofill/formAutofill.ftl"], true);
+
add_setup(async function setup_storage() {
await setStorage(
TEST_ADDRESS_2,
TEST_ADDRESS_3,
TEST_ADDRESS_4,
- TEST_ADDRESS_5
+ TEST_ADDRESS_5,
+ TEST_CREDIT_CARD_1
+ );
+});
+
+add_task(async function test_footer_has_correct_button_text_on_address() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: URL },
+ async function (browser) {
+ const {
+ autoCompletePopup: { richlistbox: itemsBox },
+ } = browser;
+
+ await openPopupOn(browser, "#organization");
+ const footer = itemsBox.querySelector(
+ ".autofill-footer-row.autofill-button"
+ );
+ Assert.equal(
+ footer.innerText,
+ l10n.formatValueSync("autofill-manage-addresses-label")
+ );
+ await closePopup(browser);
+ }
+ );
+});
+
+add_task(async function test_footer_has_correct_button_text_on_credit_card() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: CREDITCARD_FORM_URL },
+ async function (browser) {
+ const {
+ autoCompletePopup: { richlistbox: itemsBox },
+ } = browser;
+
+ await openPopupOn(browser, "#cc-number");
+ const footer = itemsBox.querySelector(
+ ".autofill-footer-row.autofill-button"
+ );
+ Assert.equal(
+ footer.innerText,
+ l10n.formatValueSync("autofill-manage-payment-methods-label")
+ );
+ await closePopup(browser);
+ }
);
});
diff --git a/browser/extensions/formautofill/test/browser/browser_autofill_sandboxed_iframe.js b/browser/extensions/formautofill/test/browser/browser_autofill_sandboxed_iframe.js
new file mode 100644
index 0000000000..2963a06941
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/browser_autofill_sandboxed_iframe.js
@@ -0,0 +1,31 @@
+"use strict";
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["extensions.formautofill.addresses.capture.enabled", true],
+ ["extensions.formautofill.addresses.supported", "on"],
+ ],
+ });
+ await setStorage(TEST_ADDRESS_2, TEST_ADDRESS_3);
+});
+
+add_task(async function test_autocomplete_in_sandboxed_iframe() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: FORM_IFRAME_SANDBOXED_URL },
+ async browser => {
+ const iframeBC = browser.browsingContext.children[0];
+ await openPopupOnSubframe(browser, iframeBC, "#street-address");
+ await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, iframeBC);
+ await BrowserTestUtils.synthesizeKey("VK_RETURN", {}, iframeBC);
+ await waitForAutofill(
+ iframeBC,
+ "#street-address",
+ TEST_ADDRESS_2["street-address"]
+ );
+ Assert.ok(true, "autocomplete works in sandboxed iframe");
+ }
+ );
+
+ await removeAllRecords();
+});
diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser.toml b/browser/extensions/formautofill/test/browser/creditCard/browser.toml
index 710cdbafb4..580ce936d4 100644
--- a/browser/extensions/formautofill/test/browser/creditCard/browser.toml
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser.toml
@@ -17,66 +17,80 @@ support-files = [
]
["browser_anti_clickjacking.js"]
-skip-if = ["!debug && os == 'mac'"] # perma-fail see Bug 1600059
+skip-if = [
+ "apple_catalina && !debug", # perma-fail see Bug 1600059
+ "apple_silicon && !debug", # perma-fail see Bug 1600059
+]
["browser_creditCard_capture_form_removal.js"]
+["browser_creditCard_capture_multiple_cc_number.js"]
+skip-if = [
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
+]
+
["browser_creditCard_capture_page_navigation.js"]
["browser_creditCard_doorhanger_action.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_display.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_fields.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_iframe.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_logo.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_not_shown.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_doorhanger_sync.js"]
skip-if = [
- "!debug && os == 'mac'", # perma-fail see Bug 1655601
- "os == 'win' && ccov", # Bug 1655600
+ "apple_catalina && !debug", # perma-fail see Bug 1655601
+ "apple_silicon && !debug", # perma-fail see Bug 1655601
+ "win11_2009 && ccov", # Bug 1655600
]
["browser_creditCard_dropdown_layout.js"]
-skip-if = [
- "os == 'mac'",
- "os == 'linux'",
- "os == 'win'",
-]
+skip-if = ["true"]
["browser_creditCard_fill_cancel_login.js"]
skip-if = [
- "!debug && os == 'mac'",
- "os == 'linux'",
- "os == 'win'",
+ "apple_catalina && !debug",
+ "os == 'linux' && os_version == '18.04'",
+ "win10_2009",
+ "win11_2009",
]
["browser_creditCard_heuristics.js"]
@@ -100,22 +114,10 @@ skip-if = [
]
["browser_editCreditCardDialog.js"]
-skip-if = [
- "os == 'mac'", # perma-fail see Bug 1600059
- "os == 'linux'", # perma-fail see Bug 1600059
- "os == 'win'", # perma-fail see Bug 1600059
-]
+skip-if = ["true"] # perma-fail see Bug 1600059
["browser_insecure_form.js"]
-skip-if = [
- "os == 'mac'", # bug 1456284
- "os == 'linux'", # bug 1456284
- "os == 'win'", # bug 1456284
-]
+skip-if = ["true"] # perma-fail see Bug 1456284
["browser_manageCreditCardsDialog.js"]
-skip-if = [
- "os == 'mac'",
- "os == 'linux'",
- "os == 'win'",
-]
+skip-if = ["true"]
diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_form_removal.js b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_form_removal.js
index a6c76aa675..3617062fad 100644
--- a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_form_removal.js
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_form_removal.js
@@ -113,7 +113,7 @@ add_task(async function test_credit_card_not_captured_without_prior_fetch() {
});
info("Ensure that credit card doorhanger is not shown");
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
}
);
});
diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_multiple_cc_number.js b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_multiple_cc_number.js
new file mode 100644
index 0000000000..5668e88e74
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_capture_multiple_cc_number.js
@@ -0,0 +1,102 @@
+"use strict";
+
+const TESTCASES = [
+ {
+ description: "Trigger credit card saving using multiple cc-number fields",
+ document: `<form id="form">
+ <input id="cc-name" autocomplete="cc-name">
+ <input id="cc-number1" autocomplete="cc-number" maxlength="4">
+ <input id="cc-number2" autocomplete="cc-number" maxlength="4">
+ <input id="cc-number3" autocomplete="cc-number" maxlength="4">
+ <input id="cc-number4" autocomplete="cc-number" maxlength="4">
+ <input id="cc-exp-month" autocomplete="cc-exp-month">
+ <input id="cc-exp-year" autocomplete="cc-exp-year">
+ <input id="submit" type="submit">
+ </form>`,
+ targetElementId: "cc-number1",
+ formValue: {
+ "#cc-name": "John Doe",
+ "#cc-number1": "3714",
+ "#cc-number2": "4963",
+ "#cc-number3": "5398",
+ "#cc-number4": "431",
+ "#cc-exp-month": 12,
+ "#cc-exp-year": 2000,
+ },
+ expected: [
+ {
+ "cc-name": "John Doe",
+ "cc-number": "371449635398431",
+ "cc-exp-month": 12,
+ "cc-exp-year": 2000,
+ "cc-type": "amex",
+ },
+ ],
+ },
+];
+
+async function expectSavedCreditCards(expectedCreditCards) {
+ const creditcards = await getCreditCards();
+ is(
+ creditcards.length,
+ expectedCreditCards.length,
+ `${creditcards.length} credit card in the storage`
+ );
+
+ for (let i = 0; i < expectedCreditCards.length; i++) {
+ for (const [key, value] of Object.entries(expectedCreditCards[i])) {
+ if (key == "cc-number") {
+ creditcards[i]["cc-number"] = await OSKeyStore.decrypt(
+ creditcards[i]["cc-number-encrypted"]
+ );
+ }
+ is(creditcards[i][key] ?? "", value, `field ${key} should be equal`);
+ }
+ }
+ return creditcards;
+}
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["extensions.formautofill.creditCards.supported", "on"],
+ ["extensions.formautofill.creditCards.enabled", true],
+ ],
+ });
+});
+
+add_task(async function test_capture_multiple_cc_number() {
+ if (!OSKeyStoreTestUtils.canTestOSKeyStoreLogin()) {
+ todo(
+ OSKeyStoreTestUtils.canTestOSKeyStoreLogin(),
+ "Cannot test OS key store login on official builds."
+ );
+ return;
+ }
+
+ for (const TEST of TESTCASES) {
+ info(`Test ${TEST.description}`);
+
+ let onChanged = waitForStorageChangedEvents("add");
+ await BrowserTestUtils.withNewTab(EMPTY_URL, async function (browser) {
+ await SpecialPowers.spawn(browser, [TEST.document], doc => {
+ content.document.body.innerHTML = doc;
+ });
+
+ await SimpleTest.promiseFocus(browser);
+
+ const onPopupShown = waitForPopupShown();
+ await focusUpdateSubmitForm(browser, {
+ focusSelector: `#${TEST.targetElementId}`,
+ newValues: TEST.formValue,
+ });
+
+ await onPopupShown;
+ await clickDoorhangerButton(MAIN_BUTTON, 0);
+ });
+ await onChanged;
+
+ await expectSavedCreditCards(TEST.expected);
+ await removeAllRecords();
+ }
+});
diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_not_shown.js b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_not_shown.js
index f0752e0c22..0056b83727 100644
--- a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_not_shown.js
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_not_shown.js
@@ -86,7 +86,7 @@ add_task(async function test_save_doorhanger_not_shown() {
newValues: TEST.formValue,
});
- await ensureNoDoorhanger(browser);
+ await ensureNoDoorhanger();
});
}
});
diff --git a/browser/extensions/formautofill/test/browser/head.js b/browser/extensions/formautofill/test/browser/head.js
index 7a58b8a202..8de8488f1f 100644
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -45,6 +45,8 @@ const ADDRESS_FORM_WITH_PAGE_NAVIGATION_BUTTONS =
"https://example.org" +
HTTP_TEST_PATH +
"address/capture_address_on_page_navigation.html";
+const FORM_IFRAME_SANDBOXED_URL =
+ "https://example.org" + HTTP_TEST_PATH + "autocomplete_iframe_sandboxed.html";
const CREDITCARD_FORM_URL =
"https://example.org" +
HTTP_TEST_PATH +
@@ -253,7 +255,7 @@ async function ensureNoAutocompletePopup(browser) {
ok(!items.length, "Should not find autocomplete items");
}
-async function ensureNoDoorhanger(browser) {
+async function ensureNoDoorhanger() {
await new Promise(resolve =>
setTimeout(resolve, TIMEOUT_ENSURE_DOORHANGER_NOT_SHOWN)
);
@@ -316,7 +318,7 @@ async function waitForAutofill(target, selector, value) {
* @returns {Promise} resolves when the sub dialog is loaded
*/
function waitForSubDialogLoad(win, dialogUrl) {
- return new Promise((resolve, reject) => {
+ return new Promise(resolve => {
win.gSubDialog._dialogStack.addEventListener(
"dialogopen",
async function dialogopen(evt) {
@@ -395,6 +397,14 @@ async function focusUpdateSubmitForm(target, args, submit = true) {
element = form.querySelector(selector);
if (content.HTMLInputElement.isInstance(element)) {
element.setUserInput(value);
+ } else if (
+ content.HTMLSelectElement.isInstance(element) &&
+ Array.isArray(value)
+ ) {
+ element.multiple = true;
+ [...element.options].forEach(option => {
+ option.selected = value.includes(option.value);
+ });
} else {
element.value = value;
}
diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser.toml b/browser/extensions/formautofill/test/browser/heuristics/browser.toml
index e7bbfa0283..2d0916e917 100644
--- a/browser/extensions/formautofill/test/browser/heuristics/browser.toml
+++ b/browser/extensions/formautofill/test/browser/heuristics/browser.toml
@@ -20,8 +20,6 @@ skip-if = ["apple_silicon && !debug"]
["browser_fr_fields.js"]
-["browser_ignore_unfocusable_fields.js"]
-
["browser_label_rules.js"]
["browser_multiple_section.js"]
@@ -37,3 +35,5 @@ skip-if = ["apple_silicon && !debug"]
["browser_section_validation_address.js"]
["browser_sections_by_name.js"]
+
+["browser_sections_with_invisible_fields.js"]
diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_ignore_unfocusable_fields.js b/browser/extensions/formautofill/test/browser/heuristics/browser_ignore_unfocusable_fields.js
deleted file mode 100644
index 56f53a1e76..0000000000
--- a/browser/extensions/formautofill/test/browser/heuristics/browser_ignore_unfocusable_fields.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/* global add_heuristic_tests */
-
-"use strict";
-
-add_heuristic_tests([
- {
- description: "All visual fields are considered focusable.",
-
- fixtureData: `
- <html>
- <body>
- <form>
- <input type="text" id="name" autocomplete="name" />
- <input type="text" id="tel" autocomplete="tel" />
- <input type="text" id="email" autocomplete="email"/>
- <select id="country" autocomplete="country">
- <option value="United States">United States</option>
- </select>
- <input type="text" id="postal-code" autocomplete="postal-code"/>
- <input type="text" id="address-line1" autocomplete="address-line1" />
- <div>
- <input type="text" id="address-line2" autocomplete="address-line2" />
- </div>
- </form>
- </form>
- </body>
- </html>
- `,
- expectedResult: [
- {
- default: {
- reason: "autocomplete",
- },
- fields: [
- { fieldName: "name" },
- { fieldName: "tel" },
- { fieldName: "email" },
- { fieldName: "country" },
- { fieldName: "postal-code" },
- { fieldName: "address-line1" },
- { fieldName: "address-line2" },
- ],
- },
- ],
- },
- {
- // ignore opacity (see Bug 1835852),
- description:
- "Invisible fields with style.opacity=0 set are considered focusable.",
-
- fixtureData: `
- <html>
- <body>
- <form>
- <input type="text" id="name" autocomplete="name" style="opacity:0" />
- <input type="text" id="tel" autocomplete="tel" />
- <input type="text" id="email" autocomplete="email" style="opacity:0"/>
- <select id="country" autocomplete="country">
- <option value="United States">United States</option>
- </select>
- <input type="text" id="postal-code" autocomplete="postal-code" />
- <input type="text" id="address-line1" autocomplete="address-line1" />
- <div>
- <input type="text" id="address-line2" autocomplete="address-line2" />
- </div>
- </form>
- </form>
- </body>
- </html>
- `,
- expectedResult: [
- {
- default: {
- reason: "autocomplete",
- },
- fields: [
- { fieldName: "name" },
- { fieldName: "tel" },
- { fieldName: "email" },
- { fieldName: "country" },
- { fieldName: "postal-code" },
- { fieldName: "address-line1" },
- { fieldName: "address-line2" },
- ],
- },
- ],
- },
- {
- description:
- "Some fields are considered unfocusable due to their invisibility.",
-
- fixtureData: `
- <html>
- <body>
- <form>
- <input type="text" id="name" autocomplete="name" />
- <input type="text" id="tel" autocomplete="tel" />
- <input type="text" id="email" autocomplete="email" />
- <input type="text" id="country" autocomplete="country" />
- <input type="text" id="postal-code" autocomplete="postal-code" hidden />
- <input type="text" id="address-line1" autocomplete="address-line1" style="display:none" />
- <div style="visibility: hidden">
- <input type="text" id="address-line2" autocomplete="address-line2" />
- </div>
- </form>
- </body>
- </html>
- `,
- expectedResult: [
- {
- default: {
- reason: "autocomplete",
- },
- fields: [
- { fieldName: "name" },
- { fieldName: "tel" },
- { fieldName: "email" },
- { fieldName: "country" },
- ],
- },
- ],
- },
- {
- description: `Disabled field and field with tabindex="-1" is considered unfocusable`,
-
- fixtureData: `
- <html>
- <body>
- <form>
- <input type="text" id="name" autocomplete="name" />
- <input type="text" id="tel" autocomplete="tel" />
- <input type="text" id="email" autocomplete="email" />
- <input type="text" id="country" autocomplete="country" disabled/>
- <input type="text" id="postal-code" autocomplete="postal-code" tabindex="-1"/>
- <input type="text" id="address-line1" autocomplete="address-line1" />
- <input type="text" id="address-line2" autocomplete="address-line2" />
- </form>
- </body>
- </html>
- `,
- expectedResult: [
- {
- default: {
- reason: "autocomplete",
- },
- fields: [
- { fieldName: "name" },
- { fieldName: "tel" },
- { fieldName: "email" },
- { fieldName: "address-line1" },
- { fieldName: "address-line2" },
- ],
- },
- ],
- },
-]);
diff --git a/browser/extensions/formautofill/test/browser/heuristics/browser_sections_with_invisible_fields.js b/browser/extensions/formautofill/test/browser/heuristics/browser_sections_with_invisible_fields.js
new file mode 100644
index 0000000000..f775d7e5fb
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/heuristics/browser_sections_with_invisible_fields.js
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/* global add_heuristic_tests */
+
+"use strict";
+
+add_heuristic_tests([
+ {
+ description: `Create a new section when the section already has a field with the same field name`,
+ fixtureData: `
+ <html><body>
+ <input type="text" autocomplete="cc-number"/>
+ <input type="text" autocomplete="cc-name"/>
+ <input type="text" autocomplete="cc-exp"/>
+ <input type="text" autocomplete="cc-exp"/>
+ </body></html>
+ `,
+ expectedResult: [
+ {
+ default: {
+ reason: "autocomplete",
+ },
+ fields: [
+ { fieldName: "cc-number" },
+ { fieldName: "cc-name" },
+ { fieldName: "cc-exp" },
+ ],
+ },
+ {
+ fields: [{ fieldName: "cc-exp", reason: "autocomplete" }],
+ },
+ ],
+ },
+ {
+ description: `Do not create a new section for an invisible field`,
+ fixtureData: `
+ <html><body>
+ <input type="text" autocomplete="cc-number"/>
+ <input type="text" autocomplete="cc-name"/>
+ <input type="text" autocomplete="cc-exp"/>
+ <input type="text" autocomplete="cc-exp" style="display:none"/>
+ </body></html>
+ `,
+ expectedResult: [
+ {
+ default: {
+ reason: "autocomplete",
+ },
+ fields: [
+ { fieldName: "cc-number" },
+ { fieldName: "cc-name" },
+ { fieldName: "cc-exp" },
+ { fieldName: "cc-exp" },
+ ],
+ },
+ ],
+ },
+ {
+ description: `Do not create a new section when the field with the same field name is an invisible field`,
+ fixtureData: `
+ <html><body>
+ <input type="text" autocomplete="cc-number""/>
+ <input type="text" autocomplete="cc-name"/>
+ <input type="text" autocomplete="cc-exp" style="display:none"/>
+ <input type="text" autocomplete="cc-exp"/>
+ </body></html>
+ `,
+ expectedResult: [
+ {
+ default: {
+ reason: "autocomplete",
+ },
+ fields: [
+ { fieldName: "cc-number" },
+ { fieldName: "cc-name" },
+ { fieldName: "cc-exp" },
+ { fieldName: "cc-exp" },
+ ],
+ },
+ ],
+ },
+ {
+ description: `Do not create a new section for an invisible field (match field is not adjacent)`,
+ fixtureData: `
+ <html><body>
+ <input type="text" autocomplete="cc-number"/>
+ <input type="text" autocomplete="cc-name"/>
+ <input type="text" autocomplete="cc-exp"/>
+ <input type="text" autocomplete="cc-number" style="display:none"/>
+ </body></html>
+ `,
+ expectedResult: [
+ {
+ default: {
+ reason: "autocomplete",
+ },
+ fields: [
+ { fieldName: "cc-number" },
+ { fieldName: "cc-name" },
+ { fieldName: "cc-exp" },
+ { fieldName: "cc-number" },
+ ],
+ },
+ ],
+ },
+ {
+ description: `Do not create a new section when the field with the same field name is an invisible field (match field is not adjacent)`,
+ fixtureData: `
+ <html><body>
+ <input type="text" autocomplete="cc-number" style="display:none"/>
+ <input type="text" autocomplete="cc-name"/>
+ <input type="text" autocomplete="cc-exp"/>
+ <input type="text" autocomplete="cc-number"/>
+ </body></html>
+ `,
+ expectedResult: [
+ {
+ default: {
+ reason: "autocomplete",
+ },
+ fields: [
+ { fieldName: "cc-number" },
+ { fieldName: "cc-name" },
+ { fieldName: "cc-exp" },
+ { fieldName: "cc-number" },
+ ],
+ },
+ ],
+ },
+]);
diff --git a/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Euronics.js b/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Euronics.js
index cd9757bd35..947757ed17 100644
--- a/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Euronics.js
+++ b/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Euronics.js
@@ -16,6 +16,8 @@ add_heuristic_tests(
//{ fieldName: "cc-cvc" },
{ fieldName: "cc-exp-month" },
{ fieldName: "cc-exp-year" },
+ { fieldName: "cc-number", reason: "regex-heuristic" }, // invisible
+ { fieldName: "cc-number", reason: "regex-heuristic" }, // invisible
],
},
{
diff --git a/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js b/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js
index 46e5ecef3c..34a1953157 100644
--- a/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js
+++ b/browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js
@@ -35,9 +35,16 @@ add_heuristic_tests(
reason: "autocomplete",
},
fields: [
+ { fieldName: "cc-exp-month" },
+ { fieldName: "cc-exp-year" },
{ fieldName: "cc-number", reason: "fathom" },
- { fieldName: "cc-exp-month", reason: "regex-heuristic" },
- { fieldName: "cc-exp-year", reason: "regex-heuristic" },
+ ],
+ },
+ {
+ invalid: true,
+ fields: [
+ { fieldName: "cc-exp-month", reason: "regex-heuristic" }, // invisible
+ { fieldName: "cc-exp-year", reason: "regex-heuristic" }, // invisible
],
},
],
diff --git a/browser/extensions/formautofill/test/fixtures/autocomplete_iframe_sandboxed.html b/browser/extensions/formautofill/test/fixtures/autocomplete_iframe_sandboxed.html
new file mode 100644
index 0000000000..bdad6d8f76
--- /dev/null
+++ b/browser/extensions/formautofill/test/fixtures/autocomplete_iframe_sandboxed.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Form Autofill With Remote IFrame Demo Page</title>
+</head>
+<body>
+ <iframe src="https://test1.example.com:443/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html" sandbox width="400" height="400">
+ </iframe>
+</body>
+</html>
diff --git a/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html b/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html
index 3d8049f053..a1a3322c4e 100644
--- a/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html
+++ b/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html
@@ -69,7 +69,6 @@ async function checkIsFormCleared(patch = {}) {
const expectedValue = patch[elem.id] || "";
checkFieldValue(elem, expectedValue);
await checkFieldHighlighted(elem, false);
- await checkFieldPreview(elem, "");
}
}
diff --git a/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html b/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html
index 4fc989a36e..6ebef3bba1 100644
--- a/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html
+++ b/browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html
@@ -54,7 +54,6 @@ async function checkIsFormCleared(patch = {}) {
const expectedValue = patch[elem.id] || "";
checkFieldValue(elem, expectedValue);
await checkFieldHighlighted(elem, false);
- await checkFieldPreview(elem, "");
}
}
diff --git a/browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html b/browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html
index 6b0d7a522c..a6d0572ac6 100644
--- a/browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html
+++ b/browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html
@@ -72,9 +72,7 @@ async function checkMultipleCCNumberFormStyle(profile, isPreviewing = true) {
} else {
fillableValue = profile[element.id];
}
- let previewValue = (isPreviewing && fillableValue) || "";
await checkFieldHighlighted(element, !!fillableValue);
- await checkFieldPreview(element, previewValue);
}
}
diff --git a/browser/extensions/formautofill/test/mochitest/formautofill_common.js b/browser/extensions/formautofill/test/mochitest/formautofill_common.js
index 6dbfa7c918..6cdf9ca86b 100644
--- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js
@@ -104,27 +104,6 @@ async function checkFieldHighlighted(elem, expectedValue) {
is(isHighlightApplied, expectedValue, `Checking #${elem.id} highlight style`);
}
-async function checkFieldPreview(elem, expectedValue) {
- is(
- SpecialPowers.wrap(elem).previewValue,
- expectedValue,
- `Checking #${elem.id} previewValue`
- );
- let isTextColorApplied;
- await SimpleTest.promiseWaitForCondition(function checkPreview() {
- const computedStyle = window.getComputedStyle(elem);
- const actualColor = computedStyle.getPropertyValue("color");
- if (elem.disabled) {
- isTextColorApplied = actualColor !== defaultDisabledTextColor;
- } else {
- isTextColorApplied = actualColor !== defaultTextColor;
- }
- return isTextColorApplied === !!expectedValue;
- }, `Checking #${elem.id} preview style`);
-
- is(isTextColorApplied, !!expectedValue, `Checking #${elem.id} preview style`);
-}
-
async function checkFormFieldsStyle(profile, isPreviewing = true) {
const elems = document.querySelectorAll("input, select");
@@ -143,7 +122,6 @@ async function checkFormFieldsStyle(profile, isPreviewing = true) {
(isPreviewing && fillableValue?.toString().replaceAll("*", "•")) || "";
}
await checkFieldHighlighted(elem, !!fillableValue);
- await checkFieldPreview(elem, previewValue);
}
}
diff --git a/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js b/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
index c133e535f5..97e62657d3 100644
--- a/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
+++ b/browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js
@@ -129,11 +129,11 @@ var ParentUtils = {
},
async operateAddress(type, msgData) {
- await this._operateRecord(ADDRESSES_COLLECTION_NAME, ...arguments);
+ await this._operateRecord(ADDRESSES_COLLECTION_NAME, type, msgData);
},
async operateCreditCard(type, msgData) {
- await this._operateRecord(CREDITCARDS_COLLECTION_NAME, ...arguments);
+ await this._operateRecord(CREDITCARDS_COLLECTION_NAME, type, msgData);
},
async cleanUpAddresses() {
@@ -145,11 +145,7 @@ var ParentUtils = {
return;
}
- await this.operateAddress(
- "remove",
- { guids },
- "FormAutofillTest:AddressesCleanedUp"
- );
+ await this.operateAddress("remove", { guids });
},
async cleanUpCreditCards() {
@@ -164,11 +160,7 @@ var ParentUtils = {
return;
}
- await this.operateCreditCard(
- "remove",
- { guids },
- "FormAutofillTest:CreditCardsCleanedUp"
- );
+ await this.operateCreditCard("remove", { guids });
},
setup() {
@@ -268,7 +260,7 @@ addMessageListener("FormAutofillTest:CheckAddresses", msg => {
return ParentUtils.checkAddresses(msg);
});
-addMessageListener("FormAutofillTest:CleanUpAddresses", msg => {
+addMessageListener("FormAutofillTest:CleanUpAddresses", _msg => {
return ParentUtils.cleanUpAddresses();
});
@@ -284,23 +276,21 @@ addMessageListener("FormAutofillTest:CheckCreditCards", msg => {
return ParentUtils.checkCreditCards(msg);
});
-addMessageListener("FormAutofillTest:CleanUpCreditCards", msg => {
+addMessageListener("FormAutofillTest:CleanUpCreditCards", _msg => {
return ParentUtils.cleanUpCreditCards();
});
-addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", msg => {
+addMessageListener("FormAutofillTest:CanTestOSKeyStoreLogin", _msg => {
return { canTest: OSKeyStoreTestUtils.canTestOSKeyStoreLogin() };
});
-addMessageListener("FormAutofillTest:OSKeyStoreLogin", async msg => {
- await OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login);
-});
+addMessageListener("FormAutofillTest:OSKeyStoreLogin", msg =>
+ OSKeyStoreTestUtils.waitForOSKeyStoreLogin(msg.login)
+);
-addMessageListener("setup", async () => {
- ParentUtils.setup();
-});
+addMessageListener("setup", async _msg => ParentUtils.setup());
-addMessageListener("cleanup", async () => {
+addMessageListener("cleanup", async _msg => {
destroyed = true;
await ParentUtils.cleanup();
});
diff --git a/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html
index 54efc83359..ab3c08e89a 100644
--- a/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html
+++ b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html
@@ -47,9 +47,8 @@ add_task(async function check_switch_autofill_form_popup() {
checkMenuEntries(
[
`{"primary":"+13453453456","secondary":"123 Sesame Street."}`,
- `{"primary":"","secondary":"","categories":["organization","address","tel","name"],"focusedCategory":"tel"}`,
],
- false
+ true
);
await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)");
@@ -75,9 +74,8 @@ add_task(async function check_switch_autofill_form_popup_back() {
checkMenuEntries(
[
`{"primary":"+13453453456","secondary":"123 Sesame Street."}`,
- `{"primary":"","secondary":"","categories":["organization","address","tel","name"],"focusedCategory":"tel"}`,
],
- false
+ true
);
await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)");
diff --git a/browser/extensions/formautofill/test/mochitest/test_form_changes.html b/browser/extensions/formautofill/test/mochitest/test_form_changes.html
index 2eace91a53..1bfc655328 100644
--- a/browser/extensions/formautofill/test/mochitest/test_form_changes.html
+++ b/browser/extensions/formautofill/test/mochitest/test_form_changes.html
@@ -77,8 +77,7 @@ async function checkFormChangeHappened(formId) {
// Click on an autofilled field would show an autocomplete popup with "clear form" entry
checkMenuEntries([
JSON.stringify({primary: "", secondary: ""}), // Clear Autofill Form
- JSON.stringify({primary: "", secondary: ""}) // FormAutofill Preferemce
- ], false);
+ ], true);
// This is for checking the changes of element removed and added then.
document.querySelector(`#${formId} input[name=address-level2]`).remove();
diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js
index 2448c7efff..efb9a65c19 100644
--- a/browser/extensions/formautofill/test/unit/head.js
+++ b/browser/extensions/formautofill/test/unit/head.js
@@ -71,24 +71,6 @@ region-name-tw = Taiwan
L10nRegistry.getInstance().registerSources([mockSource]);
}
-/**
- * Mock the return value of Services.focus.elementIsFocusable
- * since a field's focusability can't be tested in a unit test.
- */
-(function ignoreAFieldsFocusability() {
- let stub = sinon.stub(Services, "focus").get(() => {
- return {
- elementIsFocusable() {
- return true;
- },
- };
- });
-
- registerCleanupFunction(() => {
- stub.restore();
- });
-})();
-
do_get_profile();
const EXTENSION_ID = "formautofill@mozilla.org";
diff --git a/browser/extensions/formautofill/test/unit/test_autofillFormFields.js b/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
index 49ffb0083a..be6b142195 100644
--- a/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
+++ b/browser/extensions/formautofill/test/unit/test_autofillFormFields.js
@@ -423,6 +423,39 @@ const TESTCASES = [
},
{
description:
+ "Form with hidden input and visible input that share the same autocomplete attribute",
+ document: `<form>
+ <input id="hidden-cc" autocomplete="cc-number" hidden>
+ <input id="hidden-cc-2" autocomplete="cc-number" style="display:none">
+ <input id="visible-cc" autocomplete="cc-number">
+ <input id="hidden-name" autocomplete="cc-name" hidden>
+ <input id="hidden-name-2" autocomplete="cc-name" style="display:none">
+ <input id="visible-name" autocomplete="cc-name">
+ <input id="cc-exp-month" autocomplete="cc-exp-month">
+ <input id="cc-exp-year" autocomplete="cc-exp-year">
+ </form>`,
+ focusedInputId: "visible-cc",
+ profileData: {
+ guid: "123",
+ "cc-number": "4111111111111111",
+ "cc-name": "test name",
+ "cc-exp-month": 6,
+ "cc-exp-year": 25,
+ },
+ expectedResult: {
+ guid: "123",
+ "visible-cc": "4111111111111111",
+ "visible-name": "test name",
+ "cc-exp-month": "06",
+ "cc-exp-year": "25",
+ "hidden-cc": "4111111111111111",
+ "hidden-cc-2": "4111111111111111",
+ "hidden-name": "test name",
+ "hidden-name-2": "test name",
+ },
+ },
+ {
+ description:
"Fill credit card fields in a form where the value property is being used as a placeholder for cardholder name",
document: `<form>
<input id="cc-number" autocomplete="cc-number">
@@ -862,7 +895,7 @@ function do_test(testcases, testFn) {
// Replace the internal decrypt method with OSKeyStore API,
// but don't pass the reauth parameter to avoid triggering
// reauth login dialog in these tests.
- let decryptHelper = async (cipherText, reauth) => {
+ let decryptHelper = async (cipherText, _reauth) => {
return OSKeyStore.decrypt(cipherText, false);
};
handler.collectFormFields();
diff --git a/browser/extensions/formautofill/test/unit/test_getFormInputDetails.js b/browser/extensions/formautofill/test/unit/test_getFormInputDetails.js
index 18bd18b74a..cfcae8935d 100644
--- a/browser/extensions/formautofill/test/unit/test_getFormInputDetails.js
+++ b/browser/extensions/formautofill/test/unit/test_getFormInputDetails.js
@@ -1,11 +1,8 @@
"use strict";
-var FormAutofillContent;
-add_task(async function () {
- ({ FormAutofillContent } = ChromeUtils.importESModule(
- "resource://autofill/FormAutofillContent.sys.mjs"
- ));
-});
+const { FormStateManager } = ChromeUtils.importESModule(
+ "resource://gre/modules/shared/FormStateManager.sys.mjs"
+);
const TESTCASES = [
{
@@ -168,15 +165,16 @@ TESTCASES.forEach(testcase => {
for (let i in testcase.targetInput) {
let input = doc.getElementById(testcase.targetInput[i]);
- FormAutofillContent.identifyAutofillFields(input);
- FormAutofillContent.updateActiveInput(input);
+ const fsm = new FormStateManager();
+ fsm.updateActiveInput(input);
+ fsm.identifyAutofillFields(input);
// Put the input element reference to `element` to make sure the result of
// `activeFieldDetail` contains the same input element.
testcase.expectedResult[i].input.elementWeakRef = new WeakRef(input);
inputDetailAssertion(
- FormAutofillContent.activeFieldDetail,
+ fsm.activeFieldDetail,
testcase.expectedResult[i].input
);
@@ -193,7 +191,7 @@ TESTCASES.forEach(testcase => {
formDetail.elementWeakRef = new WeakRef(doc.querySelector(queryString));
}
- FormAutofillContent.activeFormDetails.forEach((detail, index) => {
+ fsm.activeFormDetails.forEach((detail, index) => {
inputDetailAssertion(detail, formDetails[index]);
});
}
diff --git a/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js b/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js
index 72960fcaf2..a170ff59a9 100644
--- a/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js
+++ b/browser/extensions/formautofill/test/unit/test_markAsAutofillField.js
@@ -1,5 +1,9 @@
"use strict";
+const { FormStateManager } = ChromeUtils.importESModule(
+ "resource://gre/modules/shared/FormStateManager.sys.mjs"
+);
+
const TESTCASES = [
{
description: "Form containing 8 fields with autocomplete attribute.",
@@ -158,19 +162,6 @@ const TESTCASES = [
},
];
-let markedFieldId = [];
-
-var FormAutofillContent;
-add_setup(async () => {
- ({ FormAutofillContent } = ChromeUtils.importESModule(
- "resource://autofill/FormAutofillContent.sys.mjs"
- ));
-
- FormAutofillContent._markAsAutofillField = function (field) {
- markedFieldId.push(field.id);
- };
-});
-
TESTCASES.forEach(testcase => {
add_task(async function () {
info("Starting testcase: " + testcase.description);
@@ -179,17 +170,20 @@ TESTCASES.forEach(testcase => {
testcase.prefs.forEach(pref => SetPref(pref[0], pref[1]));
}
- markedFieldId = [];
-
- let doc = MockDocument.createTestDocument(
+ const doc = MockDocument.createTestDocument(
"http://localhost:8080/test/",
testcase.document
);
- let element = doc.getElementById(testcase.targetElementId);
- FormAutofillContent.identifyAutofillFields(element);
+ const element = doc.getElementById(testcase.targetElementId);
+
+ const fsm = new FormStateManager();
+ fsm.updateActiveInput(element);
+
+ const identifiedFields = fsm.identifyAutofillFields(element);
+ const identifiedFieldIds = identifiedFields.map(x => x.element.id);
Assert.deepEqual(
- markedFieldId,
+ identifiedFieldIds,
testcase.expectedResult,
"Check the fields were marked correctly."
);
diff --git a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
deleted file mode 100644
index 484112cc86..0000000000
--- a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
+++ /dev/null
@@ -1,712 +0,0 @@
-"use strict";
-
-var FormAutofillContent;
-add_setup(async () => {
- ({ FormAutofillContent } = ChromeUtils.importESModule(
- "resource://autofill/FormAutofillContent.sys.mjs"
- ));
-});
-
-const DEFAULT_TEST_DOC = `<form id="form1">
- <input id="street-addr" autocomplete="street-address">
- <select id="address-level1" autocomplete="address-level1">
- <option value=""></option>
- <option value="AL">Alabama</option>
- <option value="AK">Alaska</option>
- <option value="AP">Armed Forces Pacific</option>
-
- <option value="ca">california</option>
- <option value="AR">US-Arkansas</option>
- <option value="US-CA">California</option>
- <option value="CA">California</option>
- <option value="US-AZ">US_Arizona</option>
- <option value="Ariz">Arizonac</option>
- </select>
- <input id="city" autocomplete="address-level2">
- <input id="country" autocomplete="country">
- <input id="email" autocomplete="email">
- <input id="tel" autocomplete="tel">
- <input id="cc-name" autocomplete="cc-name">
- <input id="cc-number" autocomplete="cc-number">
- <input id="cc-exp-month" autocomplete="cc-exp-month">
- <input id="cc-exp-year" autocomplete="cc-exp-year">
- <select id="cc-type">
- <option value="">Select</option>
- <option value="visa">Visa</option>
- <option value="mastercard">Master Card</option>
- <option value="amex">American Express</option>
- </select>
- <input id="submit" type="submit">
- </form>`;
-const TARGET_ELEMENT_ID = "street-addr";
-
-const TESTCASES = [
- {
- description:
- "Should not trigger address saving if the number of fields is less than 3",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "street-addr": "331 E. Evelyn Avenue",
- tel: "1-650-903-0800",
- },
- expectedResult: {
- formSubmission: false,
- },
- },
- {
- description: "Should not trigger credit card saving if number is empty",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "cc-name": "John Doe",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- },
- expectedResult: {
- formSubmission: false,
- },
- },
- {
- description:
- "Should not trigger credit card saving if there is more than one cc-number field but less than four fields",
- document: `<form id="form1">
- <input id="cc-type" autocomplete="cc-type">
- <input id="cc-name" autocomplete="cc-name">
- <input id="cc-number1" maxlength="4">
- <input id="cc-number2" maxlength="4">
- <input id="cc-number3" maxlength="4">
- <input id="cc-exp-month" autocomplete="cc-exp-month">
- <input id="cc-exp-year" autocomplete="cc-exp-year">
- <input id="submit" type="submit">
- </form>
- `,
- targetElementId: "cc-name",
- formValue: {
- "cc-name": "John Doe",
- "cc-number1": "3714",
- "cc-number2": "4963",
- "cc-number3": "5398",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "amex",
- },
- expectedResult: {
- formSubmission: false,
- },
- },
- {
- description: "Trigger address saving",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- tel: "1-650-903-0800",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- email: "",
- tel: "1-650-903-0800",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Trigger credit card saving",
- document: DEFAULT_TEST_DOC,
- targetElementId: "cc-type",
- formValue: {
- "cc-name": "John Doe",
- "cc-number": "5105105105105100",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "amex",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [],
- creditCard: [
- {
- guid: null,
- record: {
- "cc-name": "John Doe",
- "cc-number": "5105105105105100",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "amex",
- },
- untouchedFields: [],
- },
- ],
- },
- },
- },
- {
- description: "Trigger credit card saving using multiple cc-number fields",
- document: `<form id="form1">
- <input id="cc-type" autocomplete="cc-type">
- <input id="cc-name" autocomplete="cc-name">
- <input id="cc-number1" maxlength="4">
- <input id="cc-number2" maxlength="4">
- <input id="cc-number3" maxlength="4">
- <input id="cc-number4" maxlength="4">
- <input id="cc-exp-month" autocomplete="cc-exp-month">
- <input id="cc-exp-year" autocomplete="cc-exp-year">
- <input id="submit" type="submit">
- </form>`,
- targetElementId: "cc-type",
- formValue: {
- "cc-name": "John Doe",
- "cc-number1": "3714",
- "cc-number2": "4963",
- "cc-number3": "5398",
- "cc-number4": "431",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "amex",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [],
- creditCard: [
- {
- guid: null,
- record: {
- "cc-name": "John Doe",
- "cc-number": "371449635398431",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "amex",
- },
- untouchedFields: [],
- },
- ],
- },
- },
- },
- {
- description: "Trigger address and credit card saving",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- tel: "1-650-903-0800",
- "cc-name": "John Doe",
- "cc-number": "5105105105105100",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "visa",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- email: "",
- tel: "1-650-903-0800",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [
- {
- guid: null,
- record: {
- "cc-name": "John Doe",
- "cc-number": "5105105105105100",
- "cc-exp-month": 12,
- "cc-exp-year": 2000,
- "cc-type": "visa",
- },
- untouchedFields: [],
- },
- ],
- },
- },
- },
- {
- description: "Profile saved with trimmed string",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "street-addr": "331 E. Evelyn Avenue ",
- country: "US",
- tel: " 1-650-903-0800",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- email: "",
- tel: "1-650-903-0800",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Eliminate the field that is empty after trimmed",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- email: " ",
- tel: "1-650-903-0800",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- email: "",
- tel: "1-650-903-0800",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Save state with regular select option",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "CA",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "CA",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Save state with lowercase value",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "ca",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "CA",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Save state with a country code prefixed to the label",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "AR",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "AR",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Save state with a country code prefixed to the value",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "US-CA",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "CA",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description:
- "Save state with a country code prefixed to the value and label",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "US-AZ",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "AZ",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description:
- "Should save select label instead when failed to abbreviate the value",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "Ariz",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "address-level1": "Arizonac",
- "address-level2": "",
- "street-address": "331 E. Evelyn Avenue",
- country: "US",
- email: "",
- tel: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Shouldn't save select with multiple selections",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": ["AL", "AK", "AP"],
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- tel: "1-650-903-0800",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- tel: "1-650-903-0800",
- email: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
- {
- description: "Shouldn't save select with empty value",
- document: DEFAULT_TEST_DOC,
- targetElementId: TARGET_ELEMENT_ID,
- formValue: {
- "address-level1": "",
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- tel: "1-650-903-0800",
- },
- expectedResult: {
- formSubmission: true,
- records: {
- address: [
- {
- guid: null,
- record: {
- "street-address": "331 E. Evelyn Avenue",
- "address-level1": "",
- "address-level2": "",
- country: "US",
- tel: "1-650-903-0800",
- email: "",
- },
- untouchedFields: [],
- },
- ],
- creditCard: [],
- },
- },
- },
-];
-
-add_task(async function handle_invalid_form() {
- info("Starting testcase: Test an invalid form element");
- let doc = MockDocument.createTestDocument(
- "http://localhost:8080/test",
- DEFAULT_TEST_DOC
- );
- let fakeForm = doc.createElement("form");
- sinon.spy(FormAutofillContent, "_onFormSubmit");
-
- FormAutofillContent.formSubmitted(fakeForm, undefined, null);
- Assert.equal(FormAutofillContent._onFormSubmit.called, false);
- FormAutofillContent._onFormSubmit.restore();
-});
-
-add_task(async function autofill_disabled() {
- let doc = MockDocument.createTestDocument(
- "http://localhost:8080/test",
- DEFAULT_TEST_DOC
- );
- let form = doc.getElementById("form1");
- form.reset();
-
- let testcase = {
- "street-addr": "331 E. Evelyn Avenue",
- country: "US",
- tel: "+16509030800",
- "cc-number": "1111222233334444",
- };
- for (let key in testcase) {
- let input = doc.getElementById(key);
- input.value = testcase[key];
- }
-
- let element = doc.getElementById(TARGET_ELEMENT_ID);
- FormAutofillContent.identifyAutofillFields(element);
-
- sinon.stub(FormAutofillContent, "_onFormSubmit");
-
- // "_onFormSubmit" shouldn't be called if both "addresses" and "creditCards"
- // are disabled.
- Services.prefs.setBoolPref(
- "extensions.formautofill.addresses.enabled",
- false
- );
- Services.prefs.setBoolPref(
- "extensions.formautofill.creditCards.enabled",
- false
- );
- FormAutofillContent.formSubmitted(form, undefined, null);
- Assert.equal(FormAutofillContent._onFormSubmit.called, false);
- FormAutofillContent._onFormSubmit.resetHistory();
-
- // "_onFormSubmit" should be called as usual.
- Services.prefs.clearUserPref("extensions.formautofill.addresses.enabled");
- Services.prefs.clearUserPref("extensions.formautofill.creditCards.enabled");
-
- Services.prefs.setBoolPref(
- "extensions.formautofill.creditCards.enabled",
- true
- );
-
- FormAutofillContent.formSubmitted(form, undefined, null);
- Assert.equal(FormAutofillContent._onFormSubmit.called, true);
- Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
- Assert.notDeepEqual(
- FormAutofillContent._onFormSubmit.args[0][0].creditCard,
- []
- );
- FormAutofillContent._onFormSubmit.resetHistory();
-
- // "address" should be empty if "addresses" pref is disabled.
- Services.prefs.setBoolPref(
- "extensions.formautofill.addresses.enabled",
- false
- );
- FormAutofillContent.formSubmitted(form, undefined, null);
- Assert.equal(FormAutofillContent._onFormSubmit.called, true);
- Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
- Assert.notDeepEqual(
- FormAutofillContent._onFormSubmit.args[0][0].creditCard,
- []
- );
- FormAutofillContent._onFormSubmit.resetHistory();
- Services.prefs.clearUserPref("extensions.formautofill.addresses.enabled");
-
- // "creditCard" should be empty if "creditCards" pref is disabled.
- Services.prefs.setBoolPref(
- "extensions.formautofill.creditCards.enabled",
- false
- );
- FormAutofillContent.formSubmitted(form, undefined, null);
- Assert.deepEqual(FormAutofillContent._onFormSubmit.called, true);
- Assert.notDeepEqual(FormAutofillContent._onFormSubmit.args[0][0].address, []);
- Assert.deepEqual(FormAutofillContent._onFormSubmit.args[0][0].creditCard, []);
- FormAutofillContent._onFormSubmit.resetHistory();
- Services.prefs.clearUserPref("extensions.formautofill.creditCards.enabled");
-
- FormAutofillContent._onFormSubmit.restore();
-});
-
-TESTCASES.forEach(testcase => {
- add_task(async function check_records_saving_is_called_correctly() {
- info("Starting testcase: " + testcase.description);
-
- Services.prefs.setBoolPref(
- "extensions.formautofill.creditCards.enabled",
- true
- );
- let doc = MockDocument.createTestDocument(
- "http://localhost:8080/test/",
- testcase.document
- );
- let form = doc.getElementById("form1");
- form.reset();
- for (let key in testcase.formValue) {
- let input = doc.getElementById(key);
- let value = testcase.formValue[key];
- if (ChromeUtils.getClassName(input) === "HTMLSelectElement" && value) {
- input.multiple = Array.isArray(value);
- [...input.options].forEach(option => {
- option.selected = value.includes(option.value);
- });
- } else {
- input.value = testcase.formValue[key];
- }
- }
- sinon.stub(FormAutofillContent, "_onFormSubmit");
-
- let element = doc.getElementById(testcase.targetElementId);
- FormAutofillContent.identifyAutofillFields(element);
- FormAutofillContent.formSubmitted(form, undefined, null);
-
- Assert.equal(
- FormAutofillContent._onFormSubmit.called,
- testcase.expectedResult.formSubmission,
- "Check expected onFormSubmit.called"
- );
- if (FormAutofillContent._onFormSubmit.called) {
- for (let ccRecord of FormAutofillContent._onFormSubmit.args[0][0]
- .creditCard) {
- delete ccRecord.flowId;
- }
- for (let addrRecord of FormAutofillContent._onFormSubmit.args[0][0]
- .address) {
- delete addrRecord.flowId;
- }
-
- Assert.deepEqual(
- FormAutofillContent._onFormSubmit.args[0][0],
- testcase.expectedResult.records
- );
- }
- FormAutofillContent._onFormSubmit.restore();
- Services.prefs.clearUserPref("extensions.formautofill.creditCards.enabled");
- });
-});
diff --git a/browser/extensions/formautofill/test/unit/test_phoneNumber.js b/browser/extensions/formautofill/test/unit/test_phoneNumber.js
index 1c1d67e166..133e54f6d7 100644
--- a/browser/extensions/formautofill/test/unit/test_phoneNumber.js
+++ b/browser/extensions/formautofill/test/unit/test_phoneNumber.js
@@ -7,10 +7,10 @@
var PhoneNumber, PhoneNumberNormalizer;
add_setup(async () => {
({ PhoneNumber } = ChromeUtils.importESModule(
- "resource://autofill/phonenumberutils/PhoneNumber.sys.mjs"
+ "resource://gre/modules/shared/PhoneNumber.sys.mjs"
));
({ PhoneNumberNormalizer } = ChromeUtils.importESModule(
- "resource://autofill/phonenumberutils/PhoneNumberNormalizer.sys.mjs"
+ "resource://gre/modules/shared/PhoneNumberNormalizer.sys.mjs"
));
});
diff --git a/browser/extensions/formautofill/test/unit/test_previewFormFields.js b/browser/extensions/formautofill/test/unit/test_previewFormFields.js
index 1b1a01860d..b5ca7e5dfc 100644
--- a/browser/extensions/formautofill/test/unit/test_previewFormFields.js
+++ b/browser/extensions/formautofill/test/unit/test_previewFormFields.js
@@ -152,7 +152,7 @@ function run_tests(testcases) {
// Replace the internal decrypt method with OSKeyStore API,
// but don't pass the reauth parameter to avoid triggering
// reauth login dialog in these tests.
- let decryptHelper = async (cipherText, reauth) => {
+ let decryptHelper = async (cipherText, _reauth) => {
return OSKeyStore.decrypt(cipherText, false);
};
handler.collectFormFields();
diff --git a/browser/extensions/formautofill/test/unit/test_storage_tombstones.js b/browser/extensions/formautofill/test/unit/test_storage_tombstones.js
index 584dac8043..d0365d8f11 100644
--- a/browser/extensions/formautofill/test/unit/test_storage_tombstones.js
+++ b/browser/extensions/formautofill/test/unit/test_storage_tombstones.js
@@ -109,7 +109,7 @@ add_storage_task(async function test_simple_synctombstone(storage, record) {
do_check_tombstone_record(tombstoneInDisk);
});
-add_storage_task(async function test_add_tombstone(storage, record) {
+add_storage_task(async function test_add_tombstone(storage, _record) {
info("Should be able to add a new tombstone");
let guid = await storage.add({ guid: "test-guid-1", deleted: true });
@@ -136,7 +136,7 @@ add_storage_task(async function test_add_tombstone(storage, record) {
add_storage_task(async function test_add_tombstone_without_guid(
storage,
- record
+ _record
) {
info("Should not be able to add a new tombstone without specifying the guid");
await Assert.rejects(storage.add({ deleted: true }), /Record missing GUID/);
@@ -164,7 +164,7 @@ add_storage_task(async function test_add_tombstone_existing_guid(
);
});
-add_storage_task(async function test_update_tombstone(storage, record) {
+add_storage_task(async function test_update_tombstone(storage, _record) {
info("Updating a tombstone should fail");
let guid = await storage.add({ guid: "test-guid-1", deleted: true });
await Assert.rejects(storage.update(guid, {}), /No matching record./);
@@ -172,7 +172,7 @@ add_storage_task(async function test_update_tombstone(storage, record) {
add_storage_task(async function test_remove_existing_tombstone(
storage,
- record
+ _record
) {
info("Removing a record that's already a tombstone should be a no-op");
let guid = await storage.add({
diff --git a/browser/extensions/formautofill/test/unit/xpcshell.toml b/browser/extensions/formautofill/test/unit/xpcshell.toml
index f63ac60e58..dccc27fa63 100644
--- a/browser/extensions/formautofill/test/unit/xpcshell.toml
+++ b/browser/extensions/formautofill/test/unit/xpcshell.toml
@@ -6,6 +6,9 @@ skip-if = [
firefox-appdir = "browser"
head = "head.js"
support-files = ["../fixtures/**"]
+prefs = [
+ "extensions.formautofill.test.ignoreVisibilityCheck=true",
+]
["test_activeStatus.js"]
@@ -98,9 +101,6 @@ skip-if = ["tsan"] # Times out, bug 1612707
["test_nameUtils.js"]
-["test_onFormSubmitted.js"]
-skip-if = ["tsan"] # Times out, bug 1612707
-
["test_parseAddressFormat.js"]
["test_parseStreetAddress.js"]