From 4670e461427d8e48d11ecdf575e97852c89bd861 Mon Sep 17 00:00:00 2001 From: Helena Date: Thu, 22 May 2025 11:38:50 +0000 Subject: [PATCH] Bug 1919571 - The password manager dropdown is being triggered for the Email field instead of the address autofill one. r=dimi Differential Revision: https://phabricator.services.mozilla.com/D247546 --- .../formautofill/test/browser/browser.toml | 3 + .../test/browser/browser_email_dropdown.js | 59 +++++++++++++++++++ ...autocomplete_multiple_emails_checkout.html | 36 +++++++++++ toolkit/actors/AutoCompleteChild.sys.mjs | 21 ++++++- 4 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 browser/extensions/formautofill/test/browser/browser_email_dropdown.js create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_multiple_emails_checkout.html diff --git a/browser/extensions/formautofill/test/browser/browser.toml b/browser/extensions/formautofill/test/browser/browser.toml index 3b8b62aa5ce9..0c82d44cfe47 100644 --- a/browser/extensions/formautofill/test/browser/browser.toml +++ b/browser/extensions/formautofill/test/browser/browser.toml @@ -5,6 +5,7 @@ support-files = [ "../fixtures/autocomplete_basic.html", "../fixtures/autocomplete_iframe.html", "../fixtures/autocomplete_iframe_sandboxed.html", + "../fixtures/autocomplete_multiple_emails_checkout.html", "../fixtures/autocomplete_simple_basic.html", "../fixtures/dynamic_forms.html", "../fixtures/dynamic_formless_fields_updated_due_to_node_mutations.html", @@ -83,6 +84,8 @@ skip-if = [ "os == 'linux'" , # Bug 1788900 ] +["browser_email_dropdown.js"] + ["browser_fathom_cc.js"] ["browser_fillclear_events.js"] diff --git a/browser/extensions/formautofill/test/browser/browser_email_dropdown.js b/browser/extensions/formautofill/test/browser/browser_email_dropdown.js new file mode 100644 index 000000000000..21aebb57d247 --- /dev/null +++ b/browser/extensions/formautofill/test/browser/browser_email_dropdown.js @@ -0,0 +1,59 @@ +"use strict"; + +const PAGE_URL = + "https://example.org/browser/browser/extensions/formautofill/test/fixtures/autocomplete_multiple_emails_checkout.html"; + +// This testcase is to ensure that if a field gets recoginised by both +// login manager and formautofill providers, that if an address is saved, +// that the formautofill popup gets priority over the login manager. + +add_task(async function test_email_field_is_address_dropdown() { + await SpecialPowers.pushPrefEnv({ + set: [["signon.rememberSignons", true]], + }); + // If an address is saved, show the formautofill dropdown. + await setStorage(TEST_ADDRESS_1); + await BrowserTestUtils.withNewTab( + { gBrowser, url: PAGE_URL }, + async function (browser) { + const focusInput = "#email"; + // We need to initialize and identify fields on a field that doesn't trigger + // a login autocomplete on focus, otherwise the popup could appear too early. + await focusAndWaitForFieldsIdentified(browser, "#given-name"); + await openPopupOn(browser, focusInput); + const item = getDisplayedPopupItems(browser)[2]; + + is( + item.getAttribute("ac-value"), + "Manage addresses", + "Address popup should show a valid email suggestion" + ); + + await closePopup(browser); + } + ); +}); + +add_task( + async function test_email_field_shows_login_dropdown_when_no_saved_address() { + // However, if no addresses are saved, show the login manager. + await removeAllRecords(); + await BrowserTestUtils.withNewTab( + { gBrowser, url: PAGE_URL }, + async function (browser) { + const focusInput = "#email"; + await focusAndWaitForFieldsIdentified(browser, "#given-name"); + await openPopupOn(browser, focusInput); + const item = getDisplayedPopupItems(browser)[0]; + + is( + item.getAttribute("ac-value"), + "Manage Passwords", + "Login Manager should be shown" + ); + + await closePopup(browser); + } + ); + } +); diff --git a/browser/extensions/formautofill/test/fixtures/autocomplete_multiple_emails_checkout.html b/browser/extensions/formautofill/test/fixtures/autocomplete_multiple_emails_checkout.html new file mode 100644 index 000000000000..0037ee8a437c --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/autocomplete_multiple_emails_checkout.html @@ -0,0 +1,36 @@ + + + + + Form Autofill Address - Two Emails at checkout + + +

Form Autofill Address Demo Page

+ +
+

+

+ +

+

+

+

+

+

+

+

+ +

+

+

+ +

+

+ +

+ + +

+
+ + diff --git a/toolkit/actors/AutoCompleteChild.sys.mjs b/toolkit/actors/AutoCompleteChild.sys.mjs index 80101a4e89f4..1878a5f6a1e2 100644 --- a/toolkit/actors/AutoCompleteChild.sys.mjs +++ b/toolkit/actors/AutoCompleteChild.sys.mjs @@ -280,11 +280,26 @@ export class AutoCompleteChild extends JSWindowActorChild { } } + // If one provider has a non-null result, use the non-results. However, if + // no providers have a non-null result, use the empty results instead. + // This is because an autocomplete provider might want to show an + // autocomplete popup when there is no search result. For example, + // for FormHistory, insecure warning for LoginManager. + let foundResults = []; + let emptyResults = []; + for (const provider of providers) { - // Search result could be empty. However, an autocomplete provider might - // want to show an autocomplete popup when there is no search result. For example, - // for FormHistory, insecure warning for LoginManager. const searchResult = result.find(r => r.actorName == provider.actorName); + if (searchResult) { + foundResults.push([provider, searchResult]); + } else { + emptyResults.push([provider, undefined]); + } + } + + for (const [provider, searchResult] of foundResults.length + ? foundResults + : emptyResults) { const acResult = provider.searchResultToAutoCompleteResult( searchString, input,