commit 64caac4600ec633abae2dc160a9464685bc1bcbe
parent f84953d949bb3a5a368fa7cefbb68a93baba3034
Author: Segun Famisa <sfamisa@mozilla.com>
Date: Mon, 8 Dec 2025 10:02:56 +0000
Bug 2002373 - Do not prompt to save an unchanged credit card r=geckoview-reviewers,tcampbell
This patch prevents GeckoView from showing a "save credit card" prompt when a form is submitted with credit card information that already exists and has not been modified.
Differential Revision: https://phabricator.services.mozilla.com/D274910
Diffstat:
2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AutocompleteTest.kt
@@ -32,7 +32,6 @@ import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.GeckoSession
import org.mozilla.geckoview.GeckoSession.PromptDelegate
import org.mozilla.geckoview.GeckoSession.PromptDelegate.AutocompleteRequest
-import org.mozilla.geckoview.TranslationsController
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
@@ -1454,6 +1453,64 @@ class AutocompleteTest : BaseSessionTest() {
}
@Test
+ fun formSubmissionWithUnchangedCreditCardShouldNotTriggerSave() {
+ val ccName = "Jane Doe"
+ val ccNumber = "5555444433331111"
+ val ccExpMonth = "6"
+ val ccExpYear = "2024"
+ val savedCreditCard = CreditCard.Builder()
+ .guid("test-guid-1")
+ .name(ccName)
+ .number(ccNumber)
+ .expirationMonth(ccExpMonth)
+ .expirationYear(ccExpYear)
+ .build()
+
+ val savedCreditCards = arrayOf(savedCreditCard)
+
+ mainSession.loadTestPath(CC_FORM_HTML_PATH)
+ mainSession.waitForPageStop()
+
+ // Setup delegates for fetching data and handling prompts.
+ sessionRule.delegateUntilTestEnd(object : StorageDelegate, PromptDelegate {
+ @AssertCalled
+ override fun onCreditCardFetch(): GeckoResult<Array<CreditCard>> {
+ return GeckoResult.fromValue(savedCreditCards)
+ }
+
+ // These should NOT be called because no information has changed.
+ @AssertCalled(count = 0)
+ override fun onCreditCardSave(creditCard: CreditCard) = Unit
+
+ @AssertCalled(count = 0)
+ override fun onCreditCardSave(
+ session: GeckoSession,
+ request: AutocompleteRequest<CreditCardSaveOption>,
+ ): GeckoResult<PromptDelegate.PromptResponse> {
+ // This block should not be reached. If it is, the test will fail.
+ return GeckoResult.fromValue(request.dismiss())
+ }
+ })
+
+ // Fill in the fields with the same saved data
+ mainSession.evaluateJS("document.querySelector('#name').focus()")
+ mainSession.evaluateJS("document.querySelector('#name').value = '$ccName'")
+ mainSession.evaluateJS("document.querySelector('#name').focus()")
+ mainSession.evaluateJS("document.querySelector('#number').value = '$ccNumber'")
+ mainSession.evaluateJS("document.querySelector('#number').focus()")
+ mainSession.evaluateJS("document.querySelector('#expMonth').value = '$ccExpMonth'")
+ mainSession.evaluateJS("document.querySelector('#expMonth').focus()")
+ mainSession.evaluateJS("document.querySelector('#expYear').value = '$ccExpYear'")
+ mainSession.evaluateJS("document.querySelector('#expYear').focus()")
+
+ // Submit the form
+ mainSession.evaluateJS("document.querySelector('form').requestSubmit()")
+
+ // Wait for the form to submit
+ mainSession.waitForRoundTrip()
+ }
+
+ @Test
fun creditCardUpdateAccept() {
val ccName = "MyCard"
val ccNumber1 = "5105105105105100"
diff --git a/mobile/shared/modules/geckoview/GeckoViewAutocomplete.sys.mjs b/mobile/shared/modules/geckoview/GeckoViewAutocomplete.sys.mjs
@@ -10,6 +10,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
EventDispatcher: "resource://gre/modules/Messaging.sys.mjs",
GeckoViewPrompter: "resource://gre/modules/GeckoViewPrompter.sys.mjs",
AddressRecord: "resource://gre/modules/shared/AddressRecord.sys.mjs",
+ CreditCardRecord: "resource://gre/modules/shared/CreditCardRecord.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "LoginInfo", () =>
@@ -265,7 +266,7 @@ export class CreditCard {
}
toGecko() {
- return {
+ let creditCard = {
version: this.version,
"cc-name": this.name,
"cc-number": this.number,
@@ -274,6 +275,10 @@ export class CreditCard {
"cc-type": this.type,
guid: this.guid,
};
+
+ lazy.CreditCardRecord.computeFields(creditCard);
+
+ return creditCard;
}
}