Bug 1658027 - Separate visual interactions on Credit Card Autofill for A/B testing. r=abr
☠☠ backed out by c33697aac4f1 ☠ ☠
authorZibi Braniecki <zbraniecki@mozilla.com>
Sat, 08 Aug 2020 03:36:42 +0000
changeset 544002 9825feb6a05ef73b85130d9ddfa562eaebe02ba1
parent 544001 1fe4d982c2c43170b58c69eac2de5df7ce9ca16a
child 544003 1283143e3d557b54a6262253d6003af733203a14
push id123750
push userzbraniecki@mozilla.com
push dateSat, 08 Aug 2020 03:39:54 +0000
treeherderautoland@9825feb6a05e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersabr
bugs1658027
milestone81.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1658027 - Separate visual interactions on Credit Card Autofill for A/B testing. r=abr Differential Revision: https://phabricator.services.mozilla.com/D86445
browser/app/profile/firefox.js
browser/extensions/formautofill/FormAutofill.jsm
browser/extensions/formautofill/FormAutofillContent.jsm
browser/extensions/formautofill/FormAutofillParent.jsm
browser/extensions/formautofill/FormAutofillPreferences.jsm
browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_telemetry.js
browser/extensions/formautofill/test/browser/creditCard/browser_privacyPreferences.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1844,16 +1844,19 @@ pref("browser.crashReports.unsubmittedCh
 // The truthy values of "extensions.formautofill.available" are "on" and "detect",
 // any other value means autofill isn't available.
 // "detect" means it's enabled if conditions defined in the extension are met.
 pref("extensions.formautofill.available", "detect");
 pref("extensions.formautofill.creditCards.available", true);
 pref("extensions.formautofill.addresses.enabled", true);
 pref("extensions.formautofill.addresses.capture.enabled", false);
 pref("extensions.formautofill.creditCards.enabled", true);
+// Temporary preference to control displaying the UI elements for
+// credit card autofill used for the duration of the A/B test.
+pref("extensions.formautofill.creditCards.hideui", false);
 // Enable the checkbox in sync options for credit card data sync service
 pref("services.sync.engine.creditcards.available", true);
 // Pref for shield/heartbeat to recognize users who have used Credit Card
 // Autofill. The valid values can be:
 // 0: none
 // 1: submitted a manually-filled credit card form (but didn't see the doorhanger
 //    because of a duplicate profile in the storage)
 // 2: saw the doorhanger
--- a/browser/extensions/formautofill/FormAutofill.jsm
+++ b/browser/extensions/formautofill/FormAutofill.jsm
@@ -22,16 +22,18 @@ const CREDITCARDS_USED_STATUS_PREF = "ex
 const ENABLED_AUTOFILL_ADDRESSES_PREF =
   "extensions.formautofill.addresses.enabled";
 const ENABLED_AUTOFILL_ADDRESSES_CAPTURE_PREF =
   "extensions.formautofill.addresses.capture.enabled";
 const ENABLED_AUTOFILL_CREDITCARDS_PREF =
   "extensions.formautofill.creditCards.enabled";
 const ENABLED_AUTOFILL_CREDITCARDS_REAUTH_PREF =
   "extensions.formautofill.reauth.enabled";
+const AUTOFILL_CREDITCARDS_HIDE_UI_PREF =
+  "extensions.formautofill.creditCards.hideui";
 const SUPPORTED_COUNTRIES_PREF = "extensions.formautofill.supportedCountries";
 
 XPCOMUtils.defineLazyPreferenceGetter(
   this,
   "logLevel",
   "extensions.formautofill.loglevel",
   "Warn"
 );
@@ -110,16 +112,21 @@ XPCOMUtils.defineLazyPreferenceGetter(
 );
 XPCOMUtils.defineLazyPreferenceGetter(
   FormAutofill,
   "_isAutofillCreditCardsEnabled",
   ENABLED_AUTOFILL_CREDITCARDS_PREF
 );
 XPCOMUtils.defineLazyPreferenceGetter(
   FormAutofill,
+  "isAutofillCreditCardsHideUI",
+  AUTOFILL_CREDITCARDS_HIDE_UI_PREF
+);
+XPCOMUtils.defineLazyPreferenceGetter(
+  FormAutofill,
   "isAutofillAddressesFirstTimeUse",
   ADDRESSES_FIRST_TIME_USE_PREF
 );
 XPCOMUtils.defineLazyPreferenceGetter(
   FormAutofill,
   "AutofillCreditCardsUsedStatus",
   CREDITCARDS_USED_STATUS_PREF
 );
--- a/browser/extensions/formautofill/FormAutofillContent.jsm
+++ b/browser/extensions/formautofill/FormAutofillContent.jsm
@@ -178,19 +178,23 @@ AutofillProfileAutoCompleteSearch.protot
       activeFieldDetail.fieldName
     );
     const isCreditCardField = FormAutofillUtils.isCreditCardField(
       activeFieldDetail.fieldName
     );
     let isInputAutofilled = activeFieldDetail.state == FIELD_STATES.AUTO_FILLED;
     let allFieldNames = activeSection.allFieldNames;
     let filledRecordGUID = activeSection.filledRecordGUID;
+
+    let creditCardsEnabledAndVisible =
+      FormAutofill.isAutofillCreditCardsEnabled &&
+      !FormAutofill.isAutofillCreditCardsHideUI;
     let searchPermitted = isAddressField
       ? FormAutofill.isAutofillAddressesEnabled
-      : FormAutofill.isAutofillCreditCardsEnabled;
+      : creditCardsEnabledAndVisible;
     let AutocompleteResult = isAddressField ? AddressResult : CreditCardResult;
     let isFormAutofillSearch = true;
     let pendingSearchResult = null;
 
     ProfileAutocomplete.lastProfileAutoCompleteFocusedInput = activeInput;
     // Fallback to form-history if ...
     //   - specified autofill feature is pref off.
     //   - no profile can fill the currently-focused input.
--- a/browser/extensions/formautofill/FormAutofillParent.jsm
+++ b/browser/extensions/formautofill/FormAutofillParent.jsm
@@ -576,16 +576,20 @@ class FormAutofillParent extends JSWindo
           1
         );
       }
     }
     return showDoorhanger;
   }
 
   async _onCreditCardSubmit(creditCard, browser, timeStartedFillingMS) {
+    if (FormAutofill.isAutofillCreditCardsHideUI) {
+      return false;
+    }
+
     // Updates the used status for shield/heartbeat to recognize users who have
     // used Credit Card Autofill.
     let setUsedStatus = status => {
       if (FormAutofill.AutofillCreditCardsUsedStatus < status) {
         Services.prefs.setIntPref(
           FormAutofill.CREDITCARDS_USED_STATUS_PREF,
           status
         );
--- a/browser/extensions/formautofill/FormAutofillPreferences.jsm
+++ b/browser/extensions/formautofill/FormAutofillPreferences.jsm
@@ -171,17 +171,20 @@ FormAutofillPreferences.prototype = {
 
     this.refs = {
       formAutofillFragment,
       formAutofillGroup,
       addressAutofillCheckbox,
       savedAddressesBtn,
     };
 
-    if (FormAutofill.isAutofillCreditCardsAvailable) {
+    if (
+      FormAutofill.isAutofillCreditCardsAvailable &&
+      !FormAutofill.isAutofillCreditCardsHideUI
+    ) {
       let creditCardAutofill = document.createXULElement("hbox");
       let creditCardAutofillCheckboxGroup = document.createXULElement("hbox");
       let creditCardAutofillCheckbox = document.createXULElement("checkbox");
       let creditCardAutofillLearnMore = document.createXULElement("label", {
         is: "text-link",
       });
       let savedCreditCardsBtn = document.createXULElement("button", {
         is: "highlightable-button",
--- a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_telemetry.js
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_telemetry.js
@@ -586,8 +586,97 @@ add_task(async function test_histogram()
     1: 1,
     2: 2,
   });
 
   await removeAllRecords();
 
   assertHistogram(CC_NUM_USES_HISTOGRAM, {});
 });
+
+add_task(async function test_submit_creditCard_new_with_hidden_ui() {
+  const AUTOFILL_CREDITCARDS_HIDE_UI_PREF =
+    "extensions.formautofill.creditCards.hideui";
+
+  Services.telemetry.clearEvents();
+  Services.telemetry.clearScalars();
+  Services.telemetry.getHistogramById(CC_NUM_USES_HISTOGRAM).clear();
+  Services.telemetry.setEventRecordingEnabled("creditcard", true);
+
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      [CREDITCARDS_USED_STATUS_PREF, 0],
+      [AUTOFILL_CREDITCARDS_HIDE_UI_PREF, true],
+    ],
+  });
+
+  await saveCreditCard(TEST_CREDIT_CARD_1);
+
+  await BrowserTestUtils.withNewTab(
+    { gBrowser, url: CREDITCARD_FORM_URL },
+    async function(browser) {
+      await openPopupOn(browser, "form #cc-number").then(
+        () => {
+          return Promise.reject("Popup should not be displayed");
+        },
+        () => {
+          ok(true, "Popup has not been displayed");
+        }
+      );
+
+      await SpecialPowers.spawn(browser, [], async function() {
+        let form = content.document.getElementById("form");
+        let name = form.querySelector("#cc-name");
+
+        name.focus();
+        name.setUserInput("User 1");
+
+        form.querySelector("#cc-number").setUserInput("5038146897157463");
+        form.querySelector("#cc-exp-month").setUserInput("12");
+        form.querySelector("#cc-exp-year").setUserInput("2017");
+        form.querySelector("#cc-type").value = "mastercard";
+
+        // Wait 1000ms before submission to make sure the input value applied
+        await new Promise(resolve => content.setTimeout(resolve, 1000));
+        form.querySelector("input[type=submit]").click();
+      });
+
+      await sleep(1000);
+      is(PopupNotifications.panel.state, "closed", "Doorhanger is hidden");
+    }
+  );
+
+  SpecialPowers.clearUserPref(CREDITCARDS_USED_STATUS_PREF);
+  SpecialPowers.clearUserPref(ENABLED_AUTOFILL_CREDITCARDS_PREF);
+  SpecialPowers.clearUserPref(AUTOFILL_CREDITCARDS_HIDE_UI_PREF);
+
+  assertHistogram(CC_NUM_USES_HISTOGRAM, { 0: 1 });
+
+  let expected_content = [
+    ["creditcard", "detected", "cc_form"],
+    [
+      "creditcard",
+      "submitted",
+      "cc_form",
+      undefined,
+      {
+        fields_not_auto: "3",
+        fields_auto: "5",
+        fields_modified: "5",
+      },
+    ],
+  ];
+  await assertTelemetry(expected_content, []);
+  await removeAllRecords();
+
+  TelemetryTestUtils.assertScalar(
+    TelemetryTestUtils.getProcessScalars("content"),
+    "formautofill.creditCards.detected_sections_count",
+    1,
+    "There should be 1 sections detected."
+  );
+  TelemetryTestUtils.assertScalar(
+    TelemetryTestUtils.getProcessScalars("content"),
+    "formautofill.creditCards.submitted_sections_count",
+    1,
+    "There should be 1 section submitted."
+  );
+});
--- a/browser/extensions/formautofill/test/browser/creditCard/browser_privacyPreferences.js
+++ b/browser/extensions/formautofill/test/browser/creditCard/browser_privacyPreferences.js
@@ -209,16 +209,47 @@ add_task(async function test_creditCardN
           !content.document.querySelector(selectors.creditCardAutofillCheckbox),
           "Autofill credit cards checkbox should not exist"
         );
       });
     }
   );
 });
 
+add_task(async function test_creditCardHiddenUI() {
+  const AUTOFILL_CREDITCARDS_HIDE_UI_PREF =
+    "extensions.formautofill.creditCards.hideui";
+
+  await SpecialPowers.pushPrefEnv({
+    set: [[AUTOFILL_CREDITCARDS_HIDE_UI_PREF, true]],
+  });
+  let finalPrefPaneLoaded = TestUtils.topicObserved(
+    "sync-pane-loaded",
+    () => true
+  );
+  await BrowserTestUtils.withNewTab(
+    { gBrowser, url: PAGE_PRIVACY },
+    async function(browser) {
+      await finalPrefPaneLoaded;
+      await SpecialPowers.spawn(browser, [SELECTORS], selectors => {
+        is(
+          content.document.querySelector(selectors.group).hidden,
+          false,
+          "Form Autofill group should be visible"
+        );
+        ok(
+          !content.document.querySelector(selectors.creditCardAutofillCheckbox),
+          "Autofill credit cards checkbox should not exist"
+        );
+      });
+    }
+  );
+  SpecialPowers.clearUserPref(AUTOFILL_CREDITCARDS_HIDE_UI_PREF);
+});
+
 add_task(async function test_reauth() {
   await SpecialPowers.pushPrefEnv({
     set: [[AUTOFILL_CREDITCARDS_AVAILABLE_PREF, true]],
   });
   let { OSKeyStore } = ChromeUtils.import(
     "resource://gre/modules/OSKeyStore.jsm"
   );