Bug 1371113 - Part 3: Add mochitest for credit card doorhanger. r=lchang draft
authorsteveck-chung <schung@mozilla.com>
Wed, 23 Aug 2017 19:24:31 +0800
changeset 654077 d4630dd343a87c216c433e60f142fdce095e1213
parent 654076 89dac26cc83cfca34dd456a9f3de82431a4cf085
child 728480 0596b3f080180ebe17e8098487170be6d4ce6c34
push id76480
push userbmo:lchang@mozilla.com
push dateMon, 28 Aug 2017 09:17:13 +0000
reviewerslchang
bugs1371113
milestone57.0a1
Bug 1371113 - Part 3: Add mochitest for credit card doorhanger. r=lchang MozReview-Commit-ID: A8dawwdJrV2
browser/extensions/formautofill/test/browser/browser.ini
browser/extensions/formautofill/test/browser/browser_creditCard_doorhanger.js
browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
browser/extensions/formautofill/test/browser/browser_update_doorhanger.js
browser/extensions/formautofill/test/browser/head.js
--- a/browser/extensions/formautofill/test/browser/browser.ini
+++ b/browser/extensions/formautofill/test/browser/browser.ini
@@ -4,16 +4,17 @@ head = head.js
 support-files =
   ../fixtures/autocomplete_basic.html
   ../fixtures/autocomplete_creditcard_basic.html
 
 [browser_autocomplete_footer.js]
 [browser_autocomplete_marked_back_forward.js]
 [browser_autocomplete_marked_detached_tab.js]
 [browser_check_installed.js]
+[browser_creditCard_doorhanger.js]
 [browser_dropdown_layout.js]
 [browser_editAddressDialog.js]
 [browser_editCreditCardDialog.js]
 [browser_first_time_use_doorhanger.js]
 [browser_insecure_form.js]
 [browser_manageAddressesDialog.js]
 [browser_manageCreditCardsDialog.js]
 [browser_privacyPreferences.js]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/browser/browser_creditCard_doorhanger.js
@@ -0,0 +1,61 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+"use strict";
+
+add_task(async function test_submit_creditCard_cancel_saving() {
+  await BrowserTestUtils.withNewTab({gBrowser, url: CREDITCARD_FORM_URL},
+    async function(browser) {
+      let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
+                                                       "popupshown");
+      await ContentTask.spawn(browser, null, async function() {
+        let form = content.document.getElementById("form");
+        let name = form.querySelector("#cc-name");
+        name.focus();
+        name.setUserInput("User 1");
+
+        let number = form.querySelector("#cc-number");
+        number.setUserInput("1111222233334444");
+
+        // Wait 1000ms before submission to make sure the input value applied
+        await new Promise(resolve => setTimeout(resolve, 1000));
+        form.querySelector("input[type=submit]").click();
+      });
+
+      await promiseShown;
+      await clickDoorhangerButton(SECONDARY_BUTTON);
+    }
+  );
+
+  await sleep(1000);
+  let creditCards = await getCreditCards();
+  is(creditCards.length, 0, "No credit card saved");
+});
+
+add_task(async function test_submit_creditCard_saved() {
+  await BrowserTestUtils.withNewTab({gBrowser, url: CREDITCARD_FORM_URL},
+    async function(browser) {
+      let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
+                                                       "popupshown");
+      await ContentTask.spawn(browser, null, async function() {
+        let form = content.document.getElementById("form");
+        let name = form.querySelector("#cc-name");
+        name.focus();
+        name.setUserInput("User 1");
+
+        let number = form.querySelector("#cc-number");
+        number.setUserInput("1111222233334444");
+
+        // Wait 1000ms before submission to make sure the input value applied
+        await new Promise(resolve => setTimeout(resolve, 1000));
+        form.querySelector("input[type=submit]").click();
+      });
+
+      await promiseShown;
+      await clickDoorhangerButton(MAIN_BUTTON);
+      await TestUtils.topicObserved("formautofill-storage-changed");
+    }
+  );
+
+  let creditCards = await getCreditCards();
+  is(creditCards.length, 1, "Still 1 address in storage");
+  is(creditCards[0]["cc-name"], "User 1", "Verify the name field");
+});
--- a/browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
+++ b/browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js
@@ -27,17 +27,17 @@ add_task(async function test_first_time_
         await new Promise(resolve => setTimeout(resolve, 500));
         form.querySelector("input[type=submit]").click();
       });
 
       await promiseShown;
       let cb = getDoorhangerCheckbox();
       ok(cb.hidden, "Sync checkbox should be hidden");
       // Open the panel via main button
-      await clickDoorhangerButton(MAIN_BUTTON_INDEX);
+      await clickDoorhangerButton(MAIN_BUTTON);
       let tab = await tabPromise;
       ok(tab, "Privacy panel opened");
       await BrowserTestUtils.removeTab(tab);
     }
   );
 
   addresses = await getAddresses();
   is(addresses.length, 1, "Address saved");
@@ -106,17 +106,17 @@ add_task(async function test_first_time_
       is(SpecialPowers.getBoolPref(SYNC_ADDRESSES_PREF), false,
          "addresses sync should be disabled at first");
 
       is(cb.checked, false, "Checkbox state should match addresses sync state");
       cb.click();
       is(SpecialPowers.getBoolPref(SYNC_ADDRESSES_PREF), true,
          "addresses sync should be enabled after checked");
       // Open the panel via main button
-      await clickDoorhangerButton(MAIN_BUTTON_INDEX);
+      await clickDoorhangerButton(MAIN_BUTTON);
       let tab = await tabPromise;
       ok(tab, "Privacy panel opened");
       await BrowserTestUtils.removeTab(tab);
     }
   );
 
   let ftuPref = SpecialPowers.getBoolPref(FTU_PREF);
   is(ftuPref, false, "First time use flag is false");
--- a/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js
+++ b/browser/extensions/formautofill/test/browser/browser_update_doorhanger.js
@@ -21,17 +21,17 @@ add_task(async function test_update_addr
         org.setUserInput("Mozilla");
 
         // Wait 1000ms before submission to make sure the input value applied
         await new Promise(resolve => setTimeout(resolve, 1000));
         form.querySelector("input[type=submit]").click();
       });
 
       await promiseShown;
-      await clickDoorhangerButton(MAIN_BUTTON_INDEX);
+      await clickDoorhangerButton(MAIN_BUTTON);
     }
   );
 
   addresses = await getAddresses();
   is(addresses.length, 1, "Still 1 address in storage");
   is(addresses[0].organization, "Mozilla", "Verify the organization field");
 });
 
@@ -54,17 +54,17 @@ add_task(async function test_create_new_
         tel.setUserInput("+1234567890");
 
         // Wait 1000ms before submission to make sure the input value applied
         await new Promise(resolve => setTimeout(resolve, 1000));
         form.querySelector("input[type=submit]").click();
       });
 
       await promiseShown;
-      await clickDoorhangerButton(SECONDARY_BUTTON_INDEX);
+      await clickDoorhangerButton(SECONDARY_BUTTON);
     }
   );
 
   addresses = await getAddresses();
   is(addresses.length, 2, "2 addresses in storage");
   is(addresses[1].tel, "+1234567890", "Verify the tel field");
 });
 
@@ -87,17 +87,17 @@ add_task(async function test_create_new_
         tel.setUserInput("+16172535702");
 
         // Wait 1000ms before submission to make sure the input value applied
         await new Promise(resolve => setTimeout(resolve, 1000));
         form.querySelector("input[type=submit]").click();
       });
 
       await promiseShown;
-      await clickDoorhangerButton(SECONDARY_BUTTON_INDEX);
+      await clickDoorhangerButton(SECONDARY_BUTTON);
     }
   );
 
   addresses = await getAddresses();
   is(addresses.length, 2, "Still 2 addresses in storage");
 });
 
 add_task(async function test_submit_untouched_fields() {
@@ -123,17 +123,17 @@ add_task(async function test_submit_unto
         tel.value = "12345"; // ".value" won't change the highlight status.
 
         // Wait 1000ms before submission to make sure the input value applied
         await new Promise(resolve => setTimeout(resolve, 1000));
         form.querySelector("input[type=submit]").click();
       });
 
       await promiseShown;
-      await clickDoorhangerButton(MAIN_BUTTON_INDEX);
+      await clickDoorhangerButton(MAIN_BUTTON);
     }
   );
 
   addresses = await getAddresses();
   is(addresses.length, 2, "Still 2 addresses in storage");
   is(addresses[0].organization, "Organization", "organization should change");
   is(addresses[0].tel, "+16172535702", "tel should remain unchanged");
 });
--- a/browser/extensions/formautofill/test/browser/head.js
+++ b/browser/extensions/formautofill/test/browser/head.js
@@ -1,24 +1,26 @@
 /* exported MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL, EDIT_ADDRESS_DIALOG_URL, EDIT_CREDIT_CARD_DIALOG_URL,
             BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5,
-            TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL,
+            TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL, CREDITCARD_FORM_URL,
             FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF, SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF,
             sleep, expectPopupOpen, openPopupOn, expectPopupClose, closePopup, clickDoorhangerButton,
             getAddresses, saveAddress, removeAddresses, saveCreditCard,
             getDisplayedPopupItems, getDoorhangerCheckbox, waitForMasterPasswordDialog */
 
 "use strict";
 
 const MANAGE_ADDRESSES_DIALOG_URL = "chrome://formautofill/content/manageAddresses.xhtml";
 const MANAGE_CREDIT_CARDS_DIALOG_URL = "chrome://formautofill/content/manageCreditCards.xhtml";
 const EDIT_ADDRESS_DIALOG_URL = "chrome://formautofill/content/editAddress.xhtml";
 const EDIT_CREDIT_CARD_DIALOG_URL = "chrome://formautofill/content/editCreditCard.xhtml";
 const BASE_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/";
 const FORM_URL = "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_basic.html";
+const CREDITCARD_FORM_URL =
+  "http://mochi.test:8888/browser/browser/extensions/formautofill/test/browser/autocomplete_creditcard_basic.html";
 const FTU_PREF = "extensions.formautofill.firstTimeUse";
 const ENABLED_AUTOFILL_ADDRESSES_PREF = "extensions.formautofill.addresses.enabled";
 const ENABLED_AUTOFILL_CREDITCARDS_PREF = "extensions.formautofill.creditCards.enabled";
 const SYNC_USERNAME_PREF = "services.sync.username";
 const SYNC_ADDRESSES_PREF = "services.sync.engine.addresses";
 
 const TEST_ADDRESS_1 = {
   "given-name": "John",
@@ -55,17 +57,16 @@ const TEST_ADDRESS_4 = {
 
 const TEST_ADDRESS_5 = {
   tel: "+16172535702",
 };
 
 const TEST_CREDIT_CARD_1 = {
   "cc-name": "John Doe",
   "cc-number": "1234567812345678",
-  // "cc-number-encrypted": "",
   "cc-exp-month": 4,
   "cc-exp-year": 2017,
 };
 
 const TEST_CREDIT_CARD_2 = {
   "cc-name": "Timothy Berners-Lee",
   "cc-number": "1111222233334444",
   "cc-exp-month": 12,
@@ -73,18 +74,19 @@ const TEST_CREDIT_CARD_2 = {
 };
 
 const TEST_CREDIT_CARD_3 = {
   "cc-number": "9999888877776666",
   "cc-exp-month": 1,
   "cc-exp-year": 2000,
 };
 
-const MAIN_BUTTON_INDEX = 0;
-const SECONDARY_BUTTON_INDEX = 1;
+const MAIN_BUTTON = "button";
+const SECONDARY_BUTTON = "secondaryButton";
+const MENU_BUTTON = "menubutton";
 
 function getDisplayedPopupItems(browser, selector = ".autocomplete-richlistitem") {
   const {autoCompletePopup: {richlistbox: itemsBox}} = browser;
   const listItemElems = itemsBox.querySelectorAll(selector);
 
   return [...listItemElems].filter(item => item.getAttribute("collapsed") != "true");
 }
 
@@ -183,35 +185,38 @@ function removeAddresses(guids) {
 function removeCreditCards(guids) {
   Services.cpmm.sendAsyncMessage("FormAutofill:RemoveCreditCards", {guids});
   return TestUtils.topicObserved("formautofill-storage-changed");
 }
 
 /**
  * Clicks the popup notification button and wait for popup hidden.
  *
- * @param {number} buttonIndex Number indicating which button to click.
- *                             See the constants in this file.
+ * @param {string} button The button type in popup notification.
+ * @param {number} index The action's index in menu list.
  */
-async function clickDoorhangerButton(buttonIndex) {
+async function clickDoorhangerButton(button, index) {
   let popuphidden = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
   let notifications = PopupNotifications.panel.childNodes;
   ok(notifications.length > 0, "at least one notification displayed");
   ok(true, notifications.length + " notification(s)");
   let notification = notifications[0];
 
-  if (buttonIndex == MAIN_BUTTON_INDEX) {
-    ok(true, "Triggering main action");
-    EventUtils.synthesizeMouseAtCenter(notification.button, {});
-  } else if (buttonIndex == SECONDARY_BUTTON_INDEX) {
-    ok(true, "Triggering secondary action");
-    EventUtils.synthesizeMouseAtCenter(notification.secondaryButton, {});
-  } else if (notification.childNodes[buttonIndex - 1]) {
-    ok(true, "Triggering secondary action with index " + buttonIndex);
-    EventUtils.synthesizeMouseAtCenter(notification.childNodes[buttonIndex - 1], {});
+  if (button == MAIN_BUTTON || button == SECONDARY_BUTTON) {
+    EventUtils.synthesizeMouseAtCenter(notification[button], {});
+  } else if (button == MENU_BUTTON) {
+    // Click the dropmarker arrow and wait for the menu to show up.
+    let dropdownPromise =
+      BrowserTestUtils.waitForEvent(notification.menupopup, "popupshown");
+    await EventUtils.synthesizeMouseAtCenter(notification.menubutton, {});
+    ok(true, "notification menupopup displayed");
+    await dropdownPromise;
+
+    let actionMenuItem = notification.querySelectorAll("menuitem")[index];
+    await EventUtils.synthesizeMouseAtCenter(actionMenuItem, {});
   }
   await popuphidden;
 }
 
 function getDoorhangerCheckbox() {
   let notifications = PopupNotifications.panel.childNodes;
   ok(notifications.length > 0, "at least one notification displayed");
   ok(true, notifications.length + " notification(s)");