Bug 1462779 - Show the billing address page during on-boarding if requestShipping is false and there are no saved addresses. r?MattN draft
authorprathiksha <prathikshaprasadsuman@gmail.com>
Fri, 18 May 2018 16:44:25 -0700
changeset 801830 6e17ec2b767241be3e45bda7e996704bfc90e6ae
parent 800874 f01bb6245db1ea2a87e5360104a4110571265137
child 801831 eab9cfb3cc618e9d349b4f5c4ad03d6eb99774a0
push id111751
push userbmo:prathikshaprasadsuman@gmail.com
push dateWed, 30 May 2018 21:03:28 +0000
reviewersMattN
bugs1462779
milestone62.0a1
Bug 1462779 - Show the billing address page during on-boarding if requestShipping is false and there are no saved addresses. r?MattN MozReview-Commit-ID: E7KM4cIielG
browser/components/payments/res/paymentRequest.js
browser/components/payments/res/paymentRequest.xhtml
browser/components/payments/test/browser/browser_payments_onboarding_wizard.js
--- a/browser/components/payments/res/paymentRequest.js
+++ b/browser/components/payments/res/paymentRequest.js
@@ -111,40 +111,52 @@ var paymentRequest = {
     // Handle getting called before the DOM is ready.
     log.debug("onShowPaymentRequest:", detail);
     await this.domReadyPromise;
 
     log.debug("onShowPaymentRequest: domReadyPromise resolved");
     log.debug("onShowPaymentRequest, isPrivate?", detail.isPrivate);
 
     let paymentDialog = document.querySelector("payment-dialog");
+    let hasSavedAddresses = Object.keys(detail.savedAddresses).length != 0;
+    let hasSavedCards = Object.keys(detail.savedBasicCards).length != 0;
+    let shippingRequested = detail.request.paymentOptions.requestShipping;
     let state = {
       request: detail.request,
       savedAddresses: detail.savedAddresses,
       savedBasicCards: detail.savedBasicCards,
       isPrivate: detail.isPrivate,
       page: {
         id: "payment-summary",
       },
     };
 
     // Onboarding wizard flow.
-    if (Object.keys(detail.savedAddresses).length == 0) {
+    if (!hasSavedAddresses && (shippingRequested || !hasSavedCards)) {
       state.page = {
         id: "address-page",
         onboardingWizard: true,
       };
 
       state["address-page"] = {
         selectedStateKey: "selectedShippingAddress",
         addressFields: null,
         guid: null,
-        title: paymentDialog.dataset.shippingAddressTitleAdd,
       };
-    } else if (Object.keys(detail.savedBasicCards).length == 0) {
+
+      if (shippingRequested) {
+        Object.assign(state["address-page"], {
+          title: paymentDialog.dataset.shippingAddressTitleAdd,
+        });
+      } else {
+        Object.assign(state["address-page"], {
+          title: paymentDialog.dataset.billingAddressTitleAdd,
+        });
+      }
+    } else if (!hasSavedCards) {
       state.page = {
         id: "basic-card-page",
         onboardingWizard: true,
       };
     }
 
     paymentDialog.setStateFromParent(state);
   },
--- a/browser/components/payments/res/paymentRequest.xhtml
+++ b/browser/components/payments/res/paymentRequest.xhtml
@@ -184,12 +184,13 @@
           hidden="hidden"
           height="400"></iframe>
   <payment-dialog data-shipping-address-title-add="&shippingAddress.addPage.title;"
                   data-shipping-address-title-edit="&shippingAddress.editPage.title;"
                   data-delivery-address-title-add="&deliveryAddress.addPage.title;"
                   data-delivery-address-title-edit="&deliveryAddress.editPage.title;"
                   data-pickup-address-title-add="&pickupAddress.addPage.title;"
                   data-pickup-address-title-edit="&pickupAddress.editPage.title;"
+                  data-billing-address-title-add="&billingAddress.addPage.title;"
                   data-payer-title-add="&payer.addPage.title;"
                   data-payer-title-edit="&payer.editPage.title;"></payment-dialog>
 </body>
 </html>
--- a/browser/components/payments/test/browser/browser_payments_onboarding_wizard.js
+++ b/browser/components/payments/test/browser/browser_payments_onboarding_wizard.js
@@ -2,16 +2,23 @@
 
 async function addAddress() {
   let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
                                           (subject, data) => data == "add");
   formAutofillStorage.addresses.add(PTU.Addresses.TimBL);
   await onChanged;
 }
 
+async function addBasicCard() {
+  let onChanged = TestUtils.topicObserved("formautofill-storage-changed",
+                                          (subject, data) => data == "add");
+  formAutofillStorage.creditCards.add(PTU.BasicCards.JohnDoe);
+  await onChanged;
+}
+
 add_task(async function test_onboarding_wizard_without_saved_addresses_and_saved_cards() {
   await BrowserTestUtils.withNewTab({
     gBrowser,
     url: BLANK_PAGE_URL,
   }, async browser => {
     cleanupFormAutofillStorage();
 
     info("Opening the payment dialog");
@@ -23,35 +30,36 @@ add_task(async function test_onboarding_
         merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
       });
 
     await spawnPaymentDialogTask(frame, async function() {
       let {
         PaymentTestUtils: PTU,
       } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
 
-      info("Checking if the address page has been rendered");
-      let addressSaveButton = content.document.querySelector("address-form .save-button");
-      ok(content.isVisible(addressSaveButton), "Address save button is rendered");
-
       await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "address-page" &&
                state["address-page"].selectedStateKey == "selectedShippingAddress";
       }, "Address page is shown first during on-boarding if there are no saved addresses");
 
+      info("Checking if the address page has been rendered");
+      let addressSaveButton = content.document.querySelector("address-form .save-button");
+      ok(content.isVisible(addressSaveButton), "Address save button is rendered");
+
       info("Check if the total header is visible on the address page during on-boarding");
       let header = content.document.querySelector("header");
       ok(content.isVisible(header),
          "Total Header is visible on the address page during on-boarding");
       ok(header.textContent, "Total Header contains text");
 
       info("Check if the page title is visible on the address page");
       let addressPageTitle = content.document.querySelector("address-form h1");
       ok(content.isVisible(addressPageTitle), "Address page title is visible");
-      ok(addressPageTitle.textContent, "Address page title contains text");
+      is(addressPageTitle.textContent, "Add Shipping Address",
+         "Address page title is correctly shown");
 
       let addressCancelButton = content.document.querySelector("address-form .cancel-button");
       ok(content.isVisible(addressCancelButton),
          "The cancel button on the address page is visible");
 
       for (let [key, val] of Object.entries(PTU.Addresses.TimBL2)) {
         let field = content.document.getElementById(key);
         if (!field) {
@@ -61,37 +69,37 @@ add_task(async function test_onboarding_
         ok(!field.disabled, `Field #${key} shouldn't be disabled`);
       }
       content.document.querySelector("address-form .save-button").click();
 
       await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "basic-card-page";
       }, "Basic card page is shown after the address page during on boarding");
 
+      let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
+      ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
+
       let basicCardTitle = content.document.querySelector("basic-card-form h1");
       ok(content.isVisible(basicCardTitle), "Basic card page title is visible");
-      ok(basicCardTitle.textContent, "Basic card page title contains text");
-
-      let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
-      ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
+      is(basicCardTitle.textContent, "Add Credit Card", "Basic card page title is correctly shown");
 
       for (let [key, val] of Object.entries(PTU.BasicCards.JohnDoe)) {
         let field = content.document.getElementById(key);
         field.value = val;
         ok(!field.disabled, `Field #${key} shouldn't be disabled`);
       }
       content.document.querySelector("basic-card-form .save-button").click();
 
       await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "payment-summary";
-      }, "payment-summary is now visible");
+      }, "Payment summary page is shown after the basic card page during on boarding");
 
       let cancelButton = content.document.querySelector("#cancel");
       ok(content.isVisible(cancelButton),
-         "Payment summary page is shown after the basic card page during on boarding");
+         "Payment summary page is rendered");
     });
 
     info("Closing the payment dialog");
     spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
 
     await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
   });
 });
@@ -112,24 +120,24 @@ add_task(async function test_onboarding_
         merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
       });
 
     await spawnPaymentDialogTask(frame, async function() {
       let {
         PaymentTestUtils: PTU,
       } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
 
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "payment-summary";
+      }, "Payment summary page is shown first when there are saved addresses and saved cards");
+
       info("Checking if the payment summary page is now visible");
       let cancelButton = content.document.querySelector("#cancel");
       ok(content.isVisible(cancelButton), "Payment summary page is rendered");
 
-      await PTU.DialogContentUtils.waitForState(content, (state) => {
-        return state.page.id == "payment-summary";
-      }, "Payment summary page is shown first when there are saved addresses and saved cards");
-
       info("Check if the total header is visible on payments summary page");
       let header = content.document.querySelector("header");
       ok(content.isVisible(header),
          "Total Header is visible on the payment summary page");
       ok(header.textContent, "Total Header contains text");
 
       // Click on the Add/Edit buttons in the payment summary page to check if
       // the total header is visible on the address page and the basic card page.
@@ -187,24 +195,24 @@ add_task(async function test_onboarding_
         merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
       });
 
     await spawnPaymentDialogTask(frame, async function() {
       let {
         PaymentTestUtils: PTU,
       } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
 
-      info("Checking if the basic card has been rendered");
-      let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
-      ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
-
       await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "basic-card-page";
       }, "Basic card page is shown first if there are saved addresses during on boarding");
 
+      info("Checking if the basic card page has been rendered");
+      let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
+      ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
+
       info("Check if the total header is visible on the basic card page during on-boarding");
       let header = content.document.querySelector("header");
       ok(content.isVisible(header),
          "Total Header is visible on the basic card page during on-boarding");
       ok(header.textContent, "Total Header contains text");
 
       let cardCancelButton = content.document.querySelector("basic-card-form .cancel-button");
       ok(content.isVisible(cardCancelButton),
@@ -216,8 +224,171 @@ add_task(async function test_onboarding_
       content.document.querySelector("basic-card-form .cancel-button").click();
     });
 
     await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
 
     cleanupFormAutofillStorage();
   });
 });
+
+add_task(async function test_onboarding_wizard_without_saved_address_with_saved_cards() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: BLANK_PAGE_URL,
+  }, async browser => {
+    cleanupFormAutofillStorage();
+    addBasicCard();
+
+    info("Opening the payment dialog");
+    let {win, frame} =
+      await setupPaymentDialog(browser, {
+        methodData: [PTU.MethodData.basicCard],
+        details: PTU.Details.total60USD,
+        options: PTU.Options.requestShippingOption,
+        merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
+      });
+
+    await spawnPaymentDialogTask(frame, async function() {
+      let {
+        PaymentTestUtils: PTU,
+      } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "address-page";
+      }, "Address page is shown first if there are saved addresses during on boarding");
+
+      info("Checking if the address page has been rendered");
+      let addressSaveButton = content.document.querySelector("address-form .save-button");
+      ok(content.isVisible(addressSaveButton), "Address save button is rendered");
+
+      for (let [key, val] of Object.entries(PTU.Addresses.TimBL2)) {
+        let field = content.document.getElementById(key);
+        if (!field) {
+          ok(false, `${key} field not found`);
+        }
+        field.value = val;
+        ok(!field.disabled, `Field #${key} shouldn't be disabled`);
+      }
+      content.document.querySelector("address-form .save-button").click();
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "payment-summary";
+      }, "payment-summary is now visible");
+
+      let cancelButton = content.document.querySelector("#cancel");
+      ok(content.isVisible(cancelButton), "Payment summary page is shown next");
+    });
+
+    info("Closing the payment dialog");
+    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
+    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
+    cleanupFormAutofillStorage();
+  });
+});
+
+add_task(async function test_onboarding_wizard_with_requestShipping_turned_off() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: BLANK_PAGE_URL,
+  }, async browser => {
+    cleanupFormAutofillStorage();
+
+    info("Opening the payment dialog");
+    let {win, frame} =
+      await setupPaymentDialog(browser, {
+        methodData: [PTU.MethodData.basicCard],
+        details: PTU.Details.total60USD,
+        merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
+      });
+
+    await spawnPaymentDialogTask(frame, async function() {
+      let {
+        PaymentTestUtils: PTU,
+      } = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "address-page";
+      // eslint-disable-next-line max-len
+      }, "Billing address page is shown first during on-boarding if requestShipping is turned off");
+
+      info("Checking if the billing address page has been rendered");
+      let addressSaveButton = content.document.querySelector("address-form .save-button");
+      ok(content.isVisible(addressSaveButton),
+         "Address save button is rendered");
+
+      info("Check if the page title is visible on the address page");
+      let addressPageTitle = content.document.querySelector("address-form h1");
+      ok(content.isVisible(addressPageTitle), "Address page title is visible");
+      is(addressPageTitle.textContent, "Add Billing Address",
+         "Address page title is correctly shown");
+
+      for (let [key, val] of Object.entries(PTU.Addresses.TimBL2)) {
+        let field = content.document.getElementById(key);
+        if (!field) {
+          ok(false, `${key} field not found`);
+        }
+        field.value = val;
+        ok(!field.disabled, `Field #${key} shouldn't be disabled`);
+      }
+      content.document.querySelector("address-form .save-button").click();
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "basic-card-page";
+      // eslint-disable-next-line max-len
+      }, "Basic card page is shown after the billing address page during onboarding if requestShipping is turned off");
+
+      let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
+      ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
+
+      for (let [key, val] of Object.entries(PTU.BasicCards.JohnDoe)) {
+        let field = content.document.getElementById(key);
+        field.value = val;
+        ok(!field.disabled, `Field #${key} shouldn't be disabled`);
+      }
+      content.document.querySelector("basic-card-form .save-button").click();
+
+      await PTU.DialogContentUtils.waitForState(content, (state) => {
+        return state.page.id == "payment-summary";
+      }, "payment-summary is shown after the basic card page during on boarding");
+
+      let cancelButton = content.document.querySelector("#cancel");
+      ok(content.isVisible(cancelButton), "Payment summary page is rendered");
+    });
+
+    info("Closing the payment dialog");
+    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
+    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
+
+    cleanupFormAutofillStorage();
+  });
+});
+
+add_task(async function test_on_boarding_wizard_with_requestShipping_turned_off_with_saved_cards() {
+  await BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: BLANK_PAGE_URL,
+  }, async browser => {
+    cleanupFormAutofillStorage();
+    addBasicCard();
+
+    info("Opening the payment dialog");
+    let {win, frame} =
+        await setupPaymentDialog(browser, {
+          methodData: [PTU.MethodData.basicCard],
+          details: PTU.Details.total60USD,
+          merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
+        });
+
+    await spawnPaymentDialogTask(frame, async function() {
+      let cancelButton = content.document.querySelector("#cancel");
+      ok(content.isVisible(cancelButton),
+       // eslint-disable-next-line max-len
+         "Payment summary page is shown if requestShipping is turned off and there's a saved card but no saved address");
+    });
+
+    info("Closing the payment dialog");
+    spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
+    await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
+
+    cleanupFormAutofillStorage();
+  });
+});