Bug 1477117 - Part 4 - mochitest for PaymentMethodChangeEvent. r=baku
authorEden Chuang <echuang@mozilla.com>
Tue, 27 Nov 2018 06:33:31 +0100
changeset 505060 ab5b1091c88e42785e247ace0c7cc2d0026661e7
parent 505059 ae31de05b602600e90d8e312d279ed5e58779311
child 505061 9e3b1b073d5e859a010b07119c80adde8a13c41e
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1477117
milestone65.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 1477117 - Part 4 - mochitest for PaymentMethodChangeEvent. r=baku
dom/payments/test/BasiccardChromeScript.js
dom/payments/test/test_basiccard.html
--- a/dom/payments/test/BasiccardChromeScript.js
+++ b/dom/payments/test/BasiccardChromeScript.js
@@ -3,17 +3,17 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 "use strict";
 
 const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const paymentSrv = Cc["@mozilla.org/dom/payments/payment-request-service;1"].getService(Ci.nsIPaymentRequestService);
 
 function emitTestFail(message) {
-  sendAsyncMessage("test-fail", message);
+  sendAsyncMessage("test-fail", `${DummyUIService.testName}: ${message}`);
 }
 
 const billingAddress = Cc["@mozilla.org/dom/payments/payment-address;1"].
                            createInstance(Ci.nsIPaymentAddress);
 const addressLine = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
 const address = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
 address.data = "Easton Ave";
 addressLine.appendElement(address);
@@ -45,16 +45,19 @@ specialAddress.init("USA",              
                      "123456",           // sorting code
                      "",                 // organization
                      "Bill A. Pacheco",  // recipient
                      "+14344413879"); // phone
 
 const basiccardResponseData = Cc["@mozilla.org/dom/payments/basiccard-response-data;1"].
                                  createInstance(Ci.nsIBasicCardResponseData);
 
+const basiccardChangeDetails = Cc["@mozilla.org/dom/payments/basiccard-change-details;1"].
+                                  createInstance(Ci.nsIBasicCardChangeDetails);
+
 const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
                         createInstance(Ci.nsIPaymentShowActionResponse);
 
 function abortPaymentResponse(requestId) {
   let abortResponse = Cc["@mozilla.org/dom/payments/payment-abort-action-response;1"].
                          createInstance(Ci.nsIPaymentAbortActionResponse);
   abortResponse.init(requestId, Ci.nsIPaymentActionResponse.ABORT_SUCCEEDED);
   paymentSrv.respondPayment(abortResponse.QueryInterface(Ci.nsIPaymentActionResponse));
@@ -62,18 +65,79 @@ function abortPaymentResponse(requestId)
 
 function completePaymentResponse(requestId) {
   let completeResponse = Cc["@mozilla.org/dom/payments/payment-complete-action-response;1"].
                             createInstance(Ci.nsIPaymentCompleteActionResponse);
   completeResponse.init(requestId, Ci.nsIPaymentActionResponse.COMPLETE_SUCCEEDED);
   paymentSrv.respondPayment(completeResponse.QueryInterface(Ci.nsIPaymentActionResponse));
 }
 
-const detailedResponseUI = {
-  showPayment: function(requestId) {
+function showRequest(requestId) {
+  if (DummyUIService.showAction === "payment-method-change") {
+    basiccardChangeDetails.initData(billingAddress);
+    try {
+      paymentSrv.changePaymentMethod(requestId, "basic-card", basiccardChangeDetails.QueryInterface(Ci.nsIMethodChangeDetails));
+    } catch (error) {
+      emitTestFail(`Unexpected error (${error.name}) when calling PaymentRequestService::changePaymentMethod`);
+    }
+    return;
+  }
+  if (DummyUIService.showAction === "detailBasicCardResponse") {
+    try {
+      basiccardResponseData.initData("Bill A. Pacheco",  // cardholderName
+                                     "4916855166538720", // cardNumber
+                                     "01",               // expiryMonth
+                                     "2024",             // expiryYear
+                                     "180",              // cardSecurityCode
+                                     billingAddress);   // billingAddress
+    } catch (e) {
+      emitTestFail("Fail to initialize basic card response data.");
+    }
+  }
+  if (DummyUIService.showAction === "simpleBasicCardResponse") {
+    try {
+      basiccardResponseData.initData("",                 // cardholderName
+                                     "4916855166538720", // cardNumber
+                                     "",                 // expiryMonth
+                                     "",                 // expiryYear
+                                     "",                 // cardSecurityCode
+                                     null);              // billingAddress
+    } catch (e) {
+      emitTestFail("Fail to initialize basic card response data.");
+    }
+  }
+  if (DummyUIService.showAction === "specialAddressResponse") {
+    try {
+      basiccardResponseData.initData("Bill A. Pacheco",  // cardholderName
+                                     "4916855166538720", // cardNumber
+                                     "01",               // expiryMonth
+                                     "2024",             // expiryYear
+                                     "180",              // cardSecurityCode
+                                     specialAddress);    // billingAddress
+    } catch (e) {
+      emitTestFail("Fail to initialize basic card response data.");
+    }
+  }
+  showResponse.init(requestId,
+                    Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
+                    "basic-card",         // payment method
+                    basiccardResponseData,// payment method data
+                    "Bill A. Pacheco",    // payer name
+                    "",                   // payer email
+                    "");                  // payer phone
+  paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
+}
+
+const DummyUIService = {
+  testName: "",
+  showAction: "",
+  showPayment: showRequest,
+  abortPayment: abortPaymentResponse,
+  completePayment: completePaymentResponse,
+  updatePayment: (requestId) => {
     try {
       basiccardResponseData.initData("Bill A. Pacheco",  // cardholderName
                                      "4916855166538720", // cardNumber
                                      "01",               // expiryMonth
                                      "2024",             // expiryYear
                                      "180",              // cardSecurityCode
                                      billingAddress);   // billingAddress
     } catch (e) {
@@ -83,98 +147,47 @@ const detailedResponseUI = {
                       Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
                       "basic-card",         // payment method
                       basiccardResponseData,// payment method data
                       "Bill A. Pacheco",    // payer name
                       "",                   // payer email
                       "");                  // payer phone
     paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
   },
-  abortPayment: abortPaymentResponse,
-  completePayment: completePaymentResponse,
-  updatePayment: function(requestId) {
-  },
-  closePayment: function (requestId) {
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
-};
-
-const simpleResponseUI = {
-  showPayment: function(requestId) {
-    try {
-      basiccardResponseData.initData("",                 // cardholderName
-                                     "4916855166538720", // cardNumber
-                                     "",                 // expiryMonth
-                                     "",                 // expiryYear
-                                     "",                 // cardSecurityCode
-                                     null);              // billingAddress
-    } catch (e) {
-      emitTestFail("Fail to initialize basic card response data.");
-    }
-    showResponse.init(requestId,
-                      Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
-                      "basic-card",         // payment method
-                      basiccardResponseData,// payment method data
-                      "Bill A. Pacheco",    // payer name
-                      "",                   // payer email
-                      "");                  // payer phone
-    paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
-  },
-  abortPayment: abortPaymentResponse,
-  completePayment: completePaymentResponse,
-  updatePayment: function(requestId) {
-  },
-  closePayment: function(requestId) {
-  },
+  closePayment: (requestId) => {},
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
 };
 
-const specialAddressUI = {
-  showPayment: function(requestId) {
-    try {
-      basiccardResponseData.initData("Bill A. Pacheco",  // cardholderName
-                                     "4916855166538720", // cardNumber
-                                     "01",               // expiryMonth
-                                     "2024",             // expiryYear
-                                     "180",              // cardSecurityCode
-                                     specialAddress);    // billingAddress
-    } catch (e) {
-      emitTestFail("Fail to initialize basic card response data.");
-    }
-    showResponse.init(requestId,
-                      Ci.nsIPaymentActionResponse.PAYMENT_ACCEPTED,
-                      "basic-card",         // payment method
-                      basiccardResponseData,// payment method data
-                      "Bill A. Pacheco",    // payer name
-                      "",                   // payer email
-                      "");                  // payer phone
-    paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
-  },
-  abortPayment: abortPaymentResponse,
-  completePayment: completePaymentResponse,
-  updatePayment: function(requestId) {
-  },
-  closePayment: function (requestId) {
-  },
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
-};
+paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
 
-addMessageListener("set-detailed-ui-service", function() {
-  paymentSrv.setTestingUIService(detailedResponseUI.QueryInterface(Ci.nsIPaymentUIService));
+addMessageListener("set-detailed-ui-service", function(testName) {
+  DummyUIService.testName = testName;
+  DummyUIService.showAction = "detailBasicCardResponse";
+  sendAsyncMessage("set-detailed-ui-service-complete");
+});
+
+addMessageListener("set-simple-ui-service", function(testName) {
+  DummyUIService.testName = testName;
+  DummyUIService.showAction = "simpleBasicCardResponse";
+  sendAsyncMessage("set-simple-ui-service-complete");
 });
 
-addMessageListener("set-simple-ui-service", function() {
-  paymentSrv.setTestingUIService(simpleResponseUI.QueryInterface(Ci.nsIPaymentUIService));
+addMessageListener("set-special-address-ui-service", function(testName) {
+  DummyUIService.testName = testName;
+  DummyUIService.showAction = "specialAddressResponse";
+  sendAsyncMessage("set-special-address-ui-service-complete");
 });
 
-addMessageListener("set-special-address-ui-service", function() {
-  paymentSrv.setTestingUIService(specialAddressUI.QueryInterface(Ci.nsIPaymentUIService));
+addMessageListener("method-change-to-basic-card", function(testName) {
+  DummyUIService.testName = testName;
+  DummyUIService.showAction = "payment-method-change";
+  sendAsyncMessage("method-change-to-basic-card-complete");
 });
 
-addMessageListener("error-response-test", function() {
+addMessageListener("error-response-test", function(testName) {
   // test empty cardNumber
   try {
     basiccardResponseData.initData("", "", "", "", "", null);
     emitTestFail("BasicCardResponse should not be initialized with empty cardNumber.");
   } catch (e) {
     if (e.name != "NS_ERROR_FAILURE") {
       emitTestFail("Empty cardNumber expected 'NS_ERROR_FAILURE', but got " + e.name + ".");
     }
@@ -244,15 +257,15 @@ addMessageListener("error-response-test"
                       "",                   // payer email
                       "");                  // payer phone
     emitTestFail("nsIPaymentShowActionResponse should not be initialized with basic-card method and nsIGeneralResponseData.");
   } catch (e) {
     if (e.name != "NS_ERROR_FAILURE") {
       emitTestFail("ShowResponse init expected 'NS_ERROR_FAILURE', but got " + e.name + ".");
     }
   }
-  sendAsyncMessage("error-response-complete");
+  sendAsyncMessage("error-response-test-complete");
 });
 
 addMessageListener("teardown", function() {
   paymentSrv.setTestingUIService(null);
   sendAsyncMessage("teardown-complete");
 });
--- a/dom/payments/test/test_basiccard.html
+++ b/dom/payments/test/test_basiccard.html
@@ -14,17 +14,31 @@ https://bugzilla.mozilla.org/show_bug.cg
   SimpleTest.waitForExplicitFinish();
 
   var gUrl = SimpleTest.getTestFileURL('BasiccardChromeScript.js');
   var gScript = SpecialPowers.loadChromeScript(gUrl);
 
   function testFailHandler(message) {
     ok(false, message);
   }
+  function testPassHandler(message) {
+    ok(true, message);
+  }
   gScript.addMessageListener("test-fail", testFailHandler);
+  gScript.addMessageListener("test-pass", testPassHandler);
+
+  async function requestChromeAction(action, params) {
+    await new Promise(resolve => {
+      gScript.addMessageListener(`${action}-complete`, function completeListener() {
+        gScript.removeMessageListener(`${action}-complete`, completeListener);
+        resolve();
+      });
+      gScript.sendAsyncMessage(action, params);
+    });
+  }
 
   const errorNetworksMethods = [{
     supportedMethods: "basic-card",
     data: {
       supportedNetworks: ["myNetwork"],
     },
   }];
 
@@ -76,210 +90,304 @@ https://bugzilla.mozilla.org/show_bug.cg
           currency: "USD",
           value: "30.00"
         },
         selected: false,
       },
     ],
   };
 
+  const updateDetails = {
+    total: {
+      label: "Total",
+      amount: {
+        currency: "USD",
+        value: "1.00"
+      }
+    },
+    shippingOptions: [
+      {
+        id: "NormalShipping",
+        label: "NormalShipping",
+        amount: {
+          currency: "USD",
+          value: "10.00"
+        },
+        selected: true,
+      },
+      {
+        id: "FastShipping",
+        label: "FastShipping",
+        amount: {
+          currency: "USD",
+          value: "30.00"
+        },
+        selected: false,
+      },
+    ],
+    error: "",
+  };
+
   const defaultOptions = {
     requestPayerName: true,
     requestPayerEmail: false,
     requestPayerPhone: false,
     requestShipping: true,
     shippingType: "shipping"
   };
 
-  function testBasicCardRequestWithErrorNetworks() {
-    return new Promise((resolve, reject) => {
+  async function testBasicCardRequestWithErrorNetworks() {
+    const testName = "testBasicCardRequestWithErrorNetworks";
+    return new Promise(async (resolve) => {
       try {
-        const payRequest = new PaymentRequest(errorNetworksMethods, defaultDetails, defaultOptions);
-        ok(false, "Expected 'TypeError', but got success construction.");
-        resolve();
+        const request = new PaymentRequest(errorNetworksMethods, defaultDetails, defaultOptions);
+        ok(false, `${testName}: Expected 'TypeError', but got success construction.`);
       } catch (e) {
-        is(e.name, "TypeError", "Expected TypeError, but got " + e.name);
-        resolve();
+        is(e.name, "TypeError", `${testName}: Expected TypeError, but got ${e.name}`);
       }
+      resolve();
     });
   }
 
-  function testBasicCardRequestWithUnconvertableData() {
-    return new Promise((resolve, reject) => {
+  async function testBasicCardRequestWithUnconvertableData() {
+    const testName = "testBasicCardRequestWithUnconvertableData";
+    return new Promise(async (resolve) => {
       try {
-        const payRequest = new PaymentRequest(unconvertableDataMethods, defaultDetails, defaultOptions);
-        ok(false, "Expected 'TypeError', but got success construction.");
-        resolve();
+        const request = new PaymentRequest(unconvertableDataMethods, defaultDetails, defaultOptions);
+        ok(false, `${testName}: Expected 'TypeError', but got success construction.`);
       } catch (e) {
-        is(e.name, "TypeError", "Expected TypeError, but got " + e.name);
-        resolve();
+        is(e.name, "TypeError", `${testName}: Expected TypeError, but got ${e.name}`);
       }
+      resolve();
+    });
+  }
+
+  async function testBasicCardRequestWithNullData() {
+    const testName = "testBasicCardRequestWithNullData";
+    return new Promise(async (resolve) => {
+      try {
+        const request = new PaymentRequest(nullDataMethods, defaultDetails, defaultOptions);
+        ok(request, `${testName}: PaymentRequest should be constructed with null data BasicCardRequest.`);
+      } catch (e) {
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
+      }
+      resolve();
     });
   }
 
-  function testBasicCardRequestWithNullData() {
-    return new Promise((resolve, reject) => {
+  async function testBasicCardRequestWithEmptyData() {
+    const testName = "testBasicCardRequestWithEmptyData";
+    return new Promise(async (resolve) => {
       try {
-        const payRequest = new PaymentRequest(nullDataMethods, defaultDetails, defaultOptions);
-        ok(payRequest, "PaymentRequest should be constructed with null data BasicCardRequest.");
-        resolve();
+        const request = new PaymentRequest(emptyDataMethods, defaultDetails, defaultOptions);
+        ok(request, `${testName}: PaymentRequest should be constructed with empty data BasicCardRequest.`);
       } catch (e) {
-        ok(false, "Unexpected error: " + e.name);
-        resolve();
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
       }
+      resolve();
     });
   }
 
-  function testBasicCardRequestWithEmptyData() {
-    return new Promise((resolve, reject) => {
+  async function testCanMakePaymentWithBasicCardRequest() {
+    const testName = "testCanMakePaymentWithBasicCardRequest";
+    return new Promise(async (resolve) => {
+      const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
       try {
-        const payRequest = new PaymentRequest(emptyDataMethods, defaultDetails, defaultOptions);
-        ok(payRequest, "PaymentRequest should be constructed with empty data BasicCardRequest.");
-        resolve();
+        const result = await request.canMakePayment();
+        ok(result, `${testName}: canMakePayment() should be resolved with true.`);
       } catch (e) {
-        ok(false, "Unexpected error: " + e.name);
-        resolve();
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
       }
+      resolve();
     });
   }
 
-  function testCanMakePaymentWithBasicCardRequest() {
-    return new Promise((resolve, reject) => {
-      const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
-      payRequest.canMakePayment().then( result => {
-        ok(result, "Should be resolved with true, but got false.");
-        resolve();
-      }).catch (e => {
-        ok(false, "Unexpected error: " + e.name);
-        resolve();
-      });
+  async function testBasicCardSimpleResponse() {
+    const testName = "testBasicCardSimpleResponse";
+    await requestChromeAction("set-simple-ui-service", testName);
+    return new Promise(async (resolve) => {
+      const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
+      const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+      try {
+        const response = await request.show();
+        ok(response.details, `${testName}: basiccard response should exists.`);
+        ok(!response.details.cardholderName, `${testName}: response.details.cardholderName should not exist.`);
+        is(response.details.cardNumber, "4916855166538720",
+           `${testName}: response.details.cardNumber should be '4916855166538720'.`);
+        ok(!response.details.expiryMonth, `${testName}: response.details.expiryMonth should not exist.`);
+        ok(!response.details.expiryYear, `${testName}: response.details.expiryYear should be '2024'.`);
+        ok(!response.details.cardSecurityCode, `${testName}: response.details.cardSecurityCode should not exist.`);
+        ok(!response.details.billingAddress, `${testName}: response.details.billingAddress should not exist.`);
+        await response.complete("success");
+      } catch (e) {
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
+      }
+      await handler.destruct();
+      resolve();
     });
   }
 
-  function testBasicCardSimpleResponse() {
-    const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+  async function testBasicCardDetailedResponse() {
+    const testName = "testBasicCardDetailedResponse";
+    await requestChromeAction("set-detailed-ui-service", testName);
+    return new Promise(async (resolve) => {
+      const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
+      const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+      try {
+        const response = await request.show();
+        ok(response.details, `${testName}: basiccard response should exists.`);
+        ok(response.details.cardholderName, `${testName}: response.details.cardholderName should not exist.`);
+        is(response.details.cardNumber, "4916855166538720",
+           `${testName}: response.details.cardNumber should be '4916855166538720'.`);
+        ok(response.details.expiryMonth, `${testName}: response.details.expiryMonth should not exist.`);
+        ok(response.details.expiryYear, `${testName}: response.details.expiryYear should be '2024'.`);
+        ok(response.details.cardSecurityCode, `${testName}: response.details.cardSecurityCode should not exist.`);
+        ok(response.details.billingAddress, `${testName}: response.details.billingAddress should not exist.`);
+        const billingAddress = response.details.billingAddress;
+        is(billingAddress.country, "USA", `${testName}: country should be 'USA'.`);
+        is(billingAddress.addressLine.length, 1, `${testName}: addressLine.length should be 1.`);
+        is(billingAddress.addressLine[0], "Easton Ave", `${testName}: addressLine[0] should be 'Easton Ave'.`);
+        is(billingAddress.region, "CA", `${testName}: region should be 'CA'.`);
+        is(billingAddress.regionCode, "CA", `${testName}: regionCode should be 'CA'.`);
+        is(billingAddress.city, "San Bruno", `${testName}: city should be 'San Bruno'.`);
+        is(billingAddress.dependentLocality, "", `${testName}: dependentLocality should be empty.`);
+        is(billingAddress.postalCode, "94066", `${testName}: postalCode should be '94066'.`);
+        is(billingAddress.sortingCode, "123456", `${testName}: sortingCode should be '123456'.`);
+        is(billingAddress.organization, "", `${testName}: organization should be empty.`);
+        is(billingAddress.recipient, "Bill A. Pacheco", `${testName}: recipient should be 'Bill A. Pacheco'.`);
+        is(billingAddress.phone, "+14344413879", `${testName}: phone should be '+14344413879'.`);
+        await response.complete("success");
+      } catch (e) {
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
+      }
+      await handler.destruct();
+      resolve();
+    });
+  }
 
-    gScript.sendAsyncMessage("set-simple-ui-service");
-    return new Promise((resolve, reject) => {
-      const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
-      payRequest.show().then(response => {
-        ok(response.details, "basiccard response should exists.");
-        ok(!response.details.cardholderName, "response.details.cardholderName should not exist.");
-        is(response.details.cardNumber, "4916855166538720", "response.details.cardNumber should be '4916855166538720'.");
-        ok(!response.details.expiryMonth, "response.details.expiryMonth should not exist.");
-        ok(!response.details.expiryYear, "response.details.expiryYear should be '2024'.");
-        ok(!response.details.cardSecurityCode, "response.details.cardSecurityCode should not exist.");
-        ok(!response.details.billingAddress, "response.details.billingAddress should not exist.");
-        response.complete("success").then(() =>{
-          resolve();
-        }).catch(e => {
-          ok(false, "Unexpected error: " + e.name);
-          resolve();
-        });
-      }).catch( e => {
-        ok(false, "Unexpected error: " + e.name);
-        resolve();
-      }).finally(handler.destruct);
+  async function testSpecialAddressResponse() {
+    const testName = "testSpecialAddressResponse";
+    await requestChromeAction("set-special-address-ui-service", testName);
+    return new Promise(async (resolve) => {
+      const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
+      const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+      try {
+        const response = await request.show();
+        ok(response.details, `${testName}: BasiccardResponse should exist.`);
+        ok(response.details.billingAddress,
+           `${testName}: BasiccardResponse.billingAddress should exist.`);
+        is(response.details.billingAddress.addressLine[0], ":$%@&*",
+           `${testName}: AddressLine should be ':$%@&*'`);
+        await response.complete("success");
+      } catch (e) {
+        ok(false, `${testName}: Unexpected error: ${e.name}`);
+      }
+      await handler.destruct();
+      resolve();
     });
   }
 
-  function testBasicCardDetailedResponse() {
-    const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
-
-    gScript.sendAsyncMessage("set-detailed-ui-service");
-    return new Promise((resolve, reject) => {
-      const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
-      payRequest.show().then(response => {
-        ok(response.details, "basiccard response should exists.");
-        is(response.details.cardholderName, "Bill A. Pacheco", "response.details.cardholderName should be 'Bill A. Pacheco'.");
-        is(response.details.cardNumber, "4916855166538720", "response.details.cardNumber should be '4916855166538720'.");
-        is(response.details.expiryMonth, "01", "response.details.expiryMonth should be '01'.");
-        is(response.details.expiryYear, "2024", "response.details.expiryYear should be '2024'.");
-        is(response.details.cardSecurityCode, "180", "response.details.cardSecurityCode should be '180'.");
-        const billingAddress = response.details.billingAddress;
-        is(billingAddress.country, "USA", "country should be 'USA'.");
-        is(billingAddress.addressLine.length, 1, "addressLine.length should be 1.");
-        is(billingAddress.addressLine[0], "Easton Ave", "addressLine[0] should be 'Easton Ave'.");
-        is(billingAddress.region, "CA", "region should be 'CA'.");
-        is(billingAddress.regionCode, "CA", "regionCode should be 'CA'.");
-        is(billingAddress.city, "San Bruno", "city should be 'San Bruno'.");
-        is(billingAddress.dependentLocality, "", "dependentLocality should be empty.");
-        is(billingAddress.postalCode, "94066", "postalCode should be '94066'.");
-        is(billingAddress.sortingCode, "123456", "sortingCode should be '123456'.");
-        is(billingAddress.organization, "", "organization should be empty." );
-        is(billingAddress.recipient, "Bill A. Pacheco", "recipient should be 'Bill A. Pacheco'.");
-        is(billingAddress.phone, "+14344413879", "phone should be '+14344413879'.");
-        response.complete("success").then(() =>{
-          resolve();
-        }).catch(e => {
-          ok(false, "Unexpected error: " + e.name);
-          resolve();
-        });
-      }).catch( e => {
-        ok(false, "Unexpected error: " + e.name);
-        resolve();
-      }).finally(handler.destruct);
+  async function testMethodChangeWithoutRequestBillingAddress() {
+    const testName = "testMethodChangeWithoutRequestBillingAddress";
+    await requestChromeAction("method-change-to-basic-card", testName);
+    return new Promise(async (resolve) => {
+      const request = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
+      request.addEventListener("paymentmethodchange", async (event) => {
+        is(event.methodName, "basic-card", `${testName}: PaymentMethodChangeEvent.methodName should be 'basic-card'.`)
+        ok(event.methodDetails, `PaymentMethodChangeEvent.methodDetails should exist.`);
+        ok(!event.methodDetails.billingAddress, `PaymentMethodChangeEvent.methodDetails.billingAddres should not exist.`);
+        event.updateWith(updateDetails);
+      });
+      const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+      try {
+        const response = await request.show();
+        await response.complete("success");
+      } catch (error) {
+        ok(false, `${testName}: Unexpected error: ${error.name}`);
+      }
+      await handler.destruct();
+      resolve();
     });
   }
 
-  function testSpecialAddressResponse() {
-    const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
-    gScript.sendAsyncMessage("set-special-address-ui-service");
-    return new Promise((resolve, reject) => {
-      const payRequest = new PaymentRequest(defaultMethods, defaultDetails, defaultOptions);
-      payRequest.show().then(response => {
-        ok(response.details, "BasiccardResponse should exist.");
-        ok(response.details.billingAddress,
-           "BasiccardResponse.billingAddress should exist.");
-        is(response.details.billingAddress.addressLine[0], ":$%@&*",
-           "AddressLine should be ':$%@&*'");
-        response.complete("success").then(()=>{
-          resolve();
-        });
-      }).finally(handler.destruct);
+  async function testMethodChangeWithRequestBillingAddress() {
+    const testName = "testMethodChangeWithRequestBillingAddress";
+    await requestChromeAction("method-change-to-basic-card", testName);
+    return new Promise(async (resolve) => {
+      const options = {
+        requestPayerName: true,
+        requestBillingAddress: true,
+        requestShipping: true,
+        shippingType: "shipping",
+      };
+      const request = new PaymentRequest(defaultMethods, defaultDetails, options);
+      request.addEventListener("paymentmethodchange", async (event) => {
+        is(event.methodName, "basic-card", `${testName}: PaymentMethodChangeEvent.methodName should be 'basic-card'.`)
+        ok(event.methodDetails, `PaymentMethodChangeEvent.methodDetails should exist.`);
+        const billingAddress = event.methodDetails.billingAddress;
+        is(billingAddress.country, "USA", `${testName}: country should be 'USA'.`);
+        is(billingAddress.addressLine.length, 1, `${testName}: addressLine.length should be 1.`);
+        is(billingAddress.addressLine[0], "Easton Ave", `${testName}: addressLine[0] should be 'Easton Ave'.`);
+        is(billingAddress.region, "CA", `${testName}: region should be 'CA'.`);
+        is(billingAddress.regionCode, "CA", `${testName}: regionCode should be 'CA'.`);
+        is(billingAddress.city, "San Bruno", `${testName}: city should be 'San Bruno'.`);
+        is(billingAddress.dependentLocality, "", `${testName}: dependentLocality should be empty.`);
+        is(billingAddress.postalCode, "94066", `${testName}: postalCode should be '94066'.`);
+        is(billingAddress.sortingCode, "123456", `${testName}: sortingCode should be '123456'.`);
+        is(billingAddress.organization, "", `${testName}: organization should be empty.`);
+        is(billingAddress.recipient, "Bill A. Pacheco", `${testName}: recipient should be 'Bill A. Pacheco'.`);
+        is(billingAddress.phone, "+14344413879", `${testName}: phone should be '+14344413879'.`);
+        event.updateWith(updateDetails);
+      });
+      const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(true);
+      try {
+        const response = await request.show();
+        await response.complete("success");
+      } catch (error) {
+        ok(false, `${testName}: Unexpected error: ${error.name}`);
+      }
+      await handler.destruct();
+      resolve();
     });
   }
 
-  function testBasicCardErrorResponse() {
-    return new Promise((resolve, reject) => {
-      gScript.addMessageListener("error-response-complete",
-                                 function errorResponseCompleteHandler() {
-        gScript.removeMessageListener("error-response-complete",
-                                      errorResponseCompleteHandler);
-        resolve();
-      });
-      gScript.sendAsyncMessage("error-response-test");
-    });
+
+  async function testBasicCardErrorResponse() {
+    const testName = "testBasicCardErrorResponse";
+    return requestChromeAction("error-response-test", testName);
   }
 
-  function teardown() {
+  async function teardown() {
     gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
       gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
       gScript.removeMessageListener("test-fail", testFailHandler)
       gScript.destroy();
       SimpleTest.finish();
     });
     gScript.sendAsyncMessage("teardown");
   }
 
-  function runTests() {
-    testBasicCardRequestWithErrorNetworks()
-    .then(testBasicCardRequestWithUnconvertableData)
-    .then(testBasicCardRequestWithNullData)
-    .then(testBasicCardRequestWithEmptyData)
-    .then(testCanMakePaymentWithBasicCardRequest)
-    .then(testBasicCardSimpleResponse)
-    .then(testBasicCardDetailedResponse)
-    .then(testSpecialAddressResponse)
-    .then(testBasicCardErrorResponse)
-    .then(teardown)
-    .catch( e => {
-      ok(false, "Unexpected error: " + e.name);
+  async function runTests() {
+    try {
+      await testBasicCardRequestWithErrorNetworks();
+      await testBasicCardRequestWithUnconvertableData();
+      await testBasicCardRequestWithNullData();
+      await testBasicCardRequestWithEmptyData();
+      await testCanMakePaymentWithBasicCardRequest();
+      await testBasicCardSimpleResponse();
+      await testBasicCardDetailedResponse();
+      await testSpecialAddressResponse();
+      await testBasicCardErrorResponse();
+      await testMethodChangeWithoutRequestBillingAddress();
+      await testMethodChangeWithRequestBillingAddress()
+      await teardown();
+    } catch (e) {
+      ok(false, `test_basiccard.html: Unexpected error: ${e.name}`);
       SimpleTest.finish();
-    });
+    };
   }
 
   window.addEventListener('load', function() {
     SpecialPowers.pushPrefEnv({
       'set': [
         ['dom.payments.request.enabled', true],
       ]
     }, runTests);