Bug 1497219 - Mochitest for PaymentRequest in not fully active document. r=baku
authorEden Chuang <echuang@mozilla.com>
Fri, 14 Dec 2018 15:06:30 +0100
changeset 507879 7ba89c2d426df93c36e8c5550f65f69d4db1dc1d
parent 507878 2738bb9f6d54d34aa1742c50da7f6f120d9577a9
child 507880 bcd3b9fa9eace5c02ff292a3cf5a0476280e582d
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1497219
milestone66.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 1497219 - Mochitest for PaymentRequest in not fully active document. r=baku
dom/payments/test/ClosePaymentChromeScript.js
dom/payments/test/test_closePayment.html
--- a/dom/payments/test/ClosePaymentChromeScript.js
+++ b/dom/payments/test/ClosePaymentChromeScript.js
@@ -3,20 +3,20 @@
    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}`);
 }
 function emitTestPass(message) {
-  sendAsyncMessage("test-pass", message);
+  sendAsyncMessage("test-pass", `${DummyUIService.testName}: ${message}`);
 }
 
 addMessageListener("close-check", function() {
   const paymentEnum = paymentSrv.enumerate();
   if (paymentEnum.hasMoreElements()) {
     emitTestFail("Non-empty PaymentRequest queue in PaymentRequestService.");
   } else {
     emitTestPass("Got empty PaymentRequest queue in PaymentRequestService.");
@@ -51,26 +51,29 @@ addMessageListener("payment-num-check", 
     emitTestPass("Got expected '" + numPayments +
                  "' PaymentRequests in PaymentRequestService.");
   }
   // force cleanup PaymentRequests for clear environment to next testcase.
   paymentSrv.cleanup();
   sendAsyncMessage("payment-num-check-complete");
 });
 
-var respondRequestId;
+addMessageListener("test-setup", (testName) => {
+  DummyUIService.testName = testName;
+  sendAsyncMessage("test-setup-complete");
+});
 
 addMessageListener("reject-payment", (expectedError) => {
   try {
     const responseData = Cc["@mozilla.org/dom/payments/general-response-data;1"].
                             createInstance(Ci.nsIGeneralResponseData);
     responseData.initData({});
     const showResponse = Cc["@mozilla.org/dom/payments/payment-show-action-response;1"].
                             createInstance(Ci.nsIPaymentShowActionResponse);
-    showResponse.init(respondRequestId,
+    showResponse.init(DummyUIService.respondRequestId,
                       Ci.nsIPaymentActionResponse.PAYMENT_REJECTED,
                       "",                 // payment method
                       responseData,       // payment method data
                       "",                 // payer name
                       "",                 // payer email
                       "");                // payer phone
     paymentSrv.respondPayment(showResponse.QueryInterface(Ci.nsIPaymentActionResponse));
     emitTestPass("Reject PaymentRequest successfully");
@@ -85,33 +88,34 @@ addMessageListener("reject-payment", (ex
     emitTestFail("Unexpected error '" + error.name +
                  "' when reponding a closed PaymentRequest");
   }
   sendAsyncMessage("reject-payment-complete");
 });
 
 addMessageListener("update-payment", () => {
   try {
-    paymentSrv.changeShippingOption(respondRequestId, "");
+    paymentSrv.changeShippingOption(DummyUIService.respondRequestId, "");
     emitTestPass("Change shippingOption succefully");
   } catch (error) {
     emitTestFail("Unexpected error '" + error.name +
                  "' when changing the shipping option");
   }
   sendAsyncMessage("update-payment-complete");
 });
 
 const DummyUIService = {
-  showPayment: (requestId => {respondRequestId = requestId}),
-  abortPayment: (requestId) => {respondRequestId = requestId},
-  completePayment: (requestId) => {respondRequestId = requestId},
-  updatePayment: (requestId) => {respondRequestId = requestId},
-  closePayment: (requestId) => {respondRequestId = requestId},
+  testName: "",
+  respondRequestId: "",
+  showPayment: (requestId) => {DummyUIService.respondRequestId = requestId},
+  abortPayment: (requestId) => {DummyUIService.respondRequestId = requestId},
+  completePayment: (requestId) => {DummyUIService.respondRequestId = requestId},
+  updatePayment: (requestId) => {DummyUIService.respondRequestId = requestId},
+  closePayment: (requestId) => {this.respondRequestId = requestId},
   QueryInterface: ChromeUtils.generateQI([Ci.nsIPaymentUIService]),
 };
 
 paymentSrv.setTestingUIService(DummyUIService.QueryInterface(Ci.nsIPaymentUIService));
 
-
 addMessageListener("teardown", function() {
   paymentSrv.setTestingUIService(null);
   sendAsyncMessage('teardown-complete');
 });
--- a/dom/payments/test/test_closePayment.html
+++ b/dom/payments/test/test_closePayment.html
@@ -3,114 +3,109 @@
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=1408234
 -->
 <head>
   <meta charset="utf-8">
   <title>Test for closing PaymentRequest</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="DefaultData.js"></script>
   <script type="application/javascript">
 
   "use strict";
   SimpleTest.waitForExplicitFinish();
 
   var gUrl = SimpleTest.getTestFileURL('ClosePaymentChromeScript.js');
   var gScript = SpecialPowers.loadChromeScript(gUrl);
-  var testName = "";
 
   function testFailHandler(message) {
-    ok(false, testName + ": " + message);
+    ok(false, message);
   }
   function testPassHandler(message) {
-    ok(true, testName + ": " + message);
+    ok(true, message);
   }
   gScript.addMessageListener("test-fail", testFailHandler);
   gScript.addMessageListener("test-pass", testPassHandler);
 
   async function requestChromeAction(action, params) {
     gScript.sendAsyncMessage(action, params);
     await new Promise(resolve => {
       gScript.addMessageListener(`${action}-complete`, function completeListener() {
         gScript.removeMessageListener(`${action}-complete`, completeListener);
         resolve();
       });
     });
   }
 
-  function testCloseByReloading() {
-    return new Promise(async (resolve, reject) => {
-      testName = "testCloseByReloading";
-      let expectedResults = ["successful", "successful"];
+  async function testCloseByReloading() {
+    const testName = "testCloseByReloading";
+    await requestChromeAction("test-setup", testName);
+    info(testName);
+    return new Promise(async (resolve) => {
       let nextStatus = ["creating", "reloading"];
       let currStatus = nextStatus.shift();
       let ifr = document.createElement('iframe');
       await requestChromeAction("payment-num-set");
       let listener = async function(event) {
-        let expected = expectedResults.shift();
-        is(event.data, expected,
-          testName + ": Expected '" + expected + "' when " + currStatus +
-          ", but got '" + event.data + "'");
+        is(event.data, "successful",
+           `${testName}: Expected 'successful' when ${currStatus}, but got '${event.data}'.`);
         if (currStatus === "creating") {
           ifr.contentWindow.location.reload();
         } else if (currStatus === "reloading") {
           window.removeEventListener("message", listener);
           await requestChromeAction("payment-num-check", 1);
           document.body.removeChild(ifr);
           resolve();
         }
         currStatus = nextStatus.shift();
       }
       window.addEventListener("message", listener);
       ifr.src = "simple_payment_request.html";
       document.body.appendChild(ifr);
     });
   }
 
-  function testCloseByRedirecting() {
-    return new Promise((resolve, reject) => {
-      testName = "testCloseByRedirecting";
-      let expectedResults = ["successful", "successful"];
+  async function testCloseByRedirecting() {
+    const testName = "testCloseByRedirecting";
+    await requestChromeAction("test-setup", testName);
+    return new Promise((resolve) => {
       let nextStatus = ["creating", "redirecting"];
       let currStatus = nextStatus.shift();
       let ifr = document.createElement('iframe');
       let listener = async function(event) {
-        let expected = expectedResults.shift();
-        is(event.data, expected,
-          testName + ": Expected '" + expected + "' when " + currStatus +
-          ", but got '" + event.data + "'");
+        is(event.data, "successful",
+           `${testName}: Expected 'successful' when ${currStatus}, but got '${event.data}'.`);
         if (currStatus === "creating") {
           ifr.src = "blank_page.html";
         } else if (currStatus === "redirecting"){
           window.removeEventListener("message", listener);
           await requestChromeAction("close-check");
           document.body.removeChild(ifr);
           resolve();
         }
         currStatus = nextStatus.shift();
       };
       window.addEventListener("message", listener);
       ifr.src = "simple_payment_request.html";
       document.body.appendChild(ifr);
     });
   }
 
-  function testCloseByRedirectingAfterShow() {
-    return new Promise((resolve, reject) => {
-      testName = "testCloseByRedirectingAfterShow";
+  async function testCloseByRedirectingAfterShow() {
+    const testName = "testCloseByRedirectingAfterShow";
+    await requestChromeAction("test-setup", testName);
+    return new Promise((resolve) => {
       let nextStatus = ["creating", "showing", "redirecting"];
       let currStatus = nextStatus.shift();
-      let expectedResults = ["successful", "successful", "successful"];
       let ifr = document.createElement('iframe');
       let handler = undefined;
       let listener = async (event) => {
-        let expected = expectedResults.shift();
-        is(event.data, expected,
-          testName + ": Expected '" + expected + "' when " + currStatus +
-          ", but got '" + event.data + "'");
+        is(event.data, "successful",
+           `${testName}: Expected 'successful' when ${currStatus}, but got '${event.data}'.`);
         if (currStatus === "creating") {
           handler = SpecialPowers.getDOMWindowUtils(ifr.contentWindow).setHandlingUserInput(true);
           ifr.contentWindow.postMessage("show PaymentRequest", "*");
         } else if (currStatus === "showing") {
           handler.destruct();
           ifr.src = "blank_page.html";
         } else if (currStatus === "redirecting") {
           window.removeEventListener("message", listener);
@@ -122,50 +117,48 @@ https://bugzilla.mozilla.org/show_bug.cg
         currStatus = nextStatus.shift();
       }
       window.addEventListener("message", listener);
       ifr.src = "simple_payment_request.html";
       document.body.appendChild(ifr);
     });
   }
 
-  function testCloseByRemovingIframe() {
-    return new Promise((resolve, reject) => {
-      testName = "testCloseByRemovingIframe";
-      let expectedResults = ["successful"];
+  async function testCloseByRemovingIframe() {
+    const testName = "testCloseByRemovingIframe";
+    await requestChromeAction("test-setup", testName);
+    return new Promise((resolve) => {
       let nextStatus = ["creating"];
       let currStatus = nextStatus.shift();
       let ifr = document.createElement('iframe');
       let listener = async function(event) {
-        let expected = expectedResults.shift();
-        is(event.data, expected,
-          testName + ": Expected '" + expected + "' when " + currStatus +
-          ", but got '" + event.data + "'");
+        is(event.data, "successful",
+           `${testName}: Expected 'successful' when ${currStatus}, but got '${event.data}'.`);
         document.body.removeChild(ifr);
         window.removeEventListener("message", listener);
         await requestChromeAction("close-check");
         resolve();
       };
       window.addEventListener("message", listener);
       ifr.src = "simple_payment_request.html";
       document.body.appendChild(ifr);
     });
   }
 
-  function testUpdateWithRespondedPayment() {
+  async function testUpdateWithRespondedPayment() {
+    const testName = "testUpdateWithRespondedPayment";
+    await requestChromeAction("test-setup", testName);
     return new Promise(resolve => {
-      testName = "testUpdateWithRespondedPayment";
       let nextStatus = ["creating", "showing", "closing", "updating", "finishing"];
       let currStatus = nextStatus.shift();
       let ifr = document.createElement('iframe');
       let handler = undefined;
       let listener = async function(event) {
         is(event.data, "successful",
-          testName + ": Expected 'successful' when " + currStatus +
-          ", but got '" + event.data + "'");
+           `${testName}: Expected 'successful' when ${currStatus}, but got '${event.data}'.`);
         switch (currStatus) {
           case "creating":
             handler = SpecialPowers.getDOMWindowUtils(ifr.contentWindow).setHandlingUserInput(true);
             ifr.contentWindow.postMessage("show PaymentRequest", "*");
             break;
           case "showing":
             await requestChromeAction("update-payment");
             break;
@@ -189,41 +182,94 @@ https://bugzilla.mozilla.org/show_bug.cg
         currStatus = nextStatus.shift();
       }
       window.addEventListener("message", listener);
       ifr.src = "simple_payment_request.html";
       document.body.appendChild(ifr);
     });
   }
 
-  function teardown() {
-    return new Promise((resolve, reject) => {
+  function getLoadedPaymentRequest(iframe, url) {
+    return new Promise(resolve => {
+      iframe.addEventListener(
+        "load",
+        () => {
+          const { PaymentRequest } = iframe.contentWindow;
+          const request = new PaymentRequest(defaultMethods, defaultDetails);
+          resolve(request);
+        },
+        { once: true }
+      );
+      iframe.src = url;
+    });
+  }
+
+  async function testNonfullyActivePayment() {
+    const testName = "testNonfullyActivePayment";
+    await requestChromeAction("test-setup", testName);
+    return new Promise(async (resolve) => {
+      const outer = document.createElement("iframe");
+      outer.allowPaymentRequest = true;
+      document.body.appendChild(outer);
+      await getLoadedPaymentRequest(outer,"blank_page.html");
+
+      const inner = outer.contentDocument.createElement("iframe");
+      inner.allowPaymentRequest = true;
+      outer.contentDocument.body.appendChild(inner);
+
+      const request = await getLoadedPaymentRequest(inner,"blank_page.html");
+      ok(request, `${testName}: PaymentRequest in inner iframe should exist.`);
+
+      await new Promise(res => {
+        outer.addEventListener("load", res);
+        outer.src = "simple_payment_request.html";
+      });
+
+      let handler = SpecialPowers.getDOMWindowUtils(inner.contentWindow).setHandlingUserInput(true);
+      try {
+        const showPromise = await request.show();
+        ok(false, `${testName}: expected 'AbortError', but got resolved.`);
+      } catch (error) {
+        is(error.name, "AbortError",
+           `${testName}: expected 'AbortError'.`);
+      }
+      await handler.destruct();
+      inner.remove();
+      outer.remove();
+      resolve();
+    });
+  }
+
+  async function teardown() {
+    return new Promise((resolve) => {
       gScript.addMessageListener("teardown-complete", function teardownCompleteHandler() {
         gScript.removeMessageListener("teardown-complete", teardownCompleteHandler);
         gScript.removeMessageListener("test-fail", testFailHandler);
         gScript.removeMessageListener("test-pass", testPassHandler);
         gScript.destroy();
         SimpleTest.finish();
         resolve();
       });
       gScript.sendAsyncMessage("teardown");
     });
   }
 
-  function runTests() {
-    testCloseByReloading()
-    .then(testCloseByRedirecting)
-    .then(testCloseByRedirectingAfterShow)
-    .then(testCloseByRemovingIframe)
-    .then(testUpdateWithRespondedPayment)
-    .then(teardown)
-    .catch( e => {
-      ok(false, "Unexpected error: " + e.name);
+  async function runTests() {
+    try {
+      await testCloseByReloading();
+      await testCloseByRedirecting();
+      await testCloseByRedirectingAfterShow();
+      await testCloseByRemovingIframe();
+      await testUpdateWithRespondedPayment();
+      await testNonfullyActivePayment();
+      await teardown();
+    } catch(e) {
+      ok(false, "test_closePayment.html: Unexpected error: " + e.name);
       SimpleTest.finish();
-    });
+    }
   }
 
   window.addEventListener('load', function() {
     SpecialPowers.pushPrefEnv({
       'set': [
         ['dom.payments.request.enabled', true],
       ]
     }, runTests);