Bug 1527222 [wpt PR 15332] - [Payment Request][WPT] Fix inactive page tests., a=testonly
authorRouslan Solomakhin <rouslan@chromium.org>
Tue, 05 Mar 2019 11:12:13 +0000
changeset 522141 ec1f4ffa35d1590e641a668b370bc84b9aa2933e
parent 522140 89dc1513582b72484244b676404792d5239e2e2e
child 522142 1c5a3f8b212a2e434654da850c4c515cf79ebeae
push id10871
push usercbrindusan@mozilla.com
push dateMon, 18 Mar 2019 15:49:32 +0000
treeherdermozilla-beta@018abdd16060 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1527222, 15332, 929773, 1463664, 631791
milestone67.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 1527222 [wpt PR 15332] - [Payment Request][WPT] Fix inactive page tests., a=testonly Automatic update from web-platform-tests [Payment Request][WPT] Fix inactive page tests. Before this patch, the tests for calling PaymentRequest.show() in an inactive document failed because the renderer checked for an IPC connection to the browser and rejected the show() promise with an InvalidStateError because of the lack of the IPC connection. This happens because the IPC connection is terminated after the browser payment sheet closes, which happens upon a page becoming inactive. Instead, the renderer should check for an active document first and reject with AbortError in an inactive document. This patch makes PaymentRequest.show() check for an active document first and reject with AbortError in an inactive document. The IPC connection is checked second. This patch also makes a couple of active document test cases manual for ease of testing. The last test case is not moved and is still failing. It is unlikely to ever pass in Chrome, because it navigates away the context where a PaymentRequest.show() promise object was created. After the navigation, the promise object cannot change state in Chrome. After this patch, two manual test cases for active document are passing in Chrome. Bug: 929773 Change-Id: Idbe9dbd03a69c18a4d24ba34642e6c7046026c62 Reviewed-on: https://chromium-review.googlesource.com/c/1463664 Reviewed-by: Danyao Wang <danyao@chromium.org> Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org> Cr-Commit-Position: refs/heads/master@{#631791} -- wpt-commits: e6645a41093b3516eaa5bab63cd0ba65b3778a4e wpt-pr: 15332
testing/web-platform/tests/payment-request/rejects_if_not_active.https.html
testing/web-platform/tests/payment-request/rejects_if_not_active_manual.https.html
--- a/testing/web-platform/tests/payment-request/rejects_if_not_active.https.html
+++ b/testing/web-platform/tests/payment-request/rejects_if_not_active.https.html
@@ -1,17 +1,16 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<link rel="help" href="https://w3c.github.io/payment-request/#show()-method">
 <title>PaymentRequest show() rejects if doc is not fully active</title>
+<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
-<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentrequest-show()">
 <body>
 <script>
 const applePay = Object.freeze({
   supportedMethods: "https://apple.com/apple-pay",
   data: {
     version: 3,
     merchantIdentifier: "merchant.com.example",
     countryCode: "US",
@@ -49,104 +48,16 @@ function getLoadedPaymentRequest(iframe,
     iframe.src = url;
   });
 }
 
 promise_test(async t => {
   const iframe = document.createElement("iframe");
   iframe.allowPaymentRequest = true;
   document.body.appendChild(iframe);
-  // We first got to page1.html, grab a PaymentRequest instance.
-  const request1 = await getLoadedPaymentRequest(
-    iframe,
-    "/payment-request/resources/page1.html"
-  );
-  // We navigate the iframe again, putting request1's document into an inactive state.
-  const request2 = await getLoadedPaymentRequest(
-    iframe,
-    "/payment-request/resources/page2.html"
-  );
-  await test_driver.bless("show payment request", async () => {
-    // Now, request1's relevant global object's document is no longer active.
-    // So, call .show(), and make sure it rejects appropriately.
-    await promise_rejects(
-      t,
-      "AbortError",
-      request1.show(),
-      "Inactive document, so must throw AbortError"
-    );
-  });
-  await test_driver.bless("show payment request", async () => {
-    // request2 has an active document tho, so confirm it's working as expected:
-    request2.show();
-    await request2.abort();
-    await promise_rejects(
-      t,
-      "InvalidStateError",
-      request2.show(),
-      "Abort already called, so InvalidStateError"
-    );
-    // We are done, so clean up.
-    iframe.remove();
-  });
-}, "PaymentRequest.show() aborts if the document is not active");
-
-promise_test(async t => {
-  // We nest two iframes and wait for them to load.
-  const outerIframe = document.createElement("iframe");
-  outerIframe.allowPaymentRequest = true;
-  document.body.appendChild(outerIframe);
-  // Load the outer iframe (we don't care about the awaited request)
-  await getLoadedPaymentRequest(
-    outerIframe,
-    "/payment-request/resources/page1.html"
-  );
-
-  // Now we create the inner iframe
-  const innerIframe = outerIframe.contentDocument.createElement("iframe");
-  innerIframe.allowPaymentRequest = true;
-
-  // nest them
-  outerIframe.contentDocument.body.appendChild(innerIframe);
-
-  // load innerIframe, and get the PaymentRequest instance
-  const request = await getLoadedPaymentRequest(
-    innerIframe,
-    "/payment-request/resources/page2.html"
-  );
-
-  // Navigate the outer iframe to a new location.
-  // Wait for the load event to fire.
-  await new Promise(resolve => {
-    outerIframe.addEventListener("load", resolve);
-    outerIframe.src = "/payment-request/resources/page2.html";
-  });
-
-  const showPromise = await test_driver.bless("show payment request", () => {
-    return request.show();
-  });
-  // Now, request's relevant global object's document is still active
-  // (it is the active document of the inner iframe), but is not fully active
-  // (since the parent of the inner iframe is itself no longer active).
-  // So, call request.show() and make sure it rejects appropriately.
-  await promise_rejects(
-    t,
-    "AbortError",
-    showPromise,
-    "Active, but not fully active, so must throw AbortError"
-  );
-  // We are done, so clean up.
-
-  iframe.remove();
-}, "PaymentRequest.show() aborts if the document is active, but not fully active");
-
-promise_test(async t => {
-  const iframe = document.createElement("iframe");
-  iframe.allowPaymentRequest = true;
-  document.body.appendChild(iframe);
   // Make a request in the iframe.
   const request = await getLoadedPaymentRequest(
     iframe,
     "/payment-request/resources/page1.html"
   );
   const showPromise = await test_driver.bless("show payment request", () => {
     return request.show();
   });
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/rejects_if_not_active_manual.https.html
@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>PaymentRequest show() rejects if doc is not fully active</title>
+<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+setup({
+  explicit_done: true,
+  explicit_timeout: true,
+});
+
+const applePay = Object.freeze({
+  supportedMethods: "https://apple.com/apple-pay",
+  data: {
+    version: 3,
+    merchantIdentifier: "merchant.com.example",
+    countryCode: "US",
+    merchantCapabilities: ["supports3DS"],
+    supportedNetworks: ["visa"],
+  }
+});
+const validMethod = Object.freeze({
+  supportedMethods: "basic-card",
+});
+const validMethods = Object.freeze([validMethod, applePay]);
+
+const validDetails = Object.freeze({
+  total: {
+    label: "Total due",
+      amount: {
+      currency: "USD",
+      value: "5.00",
+    },
+  },
+});
+
+function getLoadedPaymentRequest(iframe, url) {
+  return new Promise(resolve => {
+    iframe.addEventListener(
+      "load",
+      () => {
+        const { PaymentRequest } = iframe.contentWindow;
+        const request = new PaymentRequest(validMethods, validDetails);
+        resolve(request);
+      },
+      { once: true }
+    );
+    iframe.src = url;
+  });
+}
+
+function testAbortShowIfDocumentIsNotActive() {
+  promise_test(async t => {
+    const iframe = document.createElement("iframe");
+    iframe.allowPaymentRequest = true;
+    document.body.appendChild(iframe);
+    // We first got to page1.html, grab a PaymentRequest instance.
+    const request1 = await getLoadedPaymentRequest(
+      iframe,
+      "/payment-request/resources/page1.html"
+    );
+    // We navigate the iframe again, putting request1's document into an inactive state.
+    const request2 = await getLoadedPaymentRequest(
+      iframe,
+      "/payment-request/resources/page2.html"
+    );
+    // Now, request1's relevant global object's document is no longer active.
+    // So, call .show(), and make sure it rejects appropriately.
+    await promise_rejects(
+      t,
+      "AbortError",
+      request1.show(),
+      "Inactive document, so must throw AbortError"
+    );
+    // request2 has an active document tho, so confirm it's working as expected:
+    request2.show();
+    await request2.abort();
+    await promise_rejects(
+      t,
+      "InvalidStateError",
+      request2.show(),
+      "Abort already called, so InvalidStateError"
+    );
+    // We are done, so clean up.
+    iframe.remove();
+  }, "PaymentRequest.show() aborts if the document is not active.");
+}
+
+function testAbortShowIfDocumentIsNotFullyActive() {
+  promise_test(async t => {
+    // We nest two iframes and wait for them to load.
+    const outerIframe = document.createElement("iframe");
+    outerIframe.allowPaymentRequest = true;
+    document.body.appendChild(outerIframe);
+    // Load the outer iframe (we don't care about the awaited request)
+    await getLoadedPaymentRequest(
+      outerIframe,
+      "/payment-request/resources/page1.html"
+    );
+
+    // Now we create the inner iframe
+    const innerIframe = outerIframe.contentDocument.createElement("iframe");
+    innerIframe.allowPaymentRequest = true;
+
+    // nest them
+    outerIframe.contentDocument.body.appendChild(innerIframe);
+
+    // load innerIframe, and get the PaymentRequest instance
+    const request = await getLoadedPaymentRequest(
+      innerIframe,
+      "/payment-request/resources/page2.html"
+    );
+
+    // Navigate the outer iframe to a new location.
+    // Wait for the load event to fire.
+    await new Promise(resolve => {
+      outerIframe.addEventListener("load", resolve);
+      outerIframe.src = "/payment-request/resources/page2.html";
+    });
+
+    const showPromise = request.show();
+    // Now, request's relevant global object's document is still active
+    // (it is the active document of the inner iframe), but is not fully active
+    // (since the parent of the inner iframe is itself no longer active).
+    // So, call request.show() and make sure it rejects appropriately.
+    await promise_rejects(
+      t,
+      "AbortError",
+      showPromise,
+      "Active, but not fully active, so must throw AbortError"
+    );
+    // We are done, so clean up.
+
+    outerIframe.remove();
+  }, "PaymentRequest.show() aborts if the document is active, but not fully active.");
+}
+</script>
+
+<h2>PaymentRequest show() rejects if doc is not fully active</h2>
+<p>
+  Click on each button in sequence from top to bottom without refreshing the
+  page. Each button will bring up the Payment Request UI window and then will
+  close it automatically. (If a payment sheet stays open, the test has failed.)
+</p>
+<ol>
+  <li>
+    <button onclick="testAbortShowIfDocumentIsNotActive()">
+      PaymentRequest.show() aborts if the document is not active.
+    </button>
+  </li>
+  <li>
+    <button onclick="testAbortShowIfDocumentIsNotFullyActive()">
+      PaymentRequest.show() aborts if the document is active, but not fully
+      active.
+    </button>
+  </li>
+  <li><button onclick="done()">Done!</button></li>
+</ol>
+<small>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
+  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
+</small>