<!DOCTYPE html> <meta charset="utf-8" />
<title>Test for PaymentRequest.show(optional promise) method</title>
<link
  rel="help"
  href="https://w3c.github.io/browser-payment-api/#dfn-payment-request-is-showing"
/>
<meta name="timeout" content="long" />
<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>
<body>
  <script>
    "use strict";
    const applePayMethod = {
      supportedMethods: "https://apple.com/apple-pay",
      data: {
        version: 3,
        merchantIdentifier: "merchant.com.example",
        countryCode: "US",
        merchantCapabilities: ["supports3DS"],
        supportedNetworks: ["visa"],
      },
    };
    const methods = [{ supportedMethods: "basic-card" }, applePayMethod];
    const details = {
      total: {
        label: "Total",
        amount: {
          currency: "USD",
          value: "1.00",
        },
      },
    };

    /**
     * Attaches an iframe to window.document.
     *
     * @param {String} src Optional resource URL to load.
     * @returns {Promise} Resolves when the src loads.
     */
    async function attachIframe(src = "blank.html") {
      const iframe = document.createElement("iframe");
      iframe.allow = "payment";
      iframe.src = src;
      document.body.appendChild(iframe);
      await new Promise((resolve) => {
        iframe.addEventListener("load", resolve, { once: true });
      });
      return iframe;
    }

    function getShowPromiseFromContext(paymentRequest, context = this) {
      return test_driver.bless(
        "payment request show()",
        () => {
          return [paymentRequest.show()];
        },
        context
      );
    }

    promise_test(async (t) => {
      const request1 = new PaymentRequest(methods, details);
      const request2 = new PaymentRequest(methods, details);

      // Sets the "payment-relevant browsing context's payment request is
      // showing boolean" to true and then try to show a second payment sheet in
      // the same window. The second show() should reject.
      await test_driver.bless("payment request show()");
      const showPromise1 = request1.show();

      await test_driver.bless("payment request show()");
      const showPromise2 = request2.show();

      await promise_rejects_dom(
        t,
        "AbortError",
        showPromise2,
        "Attempting to show a second payment request must reject."
      );

      await request1.abort();
      await promise_rejects_dom(
        t,
        "AbortError",
        showPromise1,
        "request1 was aborted via .abort()"
      );

      // Finally, request2 should have been "closed", so trying to show
      // it will again result in promise rejected with an InvalidStateError.
      // See: https://github.com/w3c/payment-request/pull/821
      const rejectedPromise = request2.show();
      await promise_rejects_dom(
        t,
        "InvalidStateError",
        rejectedPromise,
        "Attempting to show a second payment request must reject."
      );
      // Finally, we confirm that request2's returned promises are unique.
      assert_not_equals(
        showPromise2,
        rejectedPromise,
        "Returned Promises be unique"
      );
    }, "The top browsing context can only show one payment sheet at a time.");

    promise_test(async (t) => {
      const iframe = await attachIframe();
      const iframeWindow = iframe.contentWindow;

      // Payment requests
      const windowRequest = new window.PaymentRequest(methods, details);
      const iframeRequest = new iframeWindow.PaymentRequest(methods, details);

      // Let's get some blessed showPromises
      // iframe sets "is showing boolean", ignore the returned promise.
      const [iframePromise] = await getShowPromiseFromContext(
        iframeRequest,
        iframeWindow
      );

      // The top level window now tries to show() the payment request.
      await test_driver.bless("payment request show()");
      const showPromise = windowRequest.show();

      await promise_rejects_dom(
        t,
        "AbortError",
        showPromise,
        "iframe is already showing a payment request."
      );

      // Cleanup
      await iframeRequest.abort();
      iframe.remove();
    }, "If an iframe shows a payment request, the top-level browsing context can't also show one.");

    promise_test(async (t) => {
      const iframe = await attachIframe();
      const iframeWindow = iframe.contentWindow;
      const iframeRequest = new iframeWindow.PaymentRequest(methods, details);
      const [iframeShowPromise] = await getShowPromiseFromContext(
        iframeRequest,
        iframeWindow
      );

      // We navigate away, causing the payment sheet to close
      // and the request is showing boolean to become false.
      await new Promise((resolve) => {
        iframe.onload = resolve;
        iframe.src = "blank.html?test=123";
      });

      iframe.remove();

      // Now we should be ok to spin up a new payment request
      const request = new window.PaymentRequest(methods, details);
      const [showPromise] = await getShowPromiseFromContext(request);
      await request.abort();
      await promise_rejects_dom(
        t,
        "AbortError",
        showPromise,
        "Normal abort."
      );
    }, "Navigating an iframe as a nested browsing context sets 'payment request is showing boolean' to false.");
  </script>
</body>
