<!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"
/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver.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.allowPaymentRequest = true;
      iframe.src = src;
      document.body.appendChild(iframe);
      await new Promise(resolve => {
        iframe.addEventListener('load', resolve, {once: true});
      });
      return iframe;
    }

    /**
     * Creates a popup window. The caller must be triggered with a user gesture.
     *
     * @param {String} src Optional resource URL to load.
     * @returns {Promise} Resolves when the src loads.
     */
    async function loadPopupInsideUserGesture(src = 'blank.html') {
      const popupWindow = window.open(src, '', 'width=400,height=400');
      await new Promise(resolve => {
        popupWindow.addEventListener('load', resolve, {once: true});
      });
      popupWindow.focus();
      return popupWindow;
    }

    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.
      const [showPromise1, showPromise2] = await test_driver.bless(
        'testing one payment sheet per window',
        () => {
          return [request1.show(), request2.show()];
        },
      );
      await promise_rejects(
        t,
        'AbortError',
        showPromise2,
        'Attempting to show a second payment request must reject.',
      );

      await request1.abort();
      await promise_rejects(
        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(
        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 iframeRequest = new iframeWindow.PaymentRequest(methods, details);
      const windowRequest = new window.PaymentRequest(methods, details);

      // Let's get some blessed showPromises
      const [showPromise] = await test_driver.bless(
        'testing top window show() blocked by payment sheet in iframe',
        () => {
          // iframe sets "is showing boolean", ignore the returned promise.
          iframeRequest.show();
          // The top level window now tries to show() the payment request.
          return [windowRequest.show()];
        },
      );

      await promise_rejects(
        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;

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

      // We first show a payment request via the the top level browsing context,
      // windowRequest.show() sets "is showing boolean" to true. Then we try to
      // show a payment request in the iframe, which should reject.
      const [iframeShowPromise] = await test_driver.bless(
        'testing iframe show() blocked by payment sheet in top window',
        () => {
          windowRequest.show();
          return [iframeRequest.show()];
        },
      );

      await promise_rejects(
        t,
        'AbortError',
        iframeShowPromise,
        'The top window is already showing a payment request.',
      );

      // Cleanup
      await windowRequest.abort();
      iframe.remove();
    }, 'An iframe cannot show a payment request if the top-level window is already showing one.');

    promise_test(async t => {
      // Create a PaymentReuqest in top-level window.
      const windowRequest = new window.PaymentRequest(methods, details);

      // Use a single user gesture to open a popup window with a PaymentRequest.
      // Then trigger show() first on |popupRequest| then on |windowRequest|.
      // The latter should reject.
      const [
        popupWindow,
        popupRequest,
        popupShowPromise,
        windowShowPromise,
      ] = await test_driver.bless(
        'testing top-level show() blocked by payment sheet in popup',
        async () => {
          const popupWindow = await loadPopupInsideUserGesture();
          const popupRequest = new popupWindow.PaymentRequest(methods, details);
          const popupShowPromise = popupRequest.show();
          const windowShowPromise = windowRequest.show();
          return [
            popupWindow,
            popupRequest,
            popupShowPromise,
            windowShowPromise,
          ];
        },
      );
      await popupRequest.abort();
      popupWindow.close();

      await promise_rejects(
        t,
        'AbortError',
        windowShowPromise,
        "Expected window's showPromise to reject, request is already showing",
      );
    }, 'Using a popup window prevents the top-browsing context from showing a payment request');

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

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

      // Open a popup window
      const [popupWindow, popupRequest] =
      await test_driver.bless(
        'open popup to test multiple context and window calls show() first',
        async () => {
          const popupWindow = await loadPopupInsideUserGesture();
          const popupRequest = new popupWindow.PaymentRequest(methods, details);
          return [popupWindow, popupRequest];
        },
      );

      // Get the showPromise for each browsing context. Doing this in a separate
      // test_driver.bless() is important because the user gesture brings
      // |window| to the foreground, so that the payment sheet can show.
      const [
        windowShowPromise,
        popupShowPromise,
        iframeShowPromise,
      ] = await test_driver.bless(
        'test multiple nested browsing context',
        () => {
          return [
            windowRequest.show(),
            popupRequest.show(),
            iframeRequest.show(),
          ];
        },
      );
      // popupRequest and iframeRequest will both reject
      await promise_rejects(
        t,
        'AbortError',
        popupShowPromise,
        'Expected popupShowPromise to reject, request is already showing.',
      );

      await promise_rejects(
        t,
        'AbortError',
        iframeShowPromise,
        'Expected iframeShowPromise to reject, request is already showing.',
      );

      await windowRequest.abort();
      popupWindow.close();
      iframe.remove();
    }, "Given multiple nested browsing contexts, and window calls show() first, other nested browsing contexts can't show a request.");

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

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

      // Open a popup window
      const [
        popupWindow,
        popupRequest,
        popupShowPromise,
        windowShowPromise,
        iframeShowPromise
      ] = await test_driver.bless(
        'test multiple browsing context and iframe calls show() first',
        async () => {
          const popupWindow = await loadPopupInsideUserGesture();
          const popupRequest = new popupWindow.PaymentRequest(methods, details);
          const popupShowPromise = popupRequest.show();
          const windowShowPromise = windowRequest.show();
          const iframeShowPromise = iframeRequest.show();
          return [popupWindow,
                  popupRequest,
                  popupShowPromise,
                  windowShowPromise,
                  iframeShowPromise];
      });

      // windowShowPromise and iframeRequest will both reject
      await promise_rejects(
        t,
        'AbortError',
        windowShowPromise,
        'Expected windowShowPromise to reject, the popup is showing a payment request.',
      );

      await promise_rejects(
        t,
        'AbortError',
        iframeShowPromise,
        'Expected iframeShowPromise to reject, the popup is showing a payment request.',
      );

      await popupRequest.abort();
      popupWindow.close();
      iframe.remove();
    }, "Given multiple nested browsing contexts, and popup calls show() first, other nested browsing contexts can't show a request.");

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

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

      const [popupWindow, popupRequest] = await test_driver.bless(
        'open popup to test multiple context and iframe calls show() first',
        async () => {
          const w = await loadPopupInsideUserGesture();
          const r = new w.PaymentRequest(methods, details);
          return [w, r];
        },
      );

      // Get the showPromise for each browsing context. Doing this in a separate
      // test_driver.bless() is important because the user gesture brings
      // |window| to the foreground, so that the payment sheet can show.
      const [
        iframeShowPromise,
        popupShowPromise,
        windowShowPromise,
      ] = await test_driver.bless(
        'test multiple browsing context and iframe calls show() first',
        async () => {
          return [
            iframeRequest.show(),
            popupRequest.show(),
            windowRequest.show(),
          ];
        },
      );

      // windowShowPromise and iframeRequest will both reject
      await promise_rejects(
        t,
        'AbortError',
        windowShowPromise,
        'Expected windowShowPromise to reject, the popup is showing a payment request.',
      );

      await promise_rejects(
        t,
        'AbortError',
        popupShowPromise,
        'Expected popupShowPromise to reject, the popup is showing a payment request.',
      );

      await iframeRequest.abort();
      popupWindow.close();
      iframe.remove();
    }, "Given multiple nested browsing contexts, and an iframe calls show() first, other nested browsing contexts can't show a request.");

    promise_test(async t => {
      const iframe = await attachIframe();
      const iframeWindow = iframe.contentWindow;
      const iframeRequest = new iframeWindow.PaymentRequest(methods, details);
      const iframeShowPromise = test_driver.bless(
        'test navigating iframe after show()',
        () => iframeRequest.show(),
      );

      // We navigate away, causing the payment sheet to close
      // and the request is showing boolean to become false.
      iframe.src = 'blank.html?abc=123';
      await new Promise(resolve => (iframe.onload = resolve));
      await promise_rejects(
        t,
        'AbortError',
        iframeShowPromise,
        'Navigating iframe away must cause the iframeShowPromise to reject.',
      );
      iframe.remove();

      // Now we should be ok to spin up a new payment request
      const request = new window.PaymentRequest(methods, details);
      const showPromise = request.show();
      await request.abort();
    }, "Navigating an iframe as a nested browsing context sets 'payment request is showing boolean' to false.");

    promise_test(async t => {
      const [popupWindow, popupRequest, showPromise] = await test_driver.bless(
        'test navigating popup after show()',
        async () => {
          const popupWindow = await loadPopupInsideUserGesture();
          const popupRequest = new popupWindow.PaymentRequest(methods, details);
          return [popupWindow, popupRequest, popupRequest.show()];
        },
      );

      // We navigate away, causing the payment sheet to close
      // and the request is showing boolean to become false.
      popupWindow.location = 'blank.html?abc=123';
      await new Promise(resolve => (popupWindow.onload = resolve));
      await promise_rejects(
        t,
        'AbortError',
        showPromise,
        'Navigating away must cause the showPromise to reject with an AbortError',
      );
      popupWindow.close();

      // Now we should be ok to spin up a new payment request.
      const request = new window.PaymentRequest(methods, details);
      request.show();
      await request.abort();
    }, "Navigating a popup as a nested browsing context sets 'payment request is showing boolean' to false.");
  </script>
</body>
