PaymentRequest show() rejects if doc is not fully active
-
-
-
-
-
-
-
PaymentRequest show() rejects if doc is not fully active
-
- 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.)
-
-
-
-
-
-
-
-
-
-
-
- If you find a buggy test, please file a bug
- and tag one of the suggested reviewers.
-
diff --git a/payment-request/rejects_if_not_active.https.html b/payment-request/rejects_if_not_active.https.html
index 84f299db9be1da..32feccb2655f34 100644
--- a/payment-request/rejects_if_not_active.https.html
+++ b/payment-request/rejects_if_not_active.https.html
@@ -7,83 +7,136 @@
-
+ // We navigate the iframe again, putting request1's document into an non-fully active state.
+ const request2 = await getLoadedPaymentRequest(
+ iframe,
+ "./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_dom(
+ t,
+ "AbortError",
+ frameDOMException1,
+ request1.show(),
+ "Inactive document, so must throw AbortError"
+ );
+ // request2 has an active document tho, so confirm it's working as expected:
+ // Get transient activation
+ await test_driver.bless("payment 2", () => {}, iframe.contentWindow);
+ request2.show();
+ await request2.abort();
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ iframe.contentWindow.DOMException,
+ request2.show(),
+ "Abort already called, so InvalidStateError"
+ );
+ }, "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.allow = "payment";
+ document.body.appendChild(outerIframe);
+ t.add_cleanup(() => {
+ outerIframe.remove();
+ });
+ // Load the outer iframe (we don't care about the awaited request)
+ await getLoadedPaymentRequest(outerIframe, "./resources/page1.html");
+
+ // Now we create the inner iframe
+ const innerIframe = outerIframe.contentDocument.createElement("iframe");
+ innerIframe.allow = "payment";
+
+ // nest them
+ outerIframe.contentDocument.body.appendChild(innerIframe);
+
+ // load innerIframe, and get the PaymentRequest instance
+ const request = await getLoadedPaymentRequest(
+ innerIframe,
+ "./resources/page2.html"
+ );
+ // Save DOMException from innerIframe before navigating away.
+ const innerIframeDOMException = innerIframe.contentWindow.DOMException;
+
+ // 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 = "./resources/page2.html";
+ });
+
+ await test_driver.bless("", () => {}, innerIframe.contentWindow);
+ 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_dom(
+ t,
+ "AbortError",
+ innerIframeDOMException,
+ showPromise,
+ "Active, but not fully active, so must throw AbortError"
+ );
+ }, "PaymentRequest.show() aborts if the document is active, but not fully active.");
+