diff --git a/payment-request/META.yml b/payment-request/META.yml
index 1dbe3e5d7edbe4..3985039a4291da 100644
--- a/payment-request/META.yml
+++ b/payment-request/META.yml
@@ -1,7 +1,5 @@
spec: https://w3c.github.io/payment-request/
suggested_reviewers:
- marcoscaceres
- - rsolomakhin
- - zouhir
- romandev
- - aestes
+ - stephenmcgruer
diff --git a/payment-request/payment-is-showing.https.html b/payment-request/payment-is-showing.https.html
index a30029458f5f2f..c97473cc6f122b 100644
--- a/payment-request/payment-is-showing.https.html
+++ b/payment-request/payment-is-showing.https.html
@@ -91,6 +91,7 @@
// 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
+ await test_driver.bless("payment request show()");
const rejectedPromise = request2.show();
await promise_rejects_dom(
t,
diff --git a/payment-request/payment-response/rejects_if_not_active-manual.https.html b/payment-request/payment-response/rejects_if_not_active-manual.https.html
index 6f2e9e95d41d9f..af33bc0f74fdc7 100644
--- a/payment-request/payment-response/rejects_if_not_active-manual.https.html
+++ b/payment-request/payment-response/rejects_if_not_active-manual.https.html
@@ -52,7 +52,7 @@
});
}
-function methodNotFullyActive(button, method, ...args) {
+function methodNotFullyActive(button, methodName, ...args) {
const text = button.textContent.trim();
promise_test(async t => {
const iframe = document.createElement("iframe");
@@ -74,9 +74,9 @@
const promise = response[methodName](...args);
await promise_rejects_dom(
t,
- "AbortError",
+ "InvalidStateError",
promise,
- "Inactive document, so must throw AbortError"
+ "Inactive document, so must throw InvalidStateError"
);
// We are done, so clean up.
iframe.remove();
@@ -111,7 +111,7 @@
t,
"AbortError",
promise,
- "Inactive document, so must throw AbortError"
+ "Document became inactive, so must throw AbortError"
);
// We are done, so clean up.
iframe.remove();
diff --git a/payment-request/rejects_if_not_active.https.html b/payment-request/rejects_if_not_active.https.html
index 32feccb2655f34..0233aca9d053b6 100644
--- a/payment-request/rejects_if_not_active.https.html
+++ b/payment-request/rejects_if_not_active.https.html
@@ -1,7 +1,8 @@
-
PaymentRequest show() rejects if doc is not fully active
+PaymentRequest methods reject if doc is not fully active
+
@@ -72,16 +73,18 @@
// So, call .show(), and make sure it rejects appropriately.
await promise_rejects_dom(
t,
- "AbortError",
+ "InvalidStateError",
frameDOMException1,
request1.show(),
- "Inactive document, so must throw AbortError"
+ "Inactive document, so must throw InvalidStateError"
);
// 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();
+ // Need another bless() because the previous one was consumed by show()
+ await test_driver.bless("payment 3", () => {}, iframe.contentWindow);
await promise_rejects_dom(
t,
"InvalidStateError",
@@ -132,11 +135,93 @@
// So, call request.show() and make sure it rejects appropriately.
await promise_rejects_dom(
t,
- "AbortError",
+ "InvalidStateError",
innerIframeDOMException,
showPromise,
- "Active, but not fully active, so must throw AbortError"
+ "Active, but not fully active, so must throw InvalidStateError"
);
}, "PaymentRequest.show() aborts if the document is active, but not fully active.");
+
+ promise_test(async (t) => {
+ const iframe = document.createElement("iframe");
+ iframe.allow = "payment";
+ document.body.appendChild(iframe);
+ t.add_cleanup(() => {
+ iframe.remove();
+ });
+ // We first go to page1.html, grab a PaymentRequest instance.
+ const request1 = await getLoadedPaymentRequest(
+ iframe,
+ "./resources/page1.html"
+ );
+ // Save the DOMException of page1.html before navigating away.
+ const frameDOMException1 = iframe.contentWindow.DOMException;
+
+ // 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 .canMakePayment(), and make sure it rejects appropriately.
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ frameDOMException1,
+ request1.canMakePayment(),
+ "Inactive document, so must throw InvalidStateError"
+ );
+ // request2 has an active document, so confirm it's working as expected:
+ const result = await request2.canMakePayment();
+ assert_true(typeof result === "boolean", "canMakePayment() should return a boolean");
+ }, "PaymentRequest.canMakePayment() rejects 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";
+ });
+
+ const canMakePaymentPromise = request.canMakePayment();
+ // 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.canMakePayment() and make sure it rejects appropriately.
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ innerIframeDOMException,
+ canMakePaymentPromise,
+ "Active, but not fully active, so must throw InvalidStateError"
+ );
+ }, "PaymentRequest.canMakePayment() rejects if the document is active, but not fully active.");