| <!DOCTYPE html> | |
| <meta charset=utf-8> | |
| <link rel="help" href="https://w3c.github.io/payment-request/#retry-method"> | |
| <title>PaymentResponse retry() rejects if doc is not fully active</title> | |
| <script src="/js-test-resources/ui-helper.js"></script> | |
| <script src="/resources/payment-request.js"></script> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-retry"> | |
| <body> | |
| <script> | |
| setup({ explicit_done: true, explicit_timeout: true }); | |
| const validMethods = Object.freeze([validPaymentMethod()]); | |
| const validAmount = Object.freeze({ | |
| currency: "USD", | |
| value: "5.00", | |
| }); | |
| const validTotal = Object.freeze({ | |
| label: "Total due", | |
| amount: validAmount, | |
| }); | |
| const validDetails = Object.freeze({ | |
| total: validTotal, | |
| }); | |
| function getLoadedPaymentResponse(iframe, url) { | |
| return new Promise(resolve => { | |
| iframe.addEventListener( | |
| "load", | |
| () => { | |
| const { PaymentRequest } = iframe.contentWindow; | |
| activateThen(async () => { | |
| const request = new PaymentRequest(validMethods, validDetails); | |
| const acceptPromise = request.show(); | |
| internals.mockPaymentCoordinator.acceptPayment(); | |
| const response = await acceptPromise; | |
| resolve(response); | |
| }); | |
| }, | |
| { once: true } | |
| ); | |
| iframe.src = url; | |
| }); | |
| } | |
| function methodNotFullyActive(text, methodName, ...args) { | |
| promise_test(async t => { | |
| const iframe = document.createElement("iframe"); | |
| iframe.allowPaymentRequest = true; | |
| document.body.appendChild(iframe); | |
| // We first got to page1.html, grab a PaymentResponse instance. | |
| const response = await getLoadedPaymentResponse( | |
| iframe, | |
| "/payment-request/resources/page1.html" | |
| ); | |
| const iframeDOMException = iframe.contentWindow.DOMException; | |
| // We navigate the iframe again, putting response's document into an inactive state. | |
| await new Promise(resolve => { | |
| iframe.addEventListener("load", resolve); | |
| iframe.src = "/payment-request/resources/page2.html"; | |
| }); | |
| // Now, response's relevant global object's document is no longer active. | |
| // So, promise needs to reject appropriately. | |
| const promise = response[methodName](...args); | |
| await promise_rejects_dom( | |
| t, | |
| "InvalidStateError", | |
| iframeDOMException, | |
| promise, | |
| "Inactive document, so must throw InvalidStateError" | |
| ); | |
| // We are done, so clean up. | |
| iframe.remove(); | |
| }, text); | |
| } | |
| function methodBecomesNotFullyActive(text, methodName, ...args) { | |
| promise_test(async t => { | |
| const iframe = document.createElement("iframe"); | |
| iframe.allowPaymentRequest = true; | |
| document.body.appendChild(iframe); | |
| // We first got to page1.html, grab a PaymentResponse instance. | |
| const response = await getLoadedPaymentResponse( | |
| iframe, | |
| "/payment-request/resources/page1.html" | |
| ); | |
| const iframeDOMException = iframe.contentWindow.DOMException; | |
| // we get the promise from page1.html, while it's active! | |
| const promise = response[methodName](...args); | |
| // We navigate the iframe again, putting response's document into an inactive state. | |
| await new Promise(resolve => { | |
| iframe.addEventListener("load", resolve); | |
| iframe.src = "/payment-request/resources/page2.html"; | |
| }); | |
| // Now, response's relevant global object's document is no longer active. | |
| // So, promise needs to reject appropriately. | |
| await promise_rejects_dom( | |
| t, | |
| "AbortError", | |
| iframeDOMException, | |
| promise, | |
| "Document became inactive, so must throw AbortError" | |
| ); | |
| // We are done, so clean up. | |
| iframe.remove(); | |
| }, text); | |
| } | |
| window.addEventListener("load", async () => { | |
| await methodNotFullyActive("retry()'s retryPromise rejects if document is not fully active.", 'retry', {}); | |
| await methodBecomesNotFullyActive("retry()'s retryPromise rejects if the document becomes not fully active.", 'retry', {}); | |
| await methodNotFullyActive("complete()'s completePromise rejects if document is not fully active.", 'complete', 'success'); | |
| done(); | |
| }); | |
| </script> |