| <!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/#show-method"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script> |
| "use strict"; |
| setup({ |
| allow_uncaught_exception: true, |
| explicit_done: true, |
| explicit_timeout: true, |
| }); |
| |
| // DATA USED BY TESTS |
| // PaymentMethods |
| const validMethods = Object.freeze([ |
| { |
| supportedMethods: "valid-but-wont-ever-match", |
| }, |
| { |
| supportedMethods: "basic-card", |
| }, |
| { |
| supportedMethods: "https://apple.com/apple-pay", |
| }, |
| ]); |
| |
| // Amounts |
| const failAmount = Object.freeze({ |
| currency: "USD", |
| value: "1.00", |
| }); |
| const passAmount = Object.freeze({ |
| currency: "CAD", |
| value: "50.00", |
| }); |
| const neutralAmount = Object.freeze({ |
| currency: "AUD", |
| value: "0.00", |
| }); |
| |
| // Labels |
| const failLabel = "💥 TEST HAS FAILED 💥"; |
| const passLabel = "✅ TEST HAS PASSED ✅"; |
| const neutralLabel = "Ignore this label"; |
| // Totals |
| const failTotal = Object.freeze({ |
| label: failLabel, |
| amount: failAmount, |
| }); |
| const passTotal = Object.freeze({ |
| label: passLabel, |
| amount: passAmount, |
| }); |
| const neutralTotal = Object.freeze({ |
| label: neutralLabel, |
| amount: passAmount, |
| }); |
| |
| // PaymentItem |
| const failPaymentItem = Object.freeze({ |
| amount: failAmount, |
| label: failLabel, |
| }); |
| const failPaymentItems = Object.freeze([failPaymentItem]); |
| |
| const passPaymentItem = Object.freeze({ |
| amount: passAmount, |
| label: passLabel, |
| }); |
| const passPaymentItems = Object.freeze([passPaymentItem]); |
| |
| // PaymentShippingOptions |
| const failShippingOption = Object.freeze({ |
| id: "fail", |
| label: failLabel, |
| amount: failAmount, |
| }); |
| const failShippingOptions = Object.freeze([failShippingOption]); |
| |
| const neutralShippingOption = Object.freeze({ |
| id: "neutral", |
| label: neutralLabel, |
| amount: neutralAmount, |
| }); |
| |
| const updatedShippingOption1 = Object.freeze({ |
| id: "updated-1", |
| label: `${passLabel} - option 1`, |
| amount: passAmount, |
| }); |
| const updatedShippingOption2 = Object.freeze({ |
| id: "updated-2", |
| label: `${passLabel} - option 2 (MUST BE SELECTED!)`, |
| amount: passAmount, |
| selected: true, |
| }); |
| const passShippingOptions = Object.freeze([ |
| updatedShippingOption1, |
| updatedShippingOption2, |
| ]); |
| |
| // Modifiers |
| // create a modifier objects for each validMethods |
| // and single additional display item |
| const failModifiers = validMethods.map(modifier => { |
| const label = `${failLabel} - (${modifier.supportedMethods})`; |
| return { |
| ...modifier, |
| total: { |
| ...failTotal, |
| label, |
| }, |
| additionalDisplayItems: [ |
| { |
| ...failPaymentItem, |
| label, |
| }, |
| ], |
| }; |
| }); |
| // Updates the total for each, and changes the additionalDisplayItems |
| const passModifiers = failModifiers.map(modifier => { |
| const label = `${passLabel} - (${modifier.supportedMethods})`; |
| return { |
| ...modifier, |
| total: { |
| ...passTotal, |
| label, |
| }, |
| additionalDisplayItems: [ |
| { |
| ...passPaymentItem, |
| label, |
| }, |
| ], |
| }; |
| }); |
| |
| // PaymentDetailsInit |
| const failDetails = Object.freeze({ |
| displayItems: failPaymentItems, |
| id: "this cannot be changed", |
| modifiers: failModifiers, |
| shippingOptions: failShippingOptions, |
| total: failTotal, |
| }); |
| |
| const neutralDetails = Object.freeze({ |
| displayItems: [], |
| modifiers: [], |
| shippingOptions: [neutralShippingOption], |
| total: neutralTotal, |
| }); |
| |
| function smokeTest() { |
| promise_test(async t => { |
| const request = new PaymentRequest(validMethods, failDetails); |
| await promise_rejects( |
| t, |
| new TypeError(), |
| request.show({ |
| total: "This throws a TypeError", |
| }), |
| "expected TypeError" |
| ); |
| }, "smoke test - checks if the optional details are supported on show() method"); |
| } |
| |
| function runUpdateDetailsAlgorithm( |
| buttonElement, |
| details, |
| options = { |
| requestShipping: true, |
| } |
| ) { |
| const testAssertion = buttonElement.textContent.trim(); |
| buttonElement.disabled = true; |
| promise_test(async t => { |
| const request = new PaymentRequest(validMethods, failDetails, options); |
| const detailsPromise = Promise.resolve(details); |
| const acceptPromise = request.show(detailsPromise); |
| assert_equals(request.id, "this cannot be changed", "id must never change."); |
| await promise_rejects( |
| t, |
| "AbortError", |
| acceptPromise, |
| "expected AbortError" |
| ); |
| }, testAssertion); |
| } |
| </script> |
| <h2> |
| PaymentRequest <code>.show(optional detailsPromise)</code> tests |
| </h2> |
| <p> |
| These test cause <code>detailsPromise</code> to resolve successfully with some updated value. As such, that will cause |
| something in the payment sheet to change. Each test describes what is expected to change - if anything. |
| </p> |
| <p> |
| <strong>Instructions:</strong> Click on each button in sequence from top to bottom without refreshing the page. The payment |
| sheet will be shown. If required, confirm that the expected value appears in the payment sheet. Finally, manually abort/cancel |
| the payment request by closing the payment sheet. |
| </p> |
| <ol> |
| <li><button onclick="smokeTest()">If the payment sheet is shown, the test has failed.</button></li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| id: 'fail', |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, the provided `id` must have no effect on the payment request. |
| </button></li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| total: passTotal |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, the total must be CAD$50 with the label "✅ TEST HAS PASSED ✅". |
| </button></li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| displayItems: passPaymentItems, |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, there must be a one display item with a value of CAD$50 with the label "✅ TEST HAS PASSED ✅". |
| </button> |
| </li> |
| <li><button onclick=" |
| const auItem = { |
| ...passPaymentItem, |
| amount: { value: '40', currency: 'AUD'}, |
| pending: true |
| } |
| const details = { |
| ...neutralDetails, |
| displayItems: passPaymentItems.concat(auItem), |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, there must be |
| two display items: One with a value of CAD$50, another with |
| value AUD$40 that is pending. |
| </button> |
| </li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| shippingOptions: [updatedShippingOption1], |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, there must be a one shipping option |
| with a value of CAD$50. |
| </button> |
| </li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| shippingOptions: passShippingOptions, |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, there must be |
| two shipping options: One with a value of CAD$50, another with |
| value AUD$40 that is selected. |
| </button> |
| </li> |
| <li><button onclick=" |
| const details = { |
| ...neutralDetails, |
| modifiers: passModifiers, |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, the total should be CAD$50. |
| </button> |
| </li> |
| <li> |
| <button onclick=" |
| const details = { |
| ...neutralDetails, |
| shippingOptions: [], |
| error: passLabel, |
| }; |
| runUpdateDetailsAlgorithm(this, details); |
| "> |
| When the payment sheet is shown, the string "✅ TEST HAS PASSED ✅" should be shown |
| somewhere in the user interface. Alternatively, the payment sheet must indicate to the |
| end user that it's not possible to ship their order. |
| </button> |
| </li> |
| <li> |
| <button onclick=" |
| const details = { |
| ...neutralDetails, |
| error: failLabel, |
| }; |
| runUpdateDetailsAlgorithm(this, details, {requestShipping: false}); |
| "> |
| When the payment sheet is shown, there should not be any errors shown. |
| </button> |
| </li> |
| <li> |
| <button onclick="done();">Done!</button> |
| </li> |
| </ol> |
| |
| <small> |
| If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> |
| and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. |
| </small> |