| <!doctype html> |
| <meta charset="utf8"> |
| <link rel="help" href="https://w3c.github.io/payment-request/#user-accepts-the-payment-request-algorithm"> |
| <title> |
| User accepts the payment request algorithm |
| </title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script> |
| setup({ explicit_done: true, explicit_timeout: true }); |
| const basicCardMethod = Object.freeze({ |
| supportedMethods: "basic-card", |
| }); |
| const validMethod = Object.freeze({ |
| supportedMethods: "this-is-just-for-testings-will-never-match", |
| }); |
| const methods = Object.freeze([basicCardMethod, validMethod]); |
| const validAmount = Object.freeze({ |
| currency: "USD", |
| value: "5.00", |
| }); |
| const shippingOptions = [ |
| Object.freeze({ |
| id: "option1", |
| label: "Option 1", |
| amount: validAmount, |
| selected: false, |
| }), |
| Object.freeze({ |
| id: "option 2", |
| label: "Option 2", |
| amount: validAmount, |
| selected: true, |
| }), |
| ]; |
| |
| const detailsNoShippingOptions = Object.freeze({ |
| total: { |
| label: "Total due", |
| amount: validAmount, |
| }, |
| }); |
| |
| const detailsWithShippingOptions = Object.assign({}, detailsNoShippingOptions, { |
| shippingOptions, |
| }); |
| |
| const optionsRequestNothing = Object.freeze({ |
| requestShipping: false, |
| requestPayerEmail: false, |
| requestPayerName: false, |
| requestPayerPhone: false, |
| }); |
| |
| const optionsRequestEverything = Object.freeze({ |
| requestShipping: true, |
| requestPayerEmail: true, |
| requestPayerName: true, |
| requestPayerPhone: true, |
| }); |
| |
| test(() => { |
| // smoke test |
| try { |
| new PaymentRequest(methods, detailsNoShippingOptions); |
| } catch (err) { |
| done(); |
| throw err; |
| } |
| }, "Must be able to construct a payment request (smoke test)"); |
| |
| function testAcceptRequestAlgorithm( |
| button, |
| details, |
| options = {}, |
| expectedResponse = {} |
| ) { |
| button.disabled = true; |
| promise_test(async t => { |
| const request = new PaymentRequest(methods, details, options); |
| const response = await request.show(); |
| assert_true( |
| response instanceof PaymentResponse, |
| "Expected an instance of PaymentResponse." |
| ); |
| // Response [[calledComplete]] is false, so this shouldn't throw |
| await response.complete("success"); |
| // For good measure, test that subsequent complete() |
| for (const state of [undefined, "success", "fail", "unknown"]) { |
| await promise_rejects( |
| t, |
| "InvalidStateError", |
| response.complete(state), |
| "Response [[calledComplete]] is true, so InvalidStateError" |
| ); |
| } |
| assert_equals( |
| request.id, |
| response.requestId, |
| "Request and response ids must match." |
| ); |
| assert_true(response.details instanceof Object, "Expected an object"); |
| assert_equals( |
| response.shippingAddress, |
| request.shippingAddress, |
| "Request and response must reference same shippingAddress (or both null)." |
| ); |
| assert_equals( |
| response.shippingOption, |
| request.shippingOption, |
| "Request and response must be the same value (or both null)." |
| ); |
| if (options.requestShipping === true) { |
| assert_true( |
| response.shippingAddress instanceof PaymentAddress, |
| "Expected an instance of PaymentAddress." |
| ); |
| } |
| const expected = { |
| methodName: "basic-card", |
| payerEmail: options.requestPayerEmail |
| ? expectedResponse.payerEmail |
| : null, |
| payerName: options.requestPayerName ? expectedResponse.payerName : null, |
| payerPhone: options.requestPayerPhone |
| ? expectedResponse.payerPhone |
| : null, |
| }; |
| for (const [attr, expectedValue] of Object.entries(expected)) { |
| assert_equals( |
| response[attr], |
| expectedValue, |
| `response.${attr} must be ${expectedValue}` |
| ); |
| } |
| await promise_rejects( |
| t, |
| "InvalidStateError", |
| request.show(), |
| "Request [[state]] is closed, so InvalidStateError" |
| ); |
| }, button.textContent.trim()); |
| } |
| |
| </script> |
| |
| <section> |
| <h2 id="user-accepts-payment-request">User accepts payment request</h2> |
| <p> |
| Click on each button in sequence from top to bottom without refreshing the page. |
| Each button will bring up the Payment Request UI window. |
| </p> |
| <p> |
| When shown the payment sheet, please input a credit card and select Pay. |
| </p> |
| <ol> |
| <li> |
| <button onclick=" |
| const detailsWithId = Object.assign({}, detailsNoShippingOptions, { id: 'pass' }); |
| testAcceptRequestAlgorithm(this, detailsWithId, optionsRequestNothing);"> |
| User accepts payment request, but not shipping is requested. |
| </button> Use any credit card to pay. |
| </li> |
| <li> |
| <button onclick=" |
| const requestShipping = Object.assign({}, optionsRequestNothing, {requestShipping: true}); |
| const expectedValues = { shippingOption: 'option 2' }; |
| testAcceptRequestAlgorithm(this, detailsWithShippingOptions, requestShipping, expectedValues);"> |
| User accepts payment request, merchant requests shipping. |
| </button> Select any shipping option, and use any credit card to pay. |
| </li> |
| <li> |
| <button onclick=" |
| const requestPayerEmail = Object.assign({}, optionsRequestNothing, {requestPayerEmail: true}); |
| const expectValues = { payerEmail: 'wpt@w3.org' }; |
| testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerEmail, expectValues);"> |
| User accepts payment request, merchant requests email. |
| </button> |
| When prompted, please use "wpt@w3.org" as the email. |
| </li> |
| <li> |
| <button onclick=" |
| const requestPayerPhone = Object.assign({}, optionsRequestNothing, {requestPayerPhone: true}); |
| const expectValues = { payerPhone: '+12345678910' }; |
| testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerPhone, expectValues);"> |
| User accepts payment request, merchant requests phone. |
| </button> |
| When prompted, please use "+12345678910" as the phone number. |
| </li> |
| <li> |
| <button onclick=" |
| const requestPayerName = Object.assign({}, optionsRequestNothing, {requestPayerName: true}); |
| const expectValues = { payerName: 'web platform test' }; |
| testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerName, expectValues);"> |
| User accepts payment request, merchant requests payer's name. |
| </button> |
| When prompted, please use "web platform test" as the payer name. |
| </li> |
| <li> |
| <button onclick=" |
| const expectValues = { |
| payerEmail: 'wpt@w3.org', |
| payerName: 'web platform test', |
| payerPhone: '+12345678910', |
| shippingOption: 'option 2', |
| }; |
| testAcceptRequestAlgorithm(this, detailsWithShippingOptions, optionsRequestEverything, expectValues);"> |
| User accepts payment request, merchant requests everything. |
| </button> |
| When prompted, please use: "+12345678910" as the phone number, "web platform test" as the payer name, and "wpt@w3.org" as the email. Then press Pay. |
| </li> |
| <li> |
| <button onclick="done()">Done</button> |
| </li> |
| </ol> |
| </section> |
| <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> |