setup({ explicit_done: true, explicit_timeout: true }); const applePay = Object.freeze({ supportedMethods: "https://apple.com/apple-pay", data: { version: 3, merchantIdentifier: "merchant.com.example", countryCode: "US", merchantCapabilities: ["supports3DS"], supportedNetworks: ["visa"], } }); const validMethod = Object.freeze({ supportedMethods: "basic-card", }); const validMethods = Object.freeze([validMethod, applePay]); const validAmount = Object.freeze({ currency: "USD", value: "1.00", }); const validTotal = Object.freeze({ label: "Valid total", amount: validAmount, }); const validDetails = { total: validTotal, }; test(() => { try { new PaymentRequest(validMethods, validDetails); } catch (err) { done(); throw err; } }, "Can construct a payment request (smoke test)."); /** * Pops up a payment sheet, allowing options to be * passed in if particular values are needed. * * @param PaymentOptions options */ async function getPaymentResponse(options, id) { const { response } = await getPaymentRequestResponse(options, id); return response; } /** * Creates a payment request and response pair. * It also shows the payment sheet. * * @param {PaymentOptions?} options * @param {String?} id */ async function getPaymentRequestResponse(options, id) { const methods = [{ supportedMethods: "basic-card" }]; const details = { id, total: { label: "Total due", amount: { currency: "USD", value: "1.0" }, }, shippingOptions: [ { id: "fail1", label: "Fail option 1", amount: { currency: "USD", value: "5.00" }, selected: false, }, { id: "pass", label: "Pass option", amount: { currency: "USD", value: "5.00" }, selected: true, }, { id: "fail2", label: "Fail option 2", amount: { currency: "USD", value: "5.00" }, selected: false, }, ], }; const request = new PaymentRequest(methods, details, options); request.onshippingaddresschange = ev => ev.updateWith(details); request.onshippingoptionchange = ev => ev.updateWith(details); const response = await request.show(); return { request, response }; } /** * Runs a manual test for payment * * @param {HTMLButtonElement} button The HTML button. * @param {PaymentOptions?} options. * @param {Object} expected What property values are expected to pass the test. * @param {String?} id And id for the request/response pair. */ async function runManualTest(button, options, expected = {}, id = undefined) { button.disabled = true; const { request, response } = await getPaymentRequestResponse(options, id); await response.complete(); test(() => { assert_idl_attribute( response, "requestId", "Expected requestId to be an IDL attribute." ); assert_equals(response.requestId, request.id, `Expected ids to match`); for (const [attribute, value] of Object.entries(expected)) { assert_idl_attribute( response, attribute, `Expected ${attribute} to be an IDL attribute.` ); assert_equals( response[attribute], value, `Expected response ${attribute} attribute to be ${value}` ); } assert_idl_attribute(response, "details"); assert_equals(typeof response.details, "object", "Expected an object"); // Testing that this does not throw: response.toJSON(); if (options && options.requestShipping) { assert_equals( response.shippingOption, "pass", "request.shippingOption must be 'pass'" ); } else { assert_equals( request.shippingOption, null, "If requestShipping is falsy, request.shippingOption must be null" ); assert_equals( response.shippingOption, null, "request.shippingOption must be null" ); } }, button.textContent.trim()); }