From 8372389671c4aefeb625365d198390df5d8f35a5 Mon Sep 17 00:00:00 2001 From: Kashif Date: Wed, 30 Oct 2024 12:57:22 +0530 Subject: [PATCH] feat(cypress-test): include worldpay's request / response structure for test suite (#6420) --- .../e2e/PaymentTest/00006-VoidPayment.cy.js | 4 +- .../e2e/PaymentTest/00013-SaveCardFlow.cy.js | 9 +- .../e2e/PaymentTest/00020-Variations.cy.js | 22 +- .../cypress/e2e/PaymentUtils/Commons.js | 21 + .../cypress/e2e/PaymentUtils/Paybox.js | 23 - .../cypress/e2e/PaymentUtils/Utils.js | 7 + .../cypress/e2e/PaymentUtils/WorldPay.js | 436 ++++++++++++++++++ .../fixtures/create-connector-body.json | 3 +- .../cypress/support/redirectionHandler.js | 14 +- 9 files changed, 499 insertions(+), 40 deletions(-) create mode 100644 cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js diff --git a/cypress-tests/cypress/e2e/PaymentTest/00006-VoidPayment.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00006-VoidPayment.cy.js index 9735a74adfd..c783f5e3d72 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00006-VoidPayment.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00006-VoidPayment.cy.js @@ -67,7 +67,7 @@ describe("Card - NoThreeDS Manual payment flow test", () => { it("void-call-test", () => { let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Void" + "VoidAfterConfirm" ]; let req_data = data["Request"]; let res_data = data["Response"]; @@ -178,7 +178,7 @@ describe("Card - NoThreeDS Manual payment flow test", () => { it("void-call-test", () => { let data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" - ]["Void"]; + ]["VoidAfterConfirm"]; let req_data = data["Request"]; let res_data = data["Response"]; cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00013-SaveCardFlow.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00013-SaveCardFlow.cy.js index 6e9289d4d0b..e74c8fc9dd4 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00013-SaveCardFlow.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00013-SaveCardFlow.cy.js @@ -46,8 +46,13 @@ describe("Card - SaveCard payment flow test", () => { "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (should_continue) { + // Don't continue if payment status is processing during auto capture + // Payment data is tokenized only after payment is successful + let notProcessing = res_data?.body?.status != "processing"; + should_continue = + notProcessing && utils.should_continue_further(res_data); + } }); it("retrieve-payment-call-test", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00020-Variations.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00020-Variations.cy.js index a00a2e39f95..b24b9f10f79 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00020-Variations.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00020-Variations.cy.js @@ -331,7 +331,7 @@ describe("Corner cases", () => { }); it("Capture call", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "CaptureCapturedAmount" ]; @@ -396,7 +396,7 @@ describe("Corner cases", () => { }); it("Confirm call", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "ConfirmSuccessfulPayment" ]; let req_data = data["Request"]; @@ -460,12 +460,12 @@ describe("Corner cases", () => { }); it("Void call", () => { - // `commons` here is intentionally used as we need to pass `ResponseCustom` - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "Void" ]; + let commonData = getConnectorDetails(globalState.get("commons"))["card_pm"]["Void"]; let req_data = data["Request"]; - let res_data = data["ResponseCustom"]; + let res_data = utils.getConnectorFlowDetails(data, commonData, "ResponseCustom"); cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); if (should_continue) @@ -592,12 +592,12 @@ describe("Corner cases", () => { }); it("Refund call", () => { - // `commons` here is intentionally used as we need to pass `ResponseCustom` - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "Refund" ]; + let commonData = getConnectorDetails(globalState.get("commons"))["card_pm"]["Refund"]; let req_data = data["Request"]; - let res_data = data["ResponseCustom"]; + let res_data = utils.getConnectorFlowDetails(data, commonData, "ResponseCustom"); cy.refundCallTest( fixtures.refundBody, req_data, @@ -655,12 +655,12 @@ describe("Corner cases", () => { }); it("Refund call", () => { - // `commons` here is intentionally used as we need to pass `ResponseCustom` - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "Refund" ]; + let commonData = getConnectorDetails(globalState.get("commons"))["card_pm"]["Refund"]; let req_data = data["Request"]; - let res_data = data["ResponseCustom"]; + let res_data = utils.getConnectorFlowDetails(data, commonData, "ResponseCustom"); cy.refundCallTest( fixtures.refundBody, req_data, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js b/cypress-tests/cypress/e2e/PaymentUtils/Commons.js index 73e54fee916..01905ee0532 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Commons.js @@ -666,6 +666,27 @@ export const connectorDetails = { }, }, }), + VoidAfterConfirm: getCustomExchange({ + Request: {}, + Response: { + status: 200, + body: { + status: "cancelled", + capture_method: "manual", + }, + }, + ResponseCustom: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "You cannot cancel this payment because it has status succeeded", + code: "IR_16", + }, + }, + }, + }), Refund: getCustomExchange({ Request: { payment_method: "card", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js b/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js index 8fbb8c0b07b..b0550854ef8 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js @@ -401,29 +401,6 @@ export const connectorDetails = { }, }, }, - CaptureCapturedAmount: { - Request: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "EUR", - customer_acceptance: null, - }, - }, - Response: { - status: 400, - body: { - error: { - type: "invalid_request", - message: - "This Payment could not be captured because it has a payment.status of succeeded. The expected state is requires_capture, partially_captured_and_capturable, processing", - code: "IR_14", - }, - }, - }, - }, ConfirmSuccessfulPayment: { Request: { payment_method: "card", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js b/cypress-tests/cypress/e2e/PaymentUtils/Utils.js index 18f4df3eb57..8848450bc61 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Utils.js @@ -19,6 +19,7 @@ import { connectorDetails as stripeConnectorDetails } from "./Stripe.js"; import { connectorDetails as trustpayConnectorDetails } from "./Trustpay.js"; import { connectorDetails as wellsfargoConnectorDetails } from "./WellsFargo.js"; import { connectorDetails as fiuuConnectorDetails } from "./Fiuu.js"; +import { connectorDetails as worldpayConnectorDetails } from "./WorldPay.js"; const connectorDetails = { adyen: adyenConnectorDetails, @@ -39,6 +40,7 @@ const connectorDetails = { datatrans: datatransConnectorDetails, wellsfargo: wellsfargoConnectorDetails, fiuu: fiuuConnectorDetails, + worldpay: worldpayConnectorDetails, }; export default function getConnectorDetails(connectorId) { @@ -46,6 +48,11 @@ export default function getConnectorDetails(connectorId) { return x; } +export function getConnectorFlowDetails(connectorData, commonData, key) { + let data = connectorData[key] === undefined ? commonData[key] : connectorData[key]; + return data; +} + function mergeDetails(connectorId) { const connectorData = getValueByKey(connectorDetails, connectorId); const fallbackData = getValueByKey(connectorDetails, "commons"); diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js new file mode 100644 index 00000000000..70ed4fefa6c --- /dev/null +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -0,0 +1,436 @@ + +const billing = { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "CA", + zip: "94122", + country: "US", + first_name: "John", + last_name: "Doe" + } +}; + +const browser_info = { + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", + "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "language": "nl-NL", + "color_depth": 24, + "screen_height": 723, + "screen_width": 1536, + "time_zone": 0, + "java_enabled": true, + "java_script_enabled": true, + "ip_address": "127.0.0.1" +}; + +const successfulNo3DSCardDetails = { + card_number: "4242424242424242", + card_exp_month: "10", + card_exp_year: "2030", + card_holder_name: "morino", + card_cvc: "737", +}; + +const successfulThreeDSTestCardDetails = { + card_number: "4000000000001091", + card_exp_month: "10", + card_exp_year: "2030", + card_holder_name: "morino", + card_cvc: "737", +}; + +const payment_method_data_no3ds = { + card: { + last4: "4242", + card_type: "CREDIT", + card_network: "Visa", + card_issuer: "STRIPE PAYMENTS UK LIMITED", + card_issuing_country: "UNITEDKINGDOM", + card_isin: "424242", + card_extended_bin: null, + card_exp_month: "10", + card_exp_year: "2030", + card_holder_name: null, + payment_checks: null, + authentication_data: null + }, + billing: null +}; + +const payment_method_data_3ds = { + card: { + last4: "1091", + card_type: "CREDIT", + card_network: "Visa", + card_issuer: "INTL HDQTRS-CENTER OWNED", + card_issuing_country: "UNITEDSTATES", + card_isin: "400000", + card_extended_bin: null, + card_exp_month: "10", + card_exp_year: "2030", + card_holder_name: null, + payment_checks: null, + authentication_data: null + }, + billing: null +}; + +const singleUseMandateData = { + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, +}; + +export const connectorDetails = { + card_pm: { + PaymentIntent: { + Request: { + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, Response: { + status: 200, + body: { + status: "requires_payment_method", + setup_future_usage: "on_session", + }, + }, + }, + No3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + billing: billing, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + payment_method: "card", + payment_method_type: "debit", + attempt_count: 1, + payment_method_data: payment_method_data_no3ds, + }, + }, + }, + No3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", + payment_method: "card", + payment_method_type: "debit", + attempt_count: 1, + payment_method_data: payment_method_data_no3ds, + }, + }, + }, + Capture: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + }, + }, + }, + PartialCapture: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + }, + }, + }, + Void: { + Request: {}, + Response: { + status: 200, + body: { + status: "cancelled", + }, + }, + ResponseCustom: { + body: { + type: "invalid_request", + message: "You cannot cancel this payment because it has status processing", + code: "IR_16", + } + } + }, + VoidAfterConfirm: { + Request: {}, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + SaveCardUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Missing required param: payment_method_data", + code: "IR_04" + } + }, + }, + }, + SaveCardUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + setup_future_usage: "on_session", + browser_info, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "processing" + }, + } + }, + "3DSManualCapture": { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + browser_info, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + setup_future_usage: "on_session", + payment_method_data: payment_method_data_3ds, + }, + }, + }, + "3DSAutoCapture": { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + browser_info, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + setup_future_usage: "on_session", + payment_method_data: payment_method_data_3ds, + }, + }, + }, + + /** + * Variation cases + */ + CaptureCapturedAmount: { + Request: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + customer_acceptance: null, + }, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be captured because it has a capture_method of automatic. The expected state is manual_multiple", + code: "IR_14", + }, + }, + }, + }, + ConfirmSuccessfulPayment: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "You cannot confirm this payment because it has status processing", + code: "IR_16", + }, + }, + }, + }, + + /** + * Not implemented or not ready for running test cases + * - Refunds + * - Mandates + */ + Refund: { + Request: {}, + Response: { + body: { + error: { + type: "invalid_request", + message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14" + } + } + }, + ResponseCustom: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14", + }, + }, + }, + }, + PartialRefund: { + Request: {}, + Response: { + body: { + error: { + type: "invalid_request", + message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14" + } + } + } + }, + SyncRefund: { + Request: {}, + Response: { + body: { + error: { + type: "invalid_request", + message: "Refund does not exist in our records.", + code: "HE_02" + } + } + } + }, + ZeroAuthMandate: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + body: { + error: { + type: "invalid_request", + message: "Setup Mandate flow for Worldpay is not implemented", + code: "IR_00" + } + }, + }, + }, + }, +} \ No newline at end of file diff --git a/cypress-tests/cypress/fixtures/create-connector-body.json b/cypress-tests/cypress/fixtures/create-connector-body.json index 5e0ce73aedc..54a96d8f6ee 100644 --- a/cypress-tests/cypress/fixtures/create-connector-body.json +++ b/cypress-tests/cypress/fixtures/create-connector-body.json @@ -13,6 +13,7 @@ "metadata": { "city": "NY", "unit": "245", - "endpoint_prefix": "AD" + "endpoint_prefix": "AD", + "merchant_name": "Cypress Test" } } diff --git a/cypress-tests/cypress/support/redirectionHandler.js b/cypress-tests/cypress/support/redirectionHandler.js index b493d11fee8..aa6db7d5074 100644 --- a/cypress-tests/cypress/support/redirectionHandler.js +++ b/cypress-tests/cypress/support/redirectionHandler.js @@ -343,7 +343,19 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { cy.get("#outcomeSelect").select("Approve").should("have.value", "Y"); cy.get('button[type="submit"]').click(); }); - } else { + } else if (connectorId === "worldpay") { + cy.get("iframe", { timeout: WAIT_TIME }) + .its("0.contentDocument.body") + .within(() => { + cy.get('form[name="cardholderInput"]', { timeout: WAIT_TIME }) + .should("exist") + .then(() => { + cy.get('input[name="challengeDataEntry"]').click().type("1234"); + cy.get('input[value="SUBMIT"]').click(); + }) + }); + } + else { // If connectorId is neither of adyen, trustpay, nmi, stripe, bankofamerica or cybersource, wait for 10 seconds cy.wait(WAIT_TIME); }