diff --git a/.github/workflows/run-automation-test.yml b/.github/workflows/run-automation-test.yml index 2577b0900..1fa7b5fc0 100644 --- a/.github/workflows/run-automation-test.yml +++ b/.github/workflows/run-automation-test.yml @@ -57,4 +57,7 @@ jobs: uses: cypress-io/github-action@v6 with: working-directory: ./cypress-tests + env: + CYPRESS_HYPERSWITCH_PUBLISHABLE_KEY: $HS_Pub_Key + CYPRESS_HYPERSWITCH_SECRET_KEY: $HS_Sec_Key # Runs Cypress tests located in the specified directory diff --git a/Hyperswitch-React-Demo-App/src/Payment.js b/Hyperswitch-React-Demo-App/src/Payment.js index b7710ec25..20414a048 100644 --- a/Hyperswitch-React-Demo-App/src/Payment.js +++ b/Hyperswitch-React-Demo-App/src/Payment.js @@ -8,31 +8,44 @@ function Payment() { const [hyperPromise, setHyperPromise] = useState(null); const [clientSecret, setClientSecret] = useState(""); - useEffect(() => { - const fetchData = async () => { - try { - const url = SELF_SERVER_URL === "" ? ENDPOINT : SELF_SERVER_URL; + const queryParams = new URLSearchParams(window.location.search); + const isCypressTestMode = queryParams.get("isCypressTestMode"); + const publishableKeyQueryParam = queryParams.get("publishableKey"); + const clientSecretQueryParam = queryParams.get("clientSecret"); + const url = SELF_SERVER_URL === "" ? ENDPOINT : SELF_SERVER_URL; + + const getPaymentData = async () => { + try { + const [configResponse, urlsResponse] = await Promise.all([ + fetch(`${url}/config`), + fetch(`${url}/urls`), + ]); + + const paymentIntentResponse = isCypressTestMode + ? { clientSecret: clientSecretQueryParam } + : await fetch(`${url}/create-payment-intent`).then((res) => res.json()); - const [configResponse, urlsResponse, paymentIntentResponse] = - await Promise.all([ - fetch(`${url}/config`), - fetch(`${url}/urls`), - fetch(`${url}/create-payment-intent`), - ]); + if (!configResponse.ok || !urlsResponse.ok) { + throw new Error("Network response was not ok"); + } + + const paymentDataArray = await Promise.all([ + configResponse.json(), + urlsResponse.json(), + ]); - if ( - !configResponse.ok || - !urlsResponse.ok || - !paymentIntentResponse.ok - ) { - throw new Error("Network response was not ok"); - } + return [...paymentDataArray, paymentIntentResponse]; + } catch (error) { + console.error("Error fetching data:", error); + } + }; - const [configData, urlsData, paymentIntentData] = await Promise.all([ - configResponse.json(), - urlsResponse.json(), - paymentIntentResponse.json(), - ]); + useEffect(() => { + const fetchData = async () => { + try { + const [configData, urlsData, paymentIntentData] = await getPaymentData( + url + ); const { publishableKey } = configData; const { serverUrl, clientUrl } = urlsData; @@ -45,9 +58,12 @@ function Payment() { setHyperPromise( new Promise((resolve) => { resolve( - window.Hyper(publishableKey, { - customBackendUrl: serverUrl, - }) + window.Hyper( + isCypressTestMode ? publishableKeyQueryParam : publishableKey, + { + customBackendUrl: serverUrl, + } + ) ); }) ); @@ -81,7 +97,9 @@ function Payment() { { - let getIframeBody : () => Cypress.Chainable>; + + const publishableKey = Cypress.env('HYPERSWITCH_PUBLISHABLE_KEY') + const secretKey = Cypress.env('HYPERSWITCH_SECRET_KEY') + let getIframeBody: () => Cypress.Chainable>; let iframeSelector = - "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + + // changeObjectKeyValue(createPaymentBody,"profile_id","YOUR_PROFILE_ID") + + beforeEach(() => { getIframeBody = () => cy.iframe(iframeSelector); + cy.createPaymentIntent(secretKey, createPaymentBody).then(() => { + cy.getGlobalState("clientSecret").then((clientSecret) => { - cy.visit(CLIENT_URL); - }); + cy.visit(getClientURL(clientSecret, publishableKey)); + }); - it("page loaded successfully", () => { - cy.visit(CLIENT_URL); + }) }); + it("title rendered correctly", () => { cy.contains("Hyperswitch Unified Checkout").should("be.visible"); }); @@ -30,18 +41,16 @@ describe("Card payment flow test", () => { it('should check if cards are saved', () => { // Visit the page where the test will be performed - cy.visit(CLIENT_URL); - getIframeBody().find(`[data-testid=${testIds.addNewCardIcon}]`) - .then($element => { - if ($element.length > 0) { - getIframeBody().find('[data-testid=cvvInput]').type('123'); - getIframeBody().get("#submit").click(); - cy.wait(2000); - cy.contains("Thanks for your order!").should("be.visible"); - } else { - cy.log(' new card card flow'); - } - }); + .then($element => { + if ($element.length > 0) { + getIframeBody().find('[data-testid=cvvInput]').type('123'); + getIframeBody().get("#submit").click(); + cy.wait(2000); + cy.contains("Thanks for your order!").should("be.visible"); + } else { + cy.log(' new card card flow'); + } + }); }); }); diff --git a/cypress-tests/cypress/support/commands.ts b/cypress-tests/cypress/support/commands.ts index 1dbfe8435..5a3fe36e2 100644 --- a/cypress-tests/cypress/support/commands.ts +++ b/cypress-tests/cypress/support/commands.ts @@ -24,9 +24,10 @@ // -- This will overwrite an existing command -- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) import "cypress-iframe"; +import { createPaymentBody } from "./utils" import * as testIds from "../../../src/Utilities/TestUtils.bs"; // commands.js or your custom support file -const iframeSelector = +const iframeSelector = "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; let globalState = {}; @@ -73,11 +74,11 @@ Cypress.Commands.add( mapping[testIds.cardNoInputTestId] = customerData.threeDSCardNo; } let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; - let clientSecret:string; + let clientSecret: string; cy.request({ method: "GET", url: "http://localhost:5252/create-payment-intent", - }).then((response: {body: { clientSecret: string }}) => { + }).then((response: { body: { clientSecret: string } }) => { clientSecret = response.body.clientSecret; cy.request({ @@ -145,27 +146,8 @@ Cypress.Commands.add( } ); -const request = { - currency: "USD", - amount: 6500, - authentication_type: "three_ds", - description: "Joseph First Crypto", - email: "hyperswitch_sdk_demo_id@gmail.com", - connector_metadata: { - noon: { - order_category: "applepay", - }, - }, - metadata: { - udf1: "value1", - new_customer: "true", - login_date: "2019-09-10T10:11:12Z", - }, - // customer_id: "hyperswitch_sdk_demo_test_id", - business_country: "US", - business_label: "default", -}; -Cypress.Commands.add("createPaymentIntent", () => { + +Cypress.Commands.add("createPaymentIntent", (secretKey: string, createPaymentBody: any) => { return cy .request({ method: "POST", @@ -173,9 +155,9 @@ Cypress.Commands.add("createPaymentIntent", () => { headers: { "Content-Type": "application/json", Accept: "application/json", - "api-key": "snd_c691ade6995743bd88c166ba509ff5da", + "api-key": secretKey, }, - body: JSON.stringify(request), + body: JSON.stringify(createPaymentBody), }) .then((response) => { expect(response.headers["content-type"]).to.include("application/json"); @@ -188,6 +170,6 @@ Cypress.Commands.add("createPaymentIntent", () => { }); }); -Cypress.Commands.add("getGlobalState", (key: number) => { +Cypress.Commands.add("getGlobalState", (key: any) => { return globalState[key]; }); diff --git a/cypress-tests/cypress/support/types.ts b/cypress-tests/cypress/support/types.ts index 20953bc94..d1db388d1 100644 --- a/cypress-tests/cypress/support/types.ts +++ b/cypress-tests/cypress/support/types.ts @@ -1,5 +1,5 @@ -export {}; // indicate that file is a module +export { }; // indicate that file is a module export type CustomerData = { cardNo: string @@ -24,8 +24,8 @@ declare global { testDynamicFields( customerData: CustomerData, testIdsToRemoveArr: string[], isThreeDSEnabled: boolean ): Chainable> - createPaymentIntent(): Chainable> - getGlobalState(key: number): Chainable> + createPaymentIntent(secretKey: string, createPaymentBody: Record): Chainable> + getGlobalState(key: string): Chainable> } } } \ No newline at end of file diff --git a/cypress-tests/cypress/support/utils.ts b/cypress-tests/cypress/support/utils.ts index b6b28900d..ae0982a52 100644 --- a/cypress-tests/cypress/support/utils.ts +++ b/cypress-tests/cypress/support/utils.ts @@ -1,14 +1,44 @@ -export const CLIENT_URL = "http://localhost:9060" +export const CLIENT_BASE_URL = "http://localhost:9060" -export const request = { + + +export const getClientURL = (clientSecret, publishableKey) => { + return `${CLIENT_BASE_URL}?isCypressTestMode=true&clientSecret=${clientSecret}&publishableKey=${publishableKey}`; +} + + +export const createPaymentBody = { currency: "USD", - amount: 6500, + amount: 2999, + order_details: [ + { + product_name: "Apple iPhone 15", + quantity: 1, + amount: 2999, + }, + ], + confirm: false, + capture_method: "automatic", authentication_type: "three_ds", - description: "Joseph First Crypto", + customer_id: "hyperswitch_sdk_demo_id", email: "hyperswitch_sdk_demo_id@gmail.com", - connector_metadata: { - noon: { - order_category: "applepay", + request_external_three_ds_authentication: false, + description: "Hello this is description", + shipping: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "US", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "8056594427", + country_code: "+91", }, }, metadata: { @@ -16,10 +46,31 @@ export const request = { new_customer: "true", login_date: "2019-09-10T10:11:12Z", }, - // customer_id: "hyperswitch_sdk_demo_test_id", - business_country: "US", - business_label: "default", -}; + profile_id: "pro_xsQ7wTCP89OLqmWNcnRq", + billing: { + email: "hyperswitch_sdk_demo_id@gmail.com", + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "US", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "8056594427", + country_code: "+91", + }, + }, + +} + +export const changeObjectKeyValue = (object: Record, key: string, value: string) => { + object[key] = value +} export const confirmBody = { client_secret: "", diff --git a/cypress-tests/readme.md b/cypress-tests/readme.md index 7360cf74e..f565602ab 100644 --- a/cypress-tests/readme.md +++ b/cypress-tests/readme.md @@ -11,6 +11,8 @@ Steps to get started with Hyperswitch-web sdk testing locally: 3. Cypress should open the window to test separate flows. +4. To run cypress in headless mode, put publishable key and secret key to be used for tests in `cypress.env.json` and then spin a terminal window and run `npm run test` + 💡 Note: Incase you are setting cypress for the first time and run into a cypress error, try to uninstall and re-install cypress inside cypress-tests folder by running the following commands : ```