diff --git a/.github/workflows/pr-label-removal.yml b/.github/workflows/pr-label-removal.yml index f2f53e41f..969d3e358 100644 --- a/.github/workflows/pr-label-removal.yml +++ b/.github/workflows/pr-label-removal.yml @@ -13,29 +13,16 @@ jobs: - name: Check out code uses: actions/checkout@v2 - - name: Get existing labels + - name: Remove all labels run: | PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH") - TOKEN=$GITHUB_TOKEN - # Add your repository name if it's not the default branch - REPO_NAME=$(basename $GITHUB_REPOSITORY) - - # Get existing labels on the PR - EXISTING_LABELS=$(curl -s -H "Authorization: Bearer ${{ secrets.AUTORELEASE_PAT }}" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER" \ - | jq -r '.labels | map(.name) | join(" ")') - - echo $EXISTING_LABELS - - # Remove existing labels - for LABEL in $EXISTING_LABELS; do - curl -X DELETE \ - -H 'Accept: application/vnd.github.v3+json' \ - -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \ - "https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/labels/${LABEL}" - done + curl -L \ + -X DELETE \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/labels - name: Add new label run: | diff --git a/.github/workflows/run-automation-test.yml b/.github/workflows/run-automation-test.yml new file mode 100644 index 000000000..2577b0900 --- /dev/null +++ b/.github/workflows/run-automation-test.yml @@ -0,0 +1,60 @@ +name: Run Cypress Tests + +on: + pull_request: + merge_group: + push: + branches: + - main + +jobs: + cypress: + runs-on: ubuntu-latest + environment: Testing + env: + HS_Pub_Key: ${{ secrets.HYPERSWITCH_PUBLISHABLE_KEY }} + HS_Sec_Key: ${{ secrets.HYPERSWITCH_SECRET_KEY }} + HS_Prof_Id: ${{ secrets.PROFILE_ID }} + HS_Server_Url: "https://sandbox.hyperswitch.io" + HS_Client_Url: "http://localhost:9050" + # Environment variables for Hyperswitch credentials and URLs + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + # Checks out the repository so that the workflow can access the code + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" # Specifies the version of Node.js to use + cache: "npm" # Caches npm dependencies to speed up subsequent installs + + - name: Install dependencies + run: npm install + # Installs the necessary npm dependencies for the project + + - name: Create .env file + working-directory: ./Hyperswitch-React-Demo-App + run: | + touch .env + echo STATIC_DIR = ./dist >> .env + echo HYPERSWITCH_PUBLISHABLE_KEY = $HS_Pub_Key >> .env + echo HYPERSWITCH_SECRET_KEY = $HS_Sec_Key >> .env + echo PROFILE_ID = $HS_Prof_Id >> .env + echo HYPERSWITCH_SERVER_URL = $HS_Server_Url >> .env + echo HYPERSWITCH_CLIENT_URL = $HS_Client_Url >> .env + # Creates a .env file with environment variables needed for the application + + - name: Build and start local server + run: | + npm run re:build && npm start & + echo "Hyperswitch Web started" && cd Hyperswitch-React-Demo-App && npm start & + echo "Demo App started" + # Builds the project and starts both the Hyperswitch Web and Demo App servers in the background + + - name: Run Cypress + uses: cypress-io/github-action@v6 + with: + working-directory: ./cypress-tests + # Runs Cypress tests located in the specified directory diff --git a/.gitignore b/.gitignore index 80407f77b..9064f17d8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ public/app.css /dist/ **/*.bs.js .github/CODEOWNERS +screenshots +!cypress-tests/package-lock.json # yarn .pnp.* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 23fd35f0e..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 55e34a9b3..6dfb0978d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +## [0.84.1](https://github.com/juspay/hyperswitch-web/compare/v0.84.0...v0.84.1) (2024-08-13) + + +### Bug Fixes + +* john doe name added ([b46dce2](https://github.com/juspay/hyperswitch-web/commit/b46dce2102ba99d83e4a367f82660e0c61d01f02)) + +# [0.84.0](https://github.com/juspay/hyperswitch-web/compare/v0.83.0...v0.84.0) (2024-08-12) + + +### Features + +* Web Automation Testing Setup ([#556](https://github.com/juspay/hyperswitch-web/issues/556)) ([0a03fcb](https://github.com/juspay/hyperswitch-web/commit/0a03fcbfd31993f54688e1db4443cb7d2fe21ace)) + +# [0.83.0](https://github.com/juspay/hyperswitch-web/compare/v0.82.3...v0.83.0) (2024-08-12) + + +### Features + +* dockerize the hyperswitch-web ([#555](https://github.com/juspay/hyperswitch-web/issues/555)) ([e7588f3](https://github.com/juspay/hyperswitch-web/commit/e7588f3243dddba56d938b93545c19095ae45077)) + ## [0.82.3](https://github.com/juspay/hyperswitch-web/compare/v0.82.2...v0.82.3) (2024-08-12) ## [0.82.2](https://github.com/juspay/hyperswitch-web/compare/v0.82.1...v0.82.2) (2024-08-09) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..25ca7ffde --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM node:20-alpine + +# Set the working directory +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json to install dependencies +COPY package*.json ./ + +# Install dependencies +RUN npm install --ignore-scripts + +# Copy the rest of the application code +COPY . . + +# Build the rescript code +RUN npm run re:build + +# Build the application +RUN npm run build + +# Expose the port that the Webpack dev server will run on +EXPOSE 9050 + +# Start the Webpack dev server +CMD ["npm", "run", "start"] diff --git a/Hyperswitch-React-Demo-App/.env b/Hyperswitch-React-Demo-App/.env index 22dbd4bfb..d2fead8d2 100644 --- a/Hyperswitch-React-Demo-App/.env +++ b/Hyperswitch-React-Demo-App/.env @@ -4,4 +4,4 @@ HYPERSWITCH_SECRET_KEY= HYPERSWITCH_SERVER_URL= HYPERSWITCH_CLIENT_URL= SELF_SERVER_URL= - +PROFILE_ID="" diff --git a/Hyperswitch-React-Demo-App/server.js b/Hyperswitch-React-Demo-App/server.js index b19c6f74d..13cd945c2 100644 --- a/Hyperswitch-React-Demo-App/server.js +++ b/Hyperswitch-React-Demo-App/server.js @@ -39,63 +39,70 @@ app.get("/urls", (req, res) => { }); }); -function createPaymentRequest() { - return { - currency: "USD", - amount: 2999, - order_details: [ - { - product_name: "Apple iPhone 15", - quantity: 1, - amount: 2999, - }, - ], - confirm: false, - capture_method: "automatic", - authentication_type: "three_ds", - customer_id: "hyperswitch_sdk_demo_id", - email: "hyperswitch_sdk_demo_id@gmail.com", - 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", - }, +const paymentData = { + currency: "USD", + amount: 2999, + order_details: [ + { + product_name: "Apple iPhone 15", + quantity: 1, + amount: 2999, }, - metadata: { - udf1: "value1", - new_customer: "true", - login_date: "2019-09-10T10:11:12Z", + ], + confirm: false, + capture_method: "automatic", + authentication_type: "three_ds", + customer_id: "hyperswitch_sdk_demo_id", + email: "hyperswitch_sdk_demo_id@gmail.com", + 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", }, - billing: { - 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", - }, + phone: { + number: "8056594427", + country_code: "+91", + }, + }, + metadata: { + udf1: "value1", + new_customer: "true", + login_date: "2019-09-10T10:11:12Z", + }, + billing: { + 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", + }, + }, +} + +const profileId = process.env.PROFILE_ID; +if(profileId) { + paymentData.profile_id = profileId; +} + +function createPaymentRequest() { + return paymentData; } app.get("/create-payment-intent", async (_, res) => { diff --git a/cypress-tests/.env b/cypress-tests/.env new file mode 100644 index 000000000..e69de29bb diff --git a/cypress-tests/cypress.config.js b/cypress-tests/cypress.config.js new file mode 100644 index 000000000..f59b43758 --- /dev/null +++ b/cypress-tests/cypress.config.js @@ -0,0 +1,10 @@ +const { defineConfig } = require("cypress"); + +module.exports = defineConfig({ + projectId: "6r9ayw", + chromeWebSecurity: false, + e2e: { + baseUrl: "http://localhost:9050", + }, + retries: { runMode: 1, openMode: 1 }, +}); \ No newline at end of file diff --git a/cypress-tests/cypress/e2e/card-flow-e2e-test.cy.ts b/cypress-tests/cypress/e2e/card-flow-e2e-test.cy.ts new file mode 100644 index 000000000..add9fa9b8 --- /dev/null +++ b/cypress-tests/cypress/e2e/card-flow-e2e-test.cy.ts @@ -0,0 +1,47 @@ +import * as testIds from "../../../src/Utilities/TestUtils.bs"; +import { CLIENT_URL } from "../support/utils"; + +describe("Card payment flow test", () => { + let getIframeBody : () => Cypress.Chainable>; + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + beforeEach(() => { + getIframeBody = () => cy.iframe(iframeSelector); + + cy.visit(CLIENT_URL); + }); + + it("page loaded successfully", () => { + cy.visit(CLIENT_URL); + }); + + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + + 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'); + } + }); + }); +}); diff --git a/cypress-tests/cypress/fixtures/paymentMethods.json b/cypress-tests/cypress/fixtures/paymentMethods.json new file mode 100644 index 000000000..4a7cfecd2 --- /dev/null +++ b/cypress-tests/cypress/fixtures/paymentMethods.json @@ -0,0 +1,9 @@ +{ + "card":"Card", + "klarna":"Klarna", + "affirm":"Affirm", + "aliPay":"Ali Pay", + "weChatPay":"WeChat" + + } + \ No newline at end of file diff --git a/cypress-tests/cypress/fixtures/testCustomer.json b/cypress-tests/cypress/fixtures/testCustomer.json new file mode 100644 index 000000000..cf05ec5d2 --- /dev/null +++ b/cypress-tests/cypress/fixtures/testCustomer.json @@ -0,0 +1,15 @@ +{ + "cardNo": "4242 4242 4242 4242", + "threeDSCardNo": "4000000000003220", + "cardExpiry": "04/24", + "cardCVV": "424", + "billingName": "John Doe", + "cardHolderName": "John Doe", + "email": "arun@gmail.com", + "address": "123 Main Street Apt 4B", + "city": "New York", + "country": "United States", + "state": "New York", + "postalCode": "10001", + "paymentSuccessfulText": "Payment successful" +} diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/affirm-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/affirm-flow-e2e-test.cy.js new file mode 100644 index 000000000..7367283f6 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/affirm-flow-e2e-test.cy.js @@ -0,0 +1,53 @@ +import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("affirm payment flow test", () => { + let customerData; + let paymentMethodsData; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.wrap( + Cypress.automation("remote:debugger:protocol", { + command: "Network.clearBrowserCache", + }) + ); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + cy.fixture("paymentMethods").then((paymentMethods) => { + paymentMethodsData = paymentMethods; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + it("affirm payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + + cy.frameLoaded(iframeSelector); + cy.wait(2000); + + cy.iframe(iframeSelector) + .find(`[data-testid=${testIds.paymentMethodListTestId}]`) + .should("be.visible") + .contains(paymentMethodsData.affirm) + .click(); + + cy.get("#submit").click(); + + cy.url().should("include", "sandbox.hyperswitch"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/alipay-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/alipay-flow-e2e-test.cy.js new file mode 100644 index 000000000..cf0c86560 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/alipay-flow-e2e-test.cy.js @@ -0,0 +1,50 @@ +import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("Ali Pay payment flow test", () => { + let customerData; + let paymentMethodsData; + beforeEach(() => { + // cy.visit("http://localhost:9060", { cache: false }); + cy.visit("http://localhost:9060"); + + cy.wrap( + Cypress.automation("remote:debugger:protocol", { + command: "Network.clearBrowserCache", + }) + ); + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + cy.fixture("paymentMethods").then((paymentMethods) => { + paymentMethodsData = paymentMethods; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + it("ali pay payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + cy.frameLoaded(iframeSelector); + cy.wait(2000); + cy.iframe(iframeSelector) + .find(`[data-testid=${testIds.paymentMethodDropDownTestId}]`) + .should("be.visible") + .select(paymentMethodsData.aliPay); + + cy.get("#submit").click(); + + cy.url().should("include", "sandbox.hyperswitch"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/api-call-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/api-call-test.cy.js new file mode 100644 index 000000000..595e83785 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/api-call-test.cy.js @@ -0,0 +1,140 @@ +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", +}; + +const stripeTestCard = "4000000000003220"; +const adyenTestCard = "4917610000000000"; +const bluesnapTestCard = "4000000000001091"; + +const confirmBody = { + client_secret: "", + return_url: "http://localhost:9060/completion", + payment_method: "card", + payment_method_data: { + card: { + card_number: "4000000000001091", + card_exp_month: "01", + card_exp_year: "28", + card_holder_name: "", + card_cvc: "424", + card_issuer: "", + card_network: "Visa", + }, + }, + billing: { + address: { + state: "New York", + city: "New York", + country: "US", + first_name: "John", + last_name: "Doe", + zip: "10001", + line1: "123 Main Street Apt 4B", + }, + }, + email: "hyperswitch_sdk_demo_id@gmail.com", + browser_info: { + user_agent: + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + accept_header: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + language: "en-US", + color_depth: 30, + screen_height: 1117, + screen_width: 1728, + time_zone: -330, + java_enabled: true, + java_script_enabled: true, + }, +}; + +let clientSecret; +let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; +describe("Card payment flow test", () => { + // it("fethcing cl", () => { + // cy.createPaymentIntent(); + // }); + // it("kaam chalu", () => { + // const k = cy.getGlobalState("clientSecret"); + // cy.log(k); + // }); + it("create-payment-intent-call-test", () => { + cy.request({ + method: "POST", + url: "https://sandbox.hyperswitch.io/payments", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": "snd_c691ade6995743bd88c166ba509ff5da", + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("client_secret"); + clientSecret = response.body.client_secret; + cy.log(clientSecret); + cy.log(response); + }); + }); + + it("payment_methods-call-test", () => { + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("redirect_url"); + expect(response.body).to.have.property("payment_methods"); + + console.log("cl-------------->" + clientSecret); + cy.log(response); + }); + }); + + it("confirm-call-test", () => { + let paymentIntentID = clientSecret.split("_secret_")[0]; + confirmBody["client_secret"] = clientSecret; + console.log("paymentIntentID--------->" + paymentIntentID); + cy.request({ + method: "POST", + url: `https://sandbox.hyperswitch.io/payments/${paymentIntentID}/confirm`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: confirmBody, + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("next_action"); + // expect(response.body).to.have.property("redirect_to_url"); + + // clientSecret = response.body.client_secret; + + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + cy.visit(nextActionUrl); + }); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/bluesnap-3DS-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/bluesnap-3DS-test.cy.js new file mode 100644 index 000000000..f3785d88b --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/bluesnap-3DS-test.cy.js @@ -0,0 +1,141 @@ +//pay_gpmsaQ9AIL3MH78HN7gJ_secret_xlVSaOqXCtqRy4QjUKpY +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", +}; + +const stripeTestCard = "4000000000003220"; +const adyenTestCard = "4917610000000000"; +const bluesnapTestCard = "4000000000001091"; + +const confirmBody = { + client_secret: "", + return_url: "http://localhost:9060/completion", + payment_method: "card", + payment_method_data: { + card: { + card_number: "4000000000001091", + card_exp_month: "01", + card_exp_year: "28", + card_holder_name: "", + card_cvc: "424", + card_issuer: "", + card_network: "Visa", + }, + }, + billing: { + address: { + state: "New York", + city: "New York", + country: "US", + first_name: "John", + last_name: "Doe", + zip: "10001", + line1: "123 Main Street Apt 4B", + }, + }, + email: "hyperswitch_sdk_demo_id@gmail.com", + browser_info: { + user_agent: + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + accept_header: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + language: "en-US", + color_depth: 30, + screen_height: 1117, + screen_width: 1728, + time_zone: -330, + java_enabled: true, + java_script_enabled: true, + }, +}; + +let clientSecret; +let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; +describe("Card payment flow test", () => { + // it("fethcing cl", () => { + // cy.createPaymentIntent(); + // }); + // it("kaam chalu", () => { + // const k = cy.getGlobalState("clientSecret"); + // cy.log(k); + // }); + it("create-payment-intent-call-test", () => { + cy.request({ + method: "POST", + url: "https://sandbox.hyperswitch.io/payments", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": "snd_c691ade6995743bd88c166ba509ff5da", + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("client_secret"); + clientSecret = response.body.client_secret; + cy.log(clientSecret); + cy.log(response); + }); + }); + + it("payment_methods-call-test", () => { + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("redirect_url"); + expect(response.body).to.have.property("payment_methods"); + + console.log("cl-------------->" + clientSecret); + cy.log(response); + }); + }); + + it("confirm-call-test", () => { + let paymentIntentID = clientSecret.split("_secret_")[0]; + confirmBody["client_secret"] = clientSecret; + console.log("paymentIntentID--------->" + paymentIntentID); + cy.request({ + method: "POST", + url: `https://sandbox.hyperswitch.io/payments/${paymentIntentID}/confirm`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: confirmBody, + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("next_action"); + // expect(response.body).to.have.property("redirect_to_url"); + + // clientSecret = response.body.client_secret; + + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + cy.visit(nextActionUrl); + }); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-3DS-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-3DS-flow-e2e-test.cy.js new file mode 100644 index 000000000..18ba749c8 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-3DS-flow-e2e-test.cy.js @@ -0,0 +1,60 @@ +import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("Card payment flow test", () => { + let customerData; + let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.hardReload(); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + + it("card payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + // cy.wait(1000); + // cy.frameLoaded(iframeSelector); + // cy.wait(1000); + + cy.visit("http://localhost:9060"); + + cy.frameLoaded(iframeSelector); + cy.wait(4000); + + cy.iframe(iframeSelector) + .find(`[data-testid=${testIds.addNewCardIcon}]`) + .should("be.visible") + .click(); + + cy.testDynamicFields(customerData, ["email"], true); + cy.get("#submit").click(); + + // it("orca-payment-element iframe loaded", () => { + // cy.get( + // "#__privateStripeFrame7904" + // ) + // .should("be.visible") + // .its("0.contentDocument") + // .its("body"); + // }); + // cy.contains("Thanks for your order!").should("be.visible"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-backup.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-backup.cy.js new file mode 100644 index 000000000..fcfde2af0 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/card-backup.cy.js @@ -0,0 +1,188 @@ +/*import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("Card payment flow test", () => { + let customerData; + let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.hardReload(); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + + it("card payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + // cy.wait(1000); + // cy.frameLoaded(iframeSelector); + // cy.wait(1000); + + cy.visit("http://localhost:9060"); + // cy.wait(1000); + // cy.frameLoaded(iframeSelector); + cy.wait(5000); + + const myfunc = (id, customerData) => { + switch (id) { + case testIds.cardNoInputTestId: + return customerData.cardNo; + + case testIds.expiryInputTestId: + return customerData.cardExpiry; + + case testIds.cardCVVInputTestId: + return customerData.cardCVV; + + case testIds.fullNameInputTestId: + return customerData.cardHolderName; + + case testIds.emailInputTestId: + return customerData.email; + + case testIds.addressLine1InputTestId: + return customerData.address; + + case testIds.cityInputTestId: + return customerData.city; + case testIds.countryDropDownTestId: + return customerData.country; + case testIds.stateDropDownTestId: + return customerData.state; + + case testIds.postalCodeInputTestId: + return customerData.postalCode; + } + }; + const mapping = { + [testIds.cardNoInputTestId]: customerData.cardNo, + [testIds.expiryInputTestId]: "424", + [testIds.cardCVVInputTestId]: customerData.cardCVV, + [testIds.fullNameInputTestId]: customerData.cardHolderName, + [testIds.cardHolderNameInputTestId]: customerData.cardHolderName, + [testIds.emailInputTestId]: customerData.email, + [testIds.addressLine1InputTestId]: customerData.address, + [testIds.cityInputTestId]: customerData.city, + [testIds.countryDropDownTestId]: customerData.country, + [testIds.stateDropDownTestId]: customerData.state, + [testIds.postalCodeInputTestId]: customerData.postalCode, + }; + + let clientSecret; + cy.request({ + method: "GET", + url: "http://localhost:5252/create-payment-intent", + }).then((response) => { + clientSecret = response.body.clientSecret; + + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, // Replace with your API endpoint + }).then((response) => { + // Check the response status + console.warn(response.body.payment_methods); + + let paymentMethods = response.body.payment_methods; + + const foundElement = paymentMethods.find( + (element) => element.payment_method === "card" + ); + + const ele = foundElement.payment_method_types.find( + (element) => element.payment_method_type === "debit" + ); + console.log(ele.required_fields); + + let requiredFieldsArr = ele.required_fields; + let idArr = []; + for (const key in requiredFieldsArr) { + idArr.push(testIds.fieldTestIdMapping[key]); + } + + const countryIndex = idArr.indexOf("Country"); + const stateIndex = idArr.indexOf("State"); + + // Move "State" after "Country" + if ( + countryIndex !== -1 && + stateIndex !== -1 && + stateIndex < countryIndex + ) { + idArr.splice(stateIndex, 1); + idArr.splice(countryIndex, 0, "State"); + } + + console.warn(idArr); + + expect(response.status).to.eq(200); + + idArr.forEach((ele) => { + // cy.enterValueInIframe(ele, customerData.cardNo); + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .type(mapping[ele]); + + if (ele === "Country" || ele === "State") { + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .select(mapping[ele]); + } + }); + }); + }); + + // cy.enterValueInIframe(testIds.cardNoInputTestId, customerData.cardNo); + // cy.enterValueInIframe(testIds.expiryInputTestId, customerData.cardExpiry); + // cy.enterValueInIframe(testIds.cardCVVInputTestId, customerData.cardCVV); + + // cy.enterValueInIframe( + // testIds.fullNameInputTestId, + // customerData.cardHolderName + // ); + + // cy.enterValueInIframe( + // testIds.cardHolderNameInputTestId, + // customerData.billingName + // ); + // cy.enterValueInIframe(testIds.emailInputTestId, customerData.email); + // cy.enterValueInIframe( + // testIds.addressLine1InputTestId, + // customerData.address + // ); + + // cy.enterValueInIframe(testIds.cityInputTestId, customerData.city); + + // cy.selectValueInIframe(testIds.countryDropDownTestId, customerData.country); + // cy.selectValueInIframe(testIds.stateDropDownTestId, customerData.state); + // cy.enterValueInIframe( + // testIds.postalCodeInputTestId, + // customerData.postalCode + // ); + + cy.get("#submit").click(); + cy.contains("Payment successful").should("be.visible"); + }); +}); +*/ diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/confirm_payload.json b/cypress-tests/cypress/js-e2e-test-cases-to-refer/confirm_payload.json new file mode 100644 index 000000000..7cbc33714 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/confirm_payload.json @@ -0,0 +1,39 @@ +{ + "client_secret": "pay_nTQ5NfqEVxwKC0GNPgE5_secret_00PSTueBCTVNWmJo3hG1", + "return_url": "http://localhost:9060/completion", + "payment_method": "card", + "payment_method_data": { + "card": { + "card_number": "4000000000003220", + "card_exp_month": "04", + "card_exp_year": "2024", + "card_holder_name": "", + "card_cvc": "424", + "card_issuer": "", + "card_network": "Visa" + } + }, + "billing": { + "address": { + "state": "New York", + "city": "New York", + "country": "US", + "first_name": "John", + "last_name": "Doe", + "zip": "10001", + "line1": "123 Main Street Apt 4B" + } + }, + "email": "sa@gmail.com", + "browser_info": { + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "language": "en-US", + "color_depth": 30, + "screen_height": 1117, + "screen_width": 1728, + "time_zone": -330, + "java_enabled": true, + "java_script_enabled": true + } +} diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/klarna-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/klarna-flow-e2e-test.cy.js new file mode 100644 index 000000000..1cca485e1 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/klarna-flow-e2e-test.cy.js @@ -0,0 +1,78 @@ +import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("klarna payment flow test", () => { + let customerData; + let paymentMethodsData; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.wrap( + Cypress.automation("remote:debugger:protocol", { + command: "Network.clearBrowserCache", + }) + ); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + cy.fixture("paymentMethods").then((paymentMethods) => { + paymentMethodsData = paymentMethods; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + it("klarna payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + + cy.reload(true); + cy.frameLoaded(iframeSelector); + cy.wait(2000); + + cy.iframe(iframeSelector) + .find("[data-testid=paymentList]") + .should("be.visible") + .contains(paymentMethodsData.klarna) + .click(); + + const enterValueInIframe = (selector, value) => { + cy.iframe(iframeSelector).find(selector).should("be.visible").type(value); + }; + + const selectValueInIframe = (selector, value) => { + cy.iframe(iframeSelector) + .find(selector) + .should("be.visible") + .select(value); + }; + + enterValueInIframe( + `[data-testid=${testIds.fullNameInputTestId}]`, + customerData.cardHolderName + ); + // enterValueInIframe( + // `[data-testid=${testIds.emailInputTestId}]`, + // customerData.email + // ); + selectValueInIframe( + `[data-testid=${testIds.countryDropDownTestId}]`, + customerData.country + ); + + cy.get("#submit").click(); + + cy.url().should("include", "sandbox.hyperswitch"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-3DS-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-3DS-test.cy.js new file mode 100644 index 000000000..de0c17d8d --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-3DS-test.cy.js @@ -0,0 +1,149 @@ +/* +import * as testIds from "../../src/Utilities/TestUtils.bs"; +describe("Card payment flow test", () => { + let customerData; + let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.hardReload(); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + + it("card payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + // cy.wait(1000); + // cy.frameLoaded(iframeSelector); + // cy.wait(1000); + + cy.visit("http://localhost:9060"); + // cy.wait(1000); + // cy.frameLoaded(iframeSelector); + + // cy.iframe(iframeSelector) + // .find(`[data-testid=${testIds.addNewCardIcon}]`) + // .should("be.visible") + // .click(); + + cy.iframe(iframeSelector) + .find(`[data-testid=card-1]`) + .should("be.visible") + .click(); + + // cy.wait(5000); + + const mapping = { + [testIds.cardNoInputTestId]: customerData.cardNo, + [testIds.expiryInputTestId]: customerData.cardExpiry, + [testIds.cardCVVInputTestId]: customerData.cardCVV, + [testIds.fullNameInputTestId]: customerData.cardHolderName, + [testIds.cardHolderNameInputTestId]: customerData.cardHolderName, + [testIds.emailInputTestId]: customerData.email, + [testIds.addressLine1InputTestId]: customerData.address, + [testIds.cityInputTestId]: customerData.city, + [testIds.countryDropDownTestId]: customerData.country, + [testIds.stateDropDownTestId]: customerData.state, + [testIds.postalCodeInputTestId]: customerData.postalCode, + }; + + let clientSecret; + cy.request({ + method: "GET", + url: "http://localhost:5252/create-payment-intent", + }).then((response) => { + clientSecret = response.body.clientSecret; + + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, // Replace with your API endpoint + }).then((response) => { + // Check the response status + console.warn(response.body.payment_methods); + + let paymentMethods = response.body.payment_methods; + + const foundElement = paymentMethods.find( + (element) => element.payment_method === "card" + ); + + const ele = foundElement.payment_method_types.find( + (element) => element.payment_method_type === "debit" + ); + console.log(ele.required_fields); + + let requiredFieldsArr = ele.required_fields; + let idArr = []; + for (const key in requiredFieldsArr) { + idArr.push(testIds.fieldTestIdMapping[key]); + } + + let stringsToRemove = ["expiryInput", "cardNoInput", "email"]; + idArr = idArr.filter((item) => !stringsToRemove.includes(item)); + const countryIndex = idArr.indexOf("Country"); + const stateIndex = idArr.indexOf("State"); + + // Move "State" after "Country" + if ( + countryIndex !== -1 && + stateIndex !== -1 && + stateIndex < countryIndex + ) { + idArr.splice(stateIndex, 1); + idArr.splice(countryIndex, 0, "State"); + } + + console.warn(idArr); + + expect(response.status).to.eq(200); + + idArr.forEach((ele) => { + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .type(mapping[ele], { force: true }); + + if (ele === "Country" || ele === "State") { + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .select(mapping[ele]); + } + }); + }); + }); + + cy.get("#submit").click(); + // cy.url().should("include", "sandbox.hyperswitch"); + + cy.iframe(`#challengeFrame`) + .find(`id=test-source-authorize-3ds`) + .should("be.visible") + .click(); + cy.wait(20000); + cy.contains("Thanks for your order!").should("be.visible"); + }); +}); +*/ diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-flow-e2e-test.cy.js new file mode 100644 index 000000000..e5015fad4 --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/saved-card-flow-e2e-test.cy.js @@ -0,0 +1,48 @@ +describe("Card Payment Flow Test", () => { + let customerData; + const iframeSelector = "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + const thankYouMessage = "Thanks for your order!"; + + beforeEach(() => { + cy.visit("http://localhost:9060"); + cy.hardReload(); + + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + }); + + it("should load the page successfully", () => { + // Page load is validated by the presence of subsequent elements + cy.url().should('eq', 'http://localhost:9060'); + }); + + it("should render the title correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("should load the Orca payment element iframe", () => { + cy.get(iframeSelector) + .should("be.visible") + .then(iframe => { + // Check iframe content document loaded + cy.wrap(iframe.contents().find('body')).should('be.visible'); + }); + }); + + it("should complete card payment flow successfully", () => { + cy.iframe(iframeSelector) + .find(`[data-testid=${testIds.addNewCardIcon}]`) + .should("be.visible") + .click(); + + // Fill in the card details + cy.testDynamicFields(customerData, ["expiryInput", "cardNoInput", "email"]); + + // Submit the payment form + cy.get("#submit").click(); + + // Validate success message + cy.contains(thankYouMessage).should("be.visible"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/stripe-3DS-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/stripe-3DS-test.cy.js new file mode 100644 index 000000000..21e7fa02c --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/stripe-3DS-test.cy.js @@ -0,0 +1,140 @@ +//pay_gpmsaQ9AIL3MH78HN7gJ_secret_xlVSaOqXCtqRy4QjUKpY +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", +}; + +const stripeTestCard = "4000000000003220"; +const adyenTestCard = "4917610000000000"; +const bluesnapTestCard = "4000000000001091"; + +const confirmBody = { + client_secret: "", + return_url: "http://localhost:9060/completion", + payment_method: "card", + payment_method_data: { + card: { + card_number: stripeTestCard, + card_exp_month: "01", + card_exp_year: "28", + card_holder_name: "", + card_cvc: "424", + card_issuer: "", + card_network: "Visa", + }, + }, + billing: { + address: { + state: "New York", + city: "New York", + country: "US", + first_name: "John", + last_name: "Doe", + zip: "10001", + line1: "123 Main Street Apt 4B", + }, + }, + email: "hyperswitch_sdk_demo_id@gmail.com", + browser_info: { + user_agent: + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + accept_header: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + language: "en-US", + color_depth: 30, + screen_height: 1117, + screen_width: 1728, + time_zone: -330, + java_enabled: true, + java_script_enabled: true, + }, +}; + +let clientSecret; +describe("Card payment flow test", () => { + it("create payment can be written like this", () => { + cy.createPaymentIntent(); + }); + it("Why to do duplicate stuff?", () => { + const k = cy.getGlobalState("clientSecret"); + cy.log(k); + }); + it("create-payment-intent-call-test", () => { + cy.request({ + method: "POST", + url: "https://sandbox.hyperswitch.io/payments", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": "snd_c691ade6995743bd88c166ba509ff5da", + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("client_secret"); + clientSecret = response.body.client_secret; + cy.log(clientSecret); + cy.log(response); + }); + }); + + it("payment_methods-call-test", () => { + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: JSON.stringify(request), + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("redirect_url"); + expect(response.body).to.have.property("payment_methods"); + + console.log("cl-------------->" + clientSecret); + cy.log(response); + }); + }); + + it("confirm-call-test", () => { + let paymentIntentID = clientSecret.split("_secret_")[0]; + confirmBody["client_secret"] = clientSecret; + console.log("paymentIntentID--------->" + paymentIntentID); + cy.request({ + method: "POST", + url: `https://sandbox.hyperswitch.io/payments/${paymentIntentID}/confirm`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, + body: confirmBody, + }).then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("next_action"); + // expect(response.body).to.have.property("redirect_to_url"); + + // clientSecret = response.body.client_secret; + + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + cy.visit(nextActionUrl); + }); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/weChatPay-flow-e2e-test.cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/weChatPay-flow-e2e-test.cy.js new file mode 100644 index 000000000..36250fcbd --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/weChatPay-flow-e2e-test.cy.js @@ -0,0 +1,56 @@ +// NOTE: this test is for we chat QR flow, please ensure we chat is enabled in stripe connector on dashboard +describe("We Chat payment flow test", () => { + let customerData; + let paymentMethodsData; + beforeEach(() => { + cy.visit("http://localhost:9060"); + + cy.wrap( + Cypress.automation("remote:debugger:protocol", { + command: "Network.clearBrowserCache", + }) + ); + cy.fixture("testCustomer").then((customer) => { + customerData = customer; + }); + + cy.fixture("paymentMethods").then((paymentMethods) => { + paymentMethodsData = paymentMethods; + }); + }); + it("page loaded successfully", () => { + cy.visit("http://localhost:9060"); + }); + it("title rendered correctly", () => { + cy.contains("Hyperswitch Unified Checkout").should("be.visible"); + }); + + it("orca-payment-element iframe loaded", () => { + cy.get( + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element" + ) + .should("be.visible") + .its("0.contentDocument") + .its("body"); + }); + it("WeChat pay payment flow successful", () => { + let iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + + cy.frameLoaded(iframeSelector); + cy.wait(2000); + cy.iframe(iframeSelector) + .find("[data-testid=paymentMethodsSelect]") + .should("be.visible") + .select(paymentMethodsData.weChatPay); + + cy.get("#submit").click(); + cy.wait(4000); + + cy.iframe("#orca-fullscreen").contains("QR Code").should("be.visible"); + + cy.iframe("#orca-fullscreen").contains("TEST DATA").should("be.visible"); + + // cy.url().should("include", "sandbox.hyperswitch"); + }); +}); diff --git a/cypress-tests/cypress/js-e2e-test-cases-to-refer/xxx..cy.js b/cypress-tests/cypress/js-e2e-test-cases-to-refer/xxx..cy.js new file mode 100644 index 000000000..d840ea9ee --- /dev/null +++ b/cypress-tests/cypress/js-e2e-test-cases-to-refer/xxx..cy.js @@ -0,0 +1,43 @@ +const enterValueInIframeIfExsist = (selector, value) => { + // cy.iframe(iframeSelector) + // .find(selector) + // .then(($input) => { + // if ($input.length > 0) { + // cy.wrap($input).type(value); + // // You can continue with other actions or assertions here + // } else { + // cy.log( + // `Element with selector ${selector} does not exist in the iframe` + // ); + // // You can choose to take additional actions or assertions here if needed + // } + // }); + // // cy.iframe(iframeSelector).find(selector).should("be.visible").type(value); + + cy.iframe(iframeSelector).find(selector).should("be.visible").type(value); + // cy.on("uncaught:exception", (err, runnable) => { + // // expect(err.message).to.include("something about the error"); + // cy.log("failed------------->"); + // cy.get("#submit").click(); + // done(); + // return false; + // }); + + cy.on("fail", (err, runnable) => { + // expect(err.message).to.include("something about the error"); + console.warn(`here-----?> ${err}`); + cy.iframe(iframeSelector).find("#submit").click(); + console.log("Sanskar"); + return true; + }); + + // cy.iframe(iframeSelector) + // .find(selector) + // .then(($input) => { + // if ($input.length > 0) { + // cy.log("11111"); + // } else { + // cy.log("22222"); + // } + // }); +}; diff --git a/cypress-tests/cypress/support/commands.ts b/cypress-tests/cypress/support/commands.ts new file mode 100644 index 000000000..1dbfe8435 --- /dev/null +++ b/cypress-tests/cypress/support/commands.ts @@ -0,0 +1,193 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +import "cypress-iframe"; +import * as testIds from "../../../src/Utilities/TestUtils.bs"; +// commands.js or your custom support file +const iframeSelector = + "#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"; + +let globalState = {}; + +Cypress.Commands.add("enterValueInIframe", (selector, value) => { + cy.iframe(iframeSelector) + .find(`[data-testid=${selector}]`) + .should("be.visible") + .type(value); +}); + +Cypress.Commands.add("selectValueInIframe", (selector, value) => { + cy.iframe(iframeSelector) + .find(`[data-testid=${selector}]`) + .should("be.visible") + .select(value); +}); + +Cypress.Commands.add("hardReload", () => { + cy.wrap( + Cypress.automation("remote:debugger:protocol", { + command: "Network.clearBrowserCache", + }) + ); +}); + +Cypress.Commands.add( + "testDynamicFields", + (customerData, testIdsToRemoveArr = [], isThreeDSEnabled = false) => { + const mapping = { + [testIds.cardNoInputTestId]: customerData.cardNo, + [testIds.expiryInputTestId]: customerData.cardExpiry, + [testIds.cardCVVInputTestId]: customerData.cardCVV, + [testIds.fullNameInputTestId]: customerData.cardHolderName, + [testIds.cardHolderNameInputTestId]: customerData.cardHolderName, + [testIds.emailInputTestId]: customerData.email, + [testIds.addressLine1InputTestId]: customerData.address, + [testIds.cityInputTestId]: customerData.city, + [testIds.countryDropDownTestId]: customerData.country, + [testIds.stateDropDownTestId]: customerData.state, + [testIds.postalCodeInputTestId]: customerData.postalCode, + }; + if (isThreeDSEnabled) { + mapping[testIds.cardNoInputTestId] = customerData.threeDSCardNo; + } + let publishableKey = "pk_snd_3b33cd9404234113804aa1accaabe22f"; + let clientSecret:string; + cy.request({ + method: "GET", + url: "http://localhost:5252/create-payment-intent", + }).then((response: {body: { clientSecret: string }}) => { + clientSecret = response.body.clientSecret; + + cy.request({ + method: "GET", + url: `https://sandbox.hyperswitch.io/account/payment_methods?client_secret=${clientSecret}`, + headers: { + "Content-Type": "application/json", + "api-key": publishableKey, + }, // Replace with your API endpoint + }).then((response) => { + // Check the response status + console.warn(response.body.payment_methods); + + let paymentMethods = response.body.payment_methods; + + const foundElement = paymentMethods.find( + (element) => element.payment_method === "card" + ); + + const ele = foundElement.payment_method_types.find( + (element) => element.payment_method_type === "debit" + ); + console.log(ele.required_fields); + + let requiredFieldsArr = ele.required_fields; + let idArr = []; + for (const key in requiredFieldsArr) { + idArr.push(testIds.fieldTestIdMapping[key]); + } + + const countryIndex = idArr.indexOf("Country"); + const stateIndex = idArr.indexOf("State"); + + // Move "State" after "Country" + if ( + countryIndex !== -1 && + stateIndex !== -1 && + stateIndex < countryIndex + ) { + idArr.splice(stateIndex, 1); + idArr.splice(countryIndex, 0, "State"); + } + + console.warn(idArr); + + expect(response.status).to.eq(200); + + idArr = idArr.filter((item) => !testIdsToRemoveArr.includes(item)); + + idArr.forEach((ele) => { + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .type(mapping[ele], { force: true }); + + if (ele === "Country" || ele === "State") { + cy.iframe(iframeSelector) + .find(`[data-testid=${ele}]`) + .should("be.visible") + .select(mapping[ele]); + } + }); + }); + }); + } +); + +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", () => { + return cy + .request({ + method: "POST", + url: "https://sandbox.hyperswitch.io/payments", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": "snd_c691ade6995743bd88c166ba509ff5da", + }, + body: JSON.stringify(request), + }) + .then((response) => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("client_secret"); + const clientSecret = response.body.client_secret; + cy.log(clientSecret); + cy.log(response.toString()); + + globalState["clientSecret"] = clientSecret; + }); +}); + +Cypress.Commands.add("getGlobalState", (key: number) => { + return globalState[key]; +}); diff --git a/cypress-tests/cypress/support/e2e.ts b/cypress-tests/cypress/support/e2e.ts new file mode 100644 index 000000000..3a2522438 --- /dev/null +++ b/cypress-tests/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import "./commands"; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/cypress-tests/cypress/support/types.ts b/cypress-tests/cypress/support/types.ts new file mode 100644 index 000000000..20953bc94 --- /dev/null +++ b/cypress-tests/cypress/support/types.ts @@ -0,0 +1,31 @@ + +export {}; // indicate that file is a module + +export type CustomerData = { + cardNo: string + cardExpiry: string + cardCVV: string + cardHolderName: string + email: string + address: string + city: string + country: string + state: string + postalCode: string + threeDSCardNo: string +} + +declare global { + namespace Cypress { + interface Chainable { + enterValueInIframe(selector: string, value: string): Chainable> + selectValueInIframe(selector: string, value: string): Chainable> + hardReload(): Chainable> + testDynamicFields( + customerData: CustomerData, testIdsToRemoveArr: string[], isThreeDSEnabled: boolean + ): Chainable> + createPaymentIntent(): Chainable> + getGlobalState(key: number): Chainable> + } + } +} \ No newline at end of file diff --git a/cypress-tests/cypress/support/utils.ts b/cypress-tests/cypress/support/utils.ts new file mode 100644 index 000000000..b6b28900d --- /dev/null +++ b/cypress-tests/cypress/support/utils.ts @@ -0,0 +1,67 @@ +export const CLIENT_URL = "http://localhost:9060" + +export 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", +}; + +export const confirmBody = { + client_secret: "", + return_url: "http://localhost:9060/completion", + payment_method: "card", + payment_method_data: { + card: { + card_number: "4000000000001091", + card_exp_month: "01", + card_exp_year: "28", + card_holder_name: "", + card_cvc: "424", + card_issuer: "", + card_network: "Visa", + }, + }, + billing: { + address: { + state: "New York", + city: "New York", + country: "US", + first_name: "John", + last_name: "Doe", + zip: "10001", + line1: "123 Main Street Apt 4B", + }, + }, + email: "hyperswitch_sdk_demo_id@gmail.com", + browser_info: { + user_agent: + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + accept_header: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + language: "en-US", + color_depth: 30, + screen_height: 1117, + screen_width: 1728, + time_zone: -330, + java_enabled: true, + java_script_enabled: true, + }, +}; +export const stripeTestCard = "4000000000003220"; +export const adyenTestCard = "4917610000000000"; +export const bluesnapTestCard = "4000000000001091"; diff --git a/cypress-tests/package-lock.json b/cypress-tests/package-lock.json new file mode 100644 index 000000000..81c5f644f --- /dev/null +++ b/cypress-tests/package-lock.json @@ -0,0 +1,1821 @@ +{ + "name": "cypress-tests", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cypress-tests", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "cypress": "^13.13.2", + "cypress-iframe": "^1.0.1", + "typescript": "^5.5.4" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cypress/request": { + "version": "3.0.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "http-signature": "~1.3.6", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "performance-now": "^2.1.0", + "qs": "6.10.4", + "safe-buffer": "^5.1.2", + "tough-cookie": "^4.1.3", + "tunnel-agent": "^0.6.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@cypress/xvfb": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "node_modules/@cypress/xvfb/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@types/cypress": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "cypress": "*" + } + }, + "node_modules/@types/node": { + "version": "22.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sizzle": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.1", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/blob-util": { + "version": "2.0.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-more-types": { + "version": "2.24.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cypress": { + "version": "13.13.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@cypress/request": "^3.0.1", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "buffer": "^5.7.1", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-cursor": "^3.1.0", + "cli-table3": "~0.6.1", + "commander": "^6.2.1", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "^4.3.4", + "enquirer": "^2.3.6", + "eventemitter2": "6.4.7", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "figures": "^3.2.0", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.1", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.8", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "process": "^0.11.10", + "proxy-from-env": "1.0.0", + "request-progress": "^3.0.0", + "semver": "^7.5.3", + "supports-color": "^8.1.1", + "tmp": "~0.2.3", + "untildify": "^4.0.0", + "yauzl": "^2.10.0" + }, + "bin": { + "cypress": "bin/cypress" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/cypress-iframe": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/cypress": "^1.1.0" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dayjs": { + "version": "1.11.12", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.7", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/executable": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getos": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^3.2.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-signature": { + "version": "1.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ini": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isstream": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/lazy-ass": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "> 0.8" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ospath": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/request-progress": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/rxjs": { + "version": "7.8.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/throttleit": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.13.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/cypress-tests/package.json b/cypress-tests/package.json new file mode 100644 index 000000000..a7d678c04 --- /dev/null +++ b/cypress-tests/package.json @@ -0,0 +1,22 @@ +{ + "name": "cypress-tests", + "version": "1.0.0", + "description": "Test cases in cypress", + "main": "cypress.config.js", + "scripts": { + "lint": "./node_modules/.bin/tslint -c tslint.json -p cypress/**/*.ts -t stylish", + "start": "cypress open", + "test": "cypress run" + }, + "repository": { + "type": "git", + "url": "https://github.com/juspay/hyperswitch-web/cypress-tests" + }, + "author": "juspay/hyperswitch-web-sdk", + "license": "ISC", + "devDependencies": { + "cypress": "^13.13.2", + "cypress-iframe": "^1.0.1", + "typescript": "^5.5.4" + } +} diff --git a/cypress-tests/readme.md b/cypress-tests/readme.md new file mode 100644 index 000000000..7360cf74e --- /dev/null +++ b/cypress-tests/readme.md @@ -0,0 +1,31 @@ +

Hyperswitch SDK Web Testing

+ +## Quick Start Locally + +Steps to get started with Hyperswitch-web sdk testing locally: + +1. Set up hyperswitch web following the [Docs](https://github.com/juspay/hyperswitch-web?tab=readme-ov-file#hyperswitch-unified-checkout). + +2. Now that you have three terminals open, spin up a fourth terminal and do `cd cypress-tests && npm start` in the main repo terminal (hyperswitch-web) + (Note: In case Cypress is running for the first time, and cypress script runs into an error, uninstall and re install cypress as a dev module inside the cypress-tests folder) + +3. Cypress should open the window to test separate flows. + +💡 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 : + +``` + npm uninstall cypress + npm install cypress --save-dev +``` + +## Adding test cases: + +1. Test cases to be written in [Typescript](https://www.typescriptlang.org/) and type-safety to be used in all cases.
+ 💡 Note: Try to avoid using `any` keyword as much as possible + +2. In order to add test-ids to the components follow the following cases: + + 1. Create a new key in `hyperswitch-web/src/Utilities/TestUtils.res` + 2. Add the key in: `dataTestId={TestUtils.paymentMethodListTestId}` as the property for the tag to be tested. + + 💡 Note: Either run the `re:build` command or keep the `re:start` command server running to generate the necessary js code diff --git a/cypress-tests/tsconfig.json b/cypress-tests/tsconfig.json new file mode 100644 index 000000000..c9f9beba8 --- /dev/null +++ b/cypress-tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "target": "ES2022", + "lib": ["ES2015", "dom"], + "types": ["cypress", "node"] + }, + "include": ["**/*.ts", "./cypress.d.ts"] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 882c1e75d..837e0bac9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.82.3", + "version": "0.84.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.82.3", + "version": "0.84.1", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 29a899560..6a9ac0fe8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.82.3", + "version": "0.84.1", "main": "index.js", "private": true, "dependencies": { @@ -23,6 +23,7 @@ "build": "webpack --config webpack.common.js", "build:sandbox": "sdkEnv=sandbox webpack --config webpack.common.js", "build:integ": "sdkEnv=integ webpack --config webpack.common.js", + "test": "cd cypress-tests && npm run cypress:run", "re:build": "rescript", "re:clean": "rescript clean", "re:start": "rescript -w", diff --git a/src/Components/BillingNamePaymentInput.res b/src/Components/BillingNamePaymentInput.res index a2af4033c..eebec0981 100644 --- a/src/Components/BillingNamePaymentInput.res +++ b/src/Components/BillingNamePaymentInput.res @@ -71,10 +71,10 @@ let make = (~paymentType, ~customFieldName=None, ~requiredFields as optionalRequ paymentType onBlur type_="text" - name="name" inputRef=nameRef placeholder className={config.appearance.innerLayout === Spaced ? "" : "!border-b-0"} + name=TestUtils.cardHolderNameInputTestId /> } diff --git a/src/Components/EmailPaymentInput.res b/src/Components/EmailPaymentInput.res index a5b846dbf..3d8e13ded 100644 --- a/src/Components/EmailPaymentInput.res +++ b/src/Components/EmailPaymentInput.res @@ -63,9 +63,9 @@ let make = (~paymentType) => { onBlur paymentType type_="email" - name="email" inputRef=emailRef placeholder="Eg: johndoe@gmail.com" + name=TestUtils.emailInputTestId /> } diff --git a/src/Components/FullNamePaymentInput.res b/src/Components/FullNamePaymentInput.res index a83708084..64d0e3426 100644 --- a/src/Components/FullNamePaymentInput.res +++ b/src/Components/FullNamePaymentInput.res @@ -69,9 +69,9 @@ let make = (~paymentType, ~customFieldName=None, ~optionalRequiredFields=None) = paymentType onBlur type_="text" - name="name" inputRef=nameRef placeholder + name=TestUtils.fullNameInputTestId /> } diff --git a/src/Components/PaymentInputField.res b/src/Components/PaymentInputField.res index 1ff51312d..98ba1809d 100644 --- a/src/Components/PaymentInputField.res +++ b/src/Components/PaymentInputField.res @@ -102,6 +102,7 @@ let make = ( width: fieldWidth, height, } + dataTestId={name} disabled=readOnly ref={inputRef->ReactDOM.Ref.domRef} type_ diff --git a/src/Components/SavedCardItem.res b/src/Components/SavedCardItem.res index 777cfc3f0..2e9adac3e 100644 --- a/src/Components/SavedCardItem.res +++ b/src/Components/SavedCardItem.res @@ -184,6 +184,7 @@ let make = ( inputRef=cvcRef placeholder="123" height="2.2rem" + name={TestUtils.cardCVVInputTestId} /> diff --git a/src/Components/SavedMethods.res b/src/Components/SavedMethods.res index 3a2403015..6e65020b9 100644 --- a/src/Components/SavedMethods.res +++ b/src/Components/SavedMethods.res @@ -270,6 +270,7 @@ let make = ( width: "fit-content", color: themeObj.colorPrimary, } + dataTestId={TestUtils.addNewCardIcon} onClick={_ => setShowFields(_ => true)}> {React.string(localeString.morePaymentMethods)} diff --git a/src/PaymentOptions.res b/src/PaymentOptions.res index c57a487da..143de2d3b 100644 --- a/src/PaymentOptions.res +++ b/src/PaymentOptions.res @@ -108,6 +108,7 @@ let make = (
ReactDOM.Ref.domRef} className="flex flex-row overflow-auto no-scrollbar" + dataTestId={TestUtils.paymentMethodListTestId} style={ columnGap: themeObj.spacingTab, marginBottom: themeObj.spacingGridColumn, @@ -145,6 +146,7 @@ let make = ( className={`TabMore place-items-start outline-none`} onChange=handleChange disabled=readOnly + dataTestId=TestUtils.paymentMethodDropDownTestId style={ width: "40px", paddingLeft: themeObj.spacingUnit, diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 68b66ec26..7e1e811fd 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -257,6 +257,7 @@ let make = ( className={innerLayout === Compressed && cardError->String.length > 0 ? "border-b-0" : ""} + name=TestUtils.cardNoInputTestId />
@@ -302,6 +304,7 @@ let make = ( maxLength=4 inputRef=cvcRef placeholder="123" + name=TestUtils.cardCVVInputTestId />
diff --git a/src/Utilities/TestUtils.res b/src/Utilities/TestUtils.res new file mode 100644 index 000000000..b26121b9d --- /dev/null +++ b/src/Utilities/TestUtils.res @@ -0,0 +1,50 @@ +let paymentMethodListTestId = "paymentList" +let paymentMethodDropDownTestId = "paymentMethodsSelect" +let cardNoInputTestId = "cardNoInput" +let expiryInputTestId = "expiryInput" +let cardCVVInputTestId = "cvvInput" +let cardHolderNameInputTestId = "BillingName" +let fullNameInputTestId = "FullName" +let emailInputTestId = "email" +let addressLine1InputTestId = "line1" +let cityInputTestId = "city" +let countryDropDownTestId = "Country" +let stateDropDownTestId = "State" +let postalCodeInputTestId = "postal" +let addNewCardIcon = "addNewCard" + +/* +{ + + "cardNo":"4242 4242 4242 4242", + "cardExpiry":"04/24", + "cardCVV":"424", + "billingName":"John Doe", + "cardHolderName":"John Doe", + "email":"arun@gmail.com", + "address":"123 Main Street Apt 4B", + "city":"New York", + "country":"United States", + "state":"New York", + "postalCode":"10001", + "paymentSuccessfulText":"Payment successful" +} + + + */ + +let fieldTestIdMapping = { + "billing.address.city": cityInputTestId, + "billing.address.country": countryDropDownTestId, + "billing.address.first_name": cardHolderNameInputTestId, + "billing.address.last_name": cardHolderNameInputTestId, + "billing.address.line1": addressLine1InputTestId, + "billing.address.state": stateDropDownTestId, + "billing.address.zip": postalCodeInputTestId, + "email": emailInputTestId, + "payment_method_data.card.card_cvc": cardCVVInputTestId, + "payment_method_data.card.card_exp_month": expiryInputTestId, + "payment_method_data.card.card_exp_year": expiryInputTestId, + "payment_method_data.card.card_holder_name": fullNameInputTestId, + "payment_method_data.card.card_number": cardNoInputTestId, +}