Skip to content

Commit

Permalink
Merge pull request #57 from Adyen/release/3.1.0
Browse files Browse the repository at this point in the history
Release 3.1.0
  • Loading branch information
dcardos authored Sep 13, 2024
2 parents 9fbdddd + 9dcfd2d commit fc8a70e
Show file tree
Hide file tree
Showing 43 changed files with 7,087 additions and 95 deletions.
92 changes: 92 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Salesforce oms e2e test

on:
pull_request:
branches:
- '**'
paths:
- 'force-app/main/default/**'
- 'e2e/**'
workflow_dispatch:

jobs:
build-and-deploy:
runs-on: ubuntu-latest

env:
OMS_E2E_AUTH_URL: ${{ secrets.OMS_E2E_AUTH_URL }}

steps:
- name: Checkout This Repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install Salesforce CLI
run: npm install @salesforce/cli --global

- name: Create authentication file from secret
run: echo ${OMS_E2E_AUTH_URL} > secret.json

- name: Authenticate to E2E org
run: sf org login sfdx-url -f secret.json --set-default --alias e2eOrg

- name: Checkout Apex-Library Repository
uses: actions/checkout@v4
with:
repository: Adyen/adyen-apex-api-library
ref: develop
path: dependency-repo

- name: Push Apex Lib Source to the Org
run: |
cd dependency-repo
sf project deploy start --target-org e2eOrg
- name: Checkout This Repository Back
uses: actions/checkout@v4

- name: Install xmlstarlet
run: sudo apt-get install -y xmlstarlet

- name: Update customMetadata XML
run: |
chmod +x ./scripts/updateCustomMetadata.sh
./scripts/updateCustomMetadata.sh
env:
MERCHANT_ACCOUNT: ${{ secrets.OMS_E2E_MERCHANT_ACCOUNT }}
HMAC_KEY: ${{ secrets.OMS_E2E_HMAC_KEY }}

- name: Deploy This Repository Code
run: sf project deploy start --target-org e2eOrg --ignore-conflicts

e2e-testing:
runs-on: ubuntu-latest
needs: build-and-deploy

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install dependencies
working-directory: ./e2e
run: npm ci

- name: Run e2e tests
working-directory: ./e2e
run: npm run test
env:
SALESFORCE_USERNAME: ${{ secrets.SALESFORCE_USERNAME }}
SALESFORCE_PASSWORD: ${{ secrets.SALESFORCE_PASSWORD }}
SFCC_HOSTNAME: ${{ secrets.SFCC_HOSTNAME }}
SFCC_STOREFRONT_USERNAME: ${{ secrets.SFCC_STOREFRONT_USERNAME }}
SFCC_STOREFRONT_PASSWORD: ${{ secrets.SFCC_STOREFRONT_PASSWORD }}
MAX_POLL_ATTEMPTS: ${{ vars.MAX_POLL_ATTEMPTS }}
66 changes: 66 additions & 0 deletions .github/workflows/package-version-creation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Release - Package Version Creation

on:
pull_request:
branches:
- 'main'
paths:
- 'force-app/main/default/**'

jobs:
build-and-deploy:
runs-on: ubuntu-latest

env:
PBO_AUTH_URL: ${{ secrets.PBO_AUTH_URL }}

steps:
- name: Checkout This Repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install yq
run: sudo snap install yq

- name: Make scripts executable
run: |
chmod +x scripts/update-app-info-version.sh
chmod +x scripts/create-new-package-version.sh
- name: Verify And Update App Version
run: scripts/update-app-info-version.sh

- name: Install Salesforce CLI
run: npm install @salesforce/cli --global

- name: Create authentication file from secret
run: echo ${PBO_AUTH_URL} > secret.json

- name: Authenticate to Dev Hub
run: sf org login sfdx-url -f secret.json --set-default-dev-hub

- name: Create Package Version
env:
MAX_ATTEMPTS: ${{ vars.MAX_ATTEMPTS }}
run: scripts/create-new-package-version.sh

- name: Commit Modified Files
run: |
git status
git config --global user.name 'GitHub Actions'
git config --global user.email 'actions@github.com'
git config pull.rebase true
git add force-app/main/default/classes/AdyenOMSConstants.cls sfdx-project.json
# Check if any of the files have been modified before committing
if git diff --cached --quiet; then
echo "No changes detected. Skipping commit."
else
echo "Changes detected. Committing changes."
git commit -m "Updating versions on sfdx-project.json and AdyenOMSConstants.cls if needed"
git pull origin "${{ github.head_ref }}"
git push origin "HEAD:${{ github.head_ref }}"
fi
9 changes: 5 additions & 4 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: Salesforce CI/CD
name: Run Unit Tests

on:
pull_request:
branches:
- '**'
workflow_dispatch:
branches-ignore:
- main
paths:
- 'force-app/main/default/**'

jobs:
build-and-deploy:
Expand Down
5 changes: 5 additions & 0 deletions e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
146 changes: 146 additions & 0 deletions e2e/__tests__/creditCard.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { test, expect } from '@playwright/test';
import jsforce from 'jsforce';
import CheckoutPage from '../playwright/pages/CheckoutPageSFRA6.mjs';
import { Cards } from '../playwright/paymentFlows/cards.mjs';
import { ShopperData } from '../playwright/data/shopperData.mjs';
import { CardData } from '../playwright/data/cardData.mjs';

const shopperData = new ShopperData();
const cardData = new CardData();
const maxPollAttempts = process.env.MAX_POLL_ATTEMPTS;
let sfConnection;
let checkoutPage;
let cards;
const baseURL = `https://${process.env.SFCC_HOSTNAME}`;

test.beforeAll(async () => {
sfConnection = new jsforce.Connection({
loginUrl: 'https://login.salesforce.com',
});
await sfConnection.login(
process.env.SALESFORCE_USERNAME,
process.env.SALESFORCE_PASSWORD
);
});

test.describe('E2E Order Creation and Payment Capture', () => {
let orderNumber;

test.beforeAll(async ({ browser }) => {
const context = await browser.newContext({
httpCredentials: {
username: process.env.SFCC_STOREFRONT_USERNAME,
password: process.env.SFCC_STOREFRONT_PASSWORD,
},
});
const page = await context.newPage();
checkoutPage = new CheckoutPage(page);
cards = new Cards(page);

await page.goto(`${baseURL}/s/RefArch/home`);
await checkoutPage.goToCheckoutPageWithFullCart('US', 1);
await checkoutPage.setShopperDetails(shopperData.US);
await cards.doCardPayment(cardData.noThreeDs);
await checkoutPage.completeCheckout();
await checkoutPage.expectSuccess();

const orderNumberElement = await page.locator('span.summary-details.order-number');
const orderNumberElementContent = await orderNumberElement.textContent();

orderNumber = orderNumberElementContent.trim();

await browser.close();
}, 90000);

test('should create a fulfillment order, invoice, and capture payment', async () => {
const orderSummaryRecords = await pollOrderSummary(orderNumber, maxPollAttempts);
expect(orderSummaryRecords.length).toBe(1);
const orderSummaryId = orderSummaryRecords[0].Id;

// Create fulfillment order
const flowName = 'Create_Fulfillment_Orders';
const flowInputParams = {
inputs: [{ OrderSummaryId: orderSummaryId }],
};

await sfConnection.request({
method: 'POST',
url: `/services/data/v58.0/actions/custom/flow/${flowName}`,
body: JSON.stringify(flowInputParams),
headers: {
'content-type': 'application/json',
},
});

const fulfillmentOrderQueryResult = await sfConnection.query(
`SELECT Id from FulfillmentOrder where OrderSummaryId = '${orderSummaryId}'`
);
expect(fulfillmentOrderQueryResult.records.length).toBe(1);
const fulfillmentOrderId = fulfillmentOrderQueryResult.records[0].Id;

// Create invoice
const invoiceRequestBody = {};
const createInvoiceResponse = await sfConnection.request({
method: 'POST',
url: `/services/data/v58.0/commerce/fulfillment/fulfillment-orders/${fulfillmentOrderId}/actions/create-invoice`,
body: JSON.stringify(invoiceRequestBody),
headers: {
'content-type': 'application/json',
},
});
const invoiceId = createInvoiceResponse.invoiceId;

// Capture funds for invoice
const captureFundRequestBody = { invoiceId };
const captureFundResponse = await sfConnection.request({
method: 'POST',
url: `/services/data/v58.0/commerce/order-management/order-summaries/${orderSummaryId}/async-actions/ensure-funds-async`,
body: JSON.stringify(captureFundRequestBody),
headers: {
'content-type': 'application/json',
},
});

const captureReceivedLogs = await pollPaymentGatewayLog(orderSummaryId, '[capture-received]', maxPollAttempts);
expect(captureReceivedLogs.length).toBe(1);
const captureCompleteLogs = await pollPaymentGatewayLog(orderSummaryId, '[capture-complete]', maxPollAttempts);
expect(captureCompleteLogs.length).toBe(1);
});

async function pollOrderSummary(orderNumber, maxPollAttempts) {
const retryDelay = 5000;
let retryCount = 0;
let orderSummaryQueryResult;

while (retryCount < maxPollAttempts) {
orderSummaryQueryResult = await sfConnection.query(
`SELECT Id FROM OrderSummary WHERE OrderNumber = '${orderNumber}'`
);
if (orderSummaryQueryResult.records.length > 0) {
break;
}
retryCount++;
await new Promise((resolve) => setTimeout(resolve, retryDelay));
}

return orderSummaryQueryResult.records;
}

async function pollPaymentGatewayLog(orderSummaryId, gatewayMessage, maxPollAttempts) {
const retryDelay = 5000;
let retryCount = 0;
let gatewayLogQueryResult;

while (retryCount < maxPollAttempts) {
gatewayLogQueryResult = await sfConnection.query(
`SELECT Id, GatewayMessage FROM PaymentGatewayLog WHERE OrderPaymentSummary.OrderSummaryId = '${orderSummaryId}' AND GatewayMessage = '${gatewayMessage}'`
);
if (gatewayLogQueryResult.records.length > 0) {
break;
}
retryCount++;
await new Promise((resolve) => setTimeout(resolve, retryDelay));
}
return gatewayLogQueryResult.records;
}
});
Loading

0 comments on commit fc8a70e

Please sign in to comment.