As someone who has worked on various testing scenarios, I’ve often found that testing the integration between different components of an application—like a web app, APIs, and Salesforce—is crucial to ensure everything works seamlessly. I will present you an idea of how this integration feature could be tested using popular automation tools like Cypress, Postman and GitHub Actions. By the end, you’ll see how these tools complement each other to provide end-to-end test coverage.
Test Plan Overview
The objective of this test is to:
- Update user profile data via the web app using Cypress.
- Retrieve and validate the updated data using Postman.
- Update data via Postman and validate the changes in Salesforce.
- Confirm the changes are reflected in the web app using Cypress.
- Automate this whole process with GitHub Actions
This plan tests the bidirectional flow of data between the web app, Salesforce, and the API.
Step 0: Apex Class API code
First, let’s define the Apex API code that is standing behind this whole process and that is managing the data changes in Salesforce objects:
@RestResource(urlMapping='/user/*')
global with sharing class UserProfileController {
/**
* Retrieve a user's profile details.
* Endpoint: GET /user/{id}
*/
@HttpGet
global static UserDTO getUser() {
RestRequest req = RestContext.request;
String userId = req.requestURI.substringAfterLast('/');
// Query user details
Account userAccount = [SELECT Id, Name, Phone, Email FROM Account WHERE Id = :userId LIMIT 1];
// Create a DTO to return only necessary fields
return new UserDTO(userAccount.Id, userAccount.Name, userAccount.Phone, userAccount.Email);
}
/**
* Update a user's profile details.
* Endpoint: PUT /user/{id}
*/
@HttpPut
global static void updateUser() {
RestRequest req = RestContext.request;
String userId = req.requestURI.substringAfterLast('/');
String requestBody = req.requestBody.toString();
// Parse request body
Map<String, Object> parsedData = (Map<String, Object>) JSON.deserializeUntyped(requestBody);
String phone = (String) parsedData.get('Phone');
String email = (String) parsedData.get('Email');
// Update user details
Account userAccount = [SELECT Id, Phone, Email FROM Account WHERE Id = :userId LIMIT 1];
if (phone != null) userAccount.Phone = phone;
if (email != null) userAccount.Email = email;
update userAccount;
}
/**
* DTO for User data
*/
public class UserDTO {
public String id;
public String name;
public String phone;
public String email;
public UserDTO(String id, String name, String phone, String email) {
this.id = id;
this.name = name;
this.phone = phone;
this.email = email;
}
}
}
Step 1: Updating Data via Cypress
Cypress is great for simulating user interactions with a web app. In this step, we’ll log in to the web app, update the user’s phone number in their profile, and verify the update on the UI.
Cypress Script:
// cypress/e2e/updateUserProfile.cy.js
describe('Update User Profile via UI', () => {
it('Logs in and updates the profile', () => {
// Visit login page
cy.visit('/login');
// Perform login
cy.get('#username').type('test_user');
cy.get('#password').type('password123');
cy.get('#loginButton').click();
// Navigate to the profile page
cy.get('#profileMenu').click();
// Update phone number
cy.get('#phoneNumber').clear().type('123456789');
cy.get('#saveButton').click();
// Verify the phone number is updated
cy.get('#phoneNumber').should('have.value', '123456789');
});
});
This script logs into the app, updates the phone number field, and verifies the change. The updated phone number will be pushed to Salesforce via the app’s back-end.
Step 2: Validating the Update with Postman
Next, we’ll use Postman to call the Salesforce API and confirm that the phone number was updated correctly.
Postman Request:
GET Request: /user/{id}
{
"method": "GET",
"url": "https://your-salesforce-instance.com/services/data/vXX.X/sobjects/Contact/{id}",
"headers": {
"Authorization": "Bearer {{access_token}}",
"Content-Type": "application/json"
}
}
Validation in Postman:
Use a test script to validate the retrieved data:
pm.test("Verify phone number", function() {
const response = pm.response.json();
pm.expect(response.Phone).to.eql("123456789");
});
This ensures the data updated via the UI is reflected in Salesforce.
Step 3: Updating Data via Postman
In this step, we’ll update another field (e.g., email address) directly through the API and validate the response.
Postman Request:
PUT Request: /user/{id}
{
"method": "PUT",
"url": "https://your-salesforce-instance.com/services/data/vXX.X/sobjects/Contact/{id}",
"headers": {
"Authorization": "Bearer {{access_token}}",
"Content-Type": "application/json"
},
"body": {
"mode": "raw",
"raw": JSON.stringify({
"Email": "[email protected]"
})
}
}
Validation in Postman:
pm.test("Verify email update", function() {
const response = pm.response.json();
pm.expect(response.success).to.be.true;
});
This updates the email address in Salesforce.
Step 4: Validating API Updates via Cypress
Finally, we’ll log back into the web app using Cypress and verify that the changes made via the API are reflected in the UI.
Cypress Script:
// cypress/e2e/verifyApiUpdate.cy.js
describe('Verify API Updates via UI', () => {
it('Logs in and verifies updated email', () => {
// Visit login page
cy.visit('/login');
// Perform login
cy.get('#username').type('test_user');
cy.get('#password').type('password123');
cy.get('#loginButton').click();
// Navigate to the profile page
cy.get('#profileMenu').click();
// Verify updated email
cy.get('#emailAddress').should('have.value', '[email protected]');
});
});
This step confirms that changes made via the API are synchronized with the web app.
Automating the Process with GitHub Actions
To make this testing process seamless, we can automate it using GitHub Actions. By configuring a CI/CD pipeline, the entire test plan can run automatically on every commit or pull request.
Updated GitHub Actions Workflow:
name: Integration Test Workflow
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
integration-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install Cypress dependencies
run: |
npm install
- name: Run Cypress to update data
run: |
npx cypress run --spec cypress/e2e/updateUserProfile.cy.js
- name: Set up Postman Newman
run: |
npm install -g newman
- name: Run Postman to retrieve updated data
run: |
newman run postman_collection.json --environment postman_environment.json --folder RetrieveData
- name: Run Postman to update data
run: |
newman run postman_collection.json --environment postman_environment.json --folder UpdateData
- name: Run Cypress to verify API updates
run: |
npx cypress run --spec cypress/e2e/verifyApiUpdate.cy.js
- name: Upload test results
if: failure()
uses: actions/upload-artifact@v3
with:
name: test-results
path: cypress/screenshots
Steps used:
- Cypress to Update Data: The first Cypress test updates user data via the UI.
- Postman to Retrieve Data: Newman retrieves the updated data and validates it against Salesforce.
- Postman to Update Data: Newman updates the data via the API.
- Cypress to Verify Updates: The final Cypress test validates the API changes in the UI.
- Artifacts: If any step fails, relevant logs and screenshots are uploaded for debugging.