Skip to content

Commit

Permalink
New Cypress Test for User Creation (#9986)
Browse files Browse the repository at this point in the history
  • Loading branch information
nihal467 authored Jan 15, 2025
1 parent 2b69139 commit e38417d
Show file tree
Hide file tree
Showing 16 changed files with 371 additions and 104 deletions.
11 changes: 8 additions & 3 deletions cypress/docs/patterns.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
# Testing Patterns

## Element Interaction

### Preferred Command Usage

```typescript
// Correct
cy.verifyAndClickElement('[data-cy="element"]', "Button Text");

// Avoid
cy.get('[data-cy="element"]').should('be.visible').click();
cy.get('[data-cy="element"]').should("be.visible").click();
```

## Navigation Patterns

```typescript
// Good
navigateToOrganization(orgName: string) {
cy.verifyAndClickElement('[data-cy="organization-list"]', orgName);
}

navigateToFacilitiesList() {
cy.verifyAndClickElement('[data-testid="org-nav-facilities"]', "Facilities");
cy.verifyAndClickElement('[data-cy="org-nav-facilities"]', "Facilities");
}
```

## Test Data Management

```typescript
// Constants for fixed values
const facilityType = "Primary Health Centre";
Expand All @@ -32,6 +36,7 @@ const phoneNumber = generatePhoneNumber();
```

## Test Structure

```typescript
describe("Feature Name", () => {
const page = new PageObject();
Expand All @@ -47,4 +52,4 @@ describe("Feature Name", () => {
page.navigateToFacilitiesList();
});
});
```
```
5 changes: 3 additions & 2 deletions cypress/e2e/facility_spec/facility_creation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import { generateFacilityData } from "../../utils/facilityData";
describe("Facility Management", () => {
const facilityPage = new FacilityCreation();
const facilityType = "Primary Health Centre";
const testFacility = generateFacilityData();
const phoneNumber = generatePhoneNumber();

beforeEach(() => {
cy.visit("/login");
cy.loginByApi("nurse");
});

it("Create a new facility using the admin role and verify validation errors", () => {
const testFacility = generateFacilityData();
const phoneNumber = generatePhoneNumber();

facilityPage.navigateToOrganization("Kerala");
facilityPage.navigateToFacilitiesList();
facilityPage.clickAddFacility();
Expand Down
10 changes: 6 additions & 4 deletions cypress/e2e/patient_spec/patient_creation.cy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { patientCreation } from "pageObject/Patients/PatientCreation";
import { patientDashboard } from "pageObject/Patients/PatientDashboard";
import { patientVerify } from "pageObject/Patients/PatientVerify";
import { FacilityCreation } from "pageObject/facility/FacilityCreation";

import {
generateAddress,
generatePatientName,
generateName,
generatePhoneNumber,
} from "../../utils/commonUtils";

const facilityCreation = new FacilityCreation();
const ENCOUNTER_TYPE = "Observation";
const ENCOUNTER_STATUS = "In Progress";
const ENCOUNTER_PRIORITY = "ASAP";
Expand All @@ -21,7 +23,7 @@ describe("Patient Management", () => {
};

const testPatientData = {
name: generatePatientName(),
name: generateName(),
phoneNumber: generatePhoneNumber(),
gender: "male",
bloodGroup: "B+",
Expand All @@ -40,8 +42,8 @@ describe("Patient Management", () => {

it("create a new patient and verify details", () => {
cy.loginByApi("doctor");
facilityCreation.selectFacility("Arike");
patientCreation
.selectFacility("Arike")
.clickSearchPatients()
.clickCreateNewPatient()
.fillPatientDetails(testPatientData)
Expand All @@ -65,8 +67,8 @@ describe("Patient Management", () => {

it("search patient with phone number and verifies details", () => {
cy.loginByApi("staff");
facilityCreation.selectFacility("Arike");
patientCreation
.selectFacility("Arike")
.clickSearchPatients()
.searchPatient(TEST_PHONE)
.verifySearchResults(PATIENT_DETAILS);
Expand Down
57 changes: 57 additions & 0 deletions cypress/e2e/users_spec/user_creation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { UserCreation } from "../../pageObject/Users/UserCreation";
import { FacilityCreation } from "../../pageObject/facility/FacilityCreation";
import {
generateName,
generatePhoneNumber,
generateUsername,
} from "../../utils/commonUtils";

describe("User Creation", () => {
const facilityCreation = new FacilityCreation();
const userCreation = new UserCreation();
const userRole = "Doctor";

beforeEach(() => {
cy.visit("/login");
cy.loginByApi("admin");
});

it("should create a new user successfully", () => {
// Generate fresh data at the start of each test attempt
const fullName = generateName();
const [firstName, lastName] = fullName.split(" ");
const defaultPassword = "Test@123";

const testUserData = {
firstName,
lastName,
username: generateUsername(firstName),
password: defaultPassword,
confirmPassword: defaultPassword,
email: `${generateUsername(firstName)}@test.com`,
phoneNumber: generatePhoneNumber(),
dateOfBirth: "1990-01-01",
userType: "Doctor",
state: "Kerala",
district: "Ernakulam",
localBody: "Aluva",
ward: "4",
};

facilityCreation.navigateToOrganization("Kerala");

userCreation
.navigateToUsersTab()
.clickAddUserButton()
.submitUserForm()
.verifyValidationErrors()
.fillUserDetails(testUserData)
.interceptUserCreationRequest()
.submitUserForm()
.verifyUserCreationApiCall()
.selectUserRole(userRole)
.interceptOrganizationUserLinking()
.clickLinkToOrganization()
.verifyOrganizationUserLinkingApiCall();
});
});
2 changes: 1 addition & 1 deletion cypress/fixtures/users.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"admin": {
"username": "admin",
"password": "admin"
"password": "Lilo@123"
},
"nurse": {
"username": "nihal-nurse",
Expand Down
5 changes: 0 additions & 5 deletions cypress/pageObject/Patients/PatientCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ export class PatientCreation {
cy.verifyContentPresence(this.selectors.patientDetails, detailsArray);
}

selectFacility(facilityName: string) {
cy.verifyAndClickElement("[data-cy='facility-list']", facilityName);
return this;
}

clickSearchPatients() {
cy.get('[data-sidebar="content"]').contains("Search Patients").click();
return this;
Expand Down
176 changes: 176 additions & 0 deletions cypress/pageObject/Users/UserCreation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
export interface UserData {
firstName?: string;
lastName?: string;
username?: string;
password?: string;
email?: string;
phoneNumber?: string;
dateOfBirth?: string;
userType?: string;
state?: string;
district?: string;
localBody?: string;
ward?: string;
}

export class UserCreation {
clickAddUserButton() {
cy.verifyAndClickElement('[data-cy="add-user-button"]', "Add User");
return this;
}

navigateToUsersTab() {
cy.verifyAndClickElement('[data-cy="org-nav-users"]', "Users");
return this;
}

fillFirstName(firstName: string) {
cy.typeIntoField('[data-cy="first-name-input"]', firstName);
return this;
}

fillLastName(lastName: string) {
cy.typeIntoField('[data-cy="last-name-input"]', lastName);
return this;
}

fillUsername(username: string) {
cy.typeIntoField('[data-cy="username-input"]', username);
return this;
}

fillPassword(password: string) {
cy.typeIntoField('[data-cy="password-input"]', password);
return this;
}

fillConfirmPassword(confirmPassword: string) {
cy.typeIntoField('[data-cy="confirm-password-input"]', confirmPassword);
return this;
}

fillEmail(email: string) {
cy.typeIntoField('[data-cy="email-input"]', email);
return this;
}

fillPhoneNumber(phoneNumber: string) {
cy.typeIntoField('[data-cy="phone-number-input"]', phoneNumber, {
skipVerification: true,
});
return this;
}

verifyValidationErrors() {
cy.verifyErrorMessages([
{ label: "First Name", message: "Required" },
{ label: "Last Name", message: "Required" },
{ label: "Username", message: "Required" },
{ label: "Password", message: "Required" },
{ label: "Confirm Password", message: "Required" },
{ label: "Email", message: "Required" },
{
label: "Phone Number",
message: "Phone number must start with +91 followed by 10 digits",
},
{
label: "Alternate Phone Number",
message: "Phone number must start with +91 followed by 10 digits",
},
{ label: "Date of Birth", message: "Required" },
{ label: "State", message: "Required" },
]);
return this;
}

fillDateOfBirth(dateOfBirth: string) {
cy.typeIntoField('[data-cy="dob-input"]', dateOfBirth);
return this;
}

selectUserType(userType: string) {
cy.clickAndSelectOption('[data-cy="user-type-select"]', userType);
return this;
}

selectState(state: string) {
cy.clickAndSelectOption('[data-cy="select-state"]', state);
return this;
}

selectDistrict(district: string) {
cy.clickAndSelectOption('[data-cy="select-district"]', district);
return this;
}

selectLocalBody(localBody: string) {
cy.clickAndSelectOption('[data-cy="select-local_body"]', localBody);
return this;
}

selectWard(ward: string) {
cy.clickAndSelectOption('[data-cy="select-ward"]', ward);
return this;
}

fillUserDetails(userData: UserData & { confirmPassword?: string }) {
if (userData.userType) this.selectUserType(userData.userType);
if (userData.firstName) this.fillFirstName(userData.firstName);
if (userData.lastName) this.fillLastName(userData.lastName);
if (userData.username) this.fillUsername(userData.username);
if (userData.password) {
this.fillPassword(userData.password);
this.fillConfirmPassword(userData.confirmPassword || userData.password);
}
if (userData.email) this.fillEmail(userData.email);
if (userData.phoneNumber) this.fillPhoneNumber(userData.phoneNumber);
if (userData.dateOfBirth) this.fillDateOfBirth(userData.dateOfBirth);
if (userData.state) this.selectState(userData.state);
if (userData.district) this.selectDistrict(userData.district);
if (userData.localBody) this.selectLocalBody(userData.localBody);
if (userData.ward) this.selectWard(userData.ward);
return this;
}

submitUserForm() {
cy.clickSubmitButton("Create User");
return this;
}

selectUserRole(role: string) {
cy.clickAndSelectOption('[data-cy="select-role-dropdown"]', role);
return this;
}

clickLinkToOrganization() {
cy.verifyAndClickElement(
'[data-cy="link-user-button"]',
"Link to Organization",
);
return this;
}

interceptUserCreationRequest() {
cy.intercept("POST", "**/api/v1/users/").as("createUser");
return this;
}

verifyUserCreationApiCall() {
cy.wait("@createUser").then((interception) => {
expect(interception.response?.statusCode).to.equal(200);
});
return this;
}

interceptOrganizationUserLinking() {
cy.intercept("POST", "**/api/v1/organization/*/users/").as("linkUserToOrg");
return this;
}

verifyOrganizationUserLinkingApiCall() {
cy.wait("@linkUserToOrg").then((interception) => {
expect(interception.response?.statusCode).to.equal(200);
});
return this;
}
}
4 changes: 2 additions & 2 deletions cypress/pageObject/auth/LoginPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export class LoginPage {

verifyValidationErrors() {
cy.verifyErrorMessages([
"This field is required",
"This field is required",
{ label: "Username", message: "This field is required" },
{ label: "Password", message: "This field is required" },
]);
return this;
}
Expand Down
Loading

0 comments on commit e38417d

Please sign in to comment.