Skip to content

Commit

Permalink
cypress test for facility creation
Browse files Browse the repository at this point in the history
  • Loading branch information
nihal467 committed Jan 8, 2025
1 parent 0088123 commit bb2aa77
Show file tree
Hide file tree
Showing 12 changed files with 409 additions and 18 deletions.
67 changes: 67 additions & 0 deletions cypress/e2e/facility_spec/facility_creation.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { LoginPage } from "../../pageObject/auth/LoginPage";
import { FacilityCreation } from "../../pageObject/facility/FacilityCreation";
import { generatePhoneNumber } from "../../utils/commonUtils";
import { generateFacilityData } from "../../utils/facilityData";

describe("Facility Management", () => {
const loginPage = new LoginPage();
const facilityPage = new FacilityCreation();
const testFacility = generateFacilityData();
const phoneNumber = generatePhoneNumber();

Check failure

Code scanning / CodeQL

Insecure randomness High

This uses a cryptographically insecure random number generated at
Math.random()
in a security context.
This uses a cryptographically insecure random number generated at
Math.random()
in a security context.

beforeEach(() => {
cy.clearLocalStorage();
cy.saveLocalStorage();
cy.visit("/login");
});

afterEach(() => {
cy.saveLocalStorage();
});

it("Create a new facility using the admin role", () => {
// Login
loginPage.loginByRole("admin");
// Navigate to facility creation
facilityPage.navigateToFacilities();
facilityPage.clickAddFacility();

// Fill form
facilityPage.fillBasicDetails(
testFacility.name,
testFacility.type,
testFacility.description,
);

facilityPage.selectFeatures(testFacility.features);

facilityPage.fillContactDetails(
phoneNumber,
testFacility.pincode,
testFacility.address,
);

facilityPage.fillLocationDetails(
testFacility.coordinates.latitude,
testFacility.coordinates.longitude,
);

// Submit and verify
facilityPage.makePublicFacility();
facilityPage.submitFacilityCreationForm();
facilityPage.verifySuccessMessage();

// Search for the facility and verify in card
facilityPage.searchFacility(testFacility.name);
facilityPage.verifyFacilityNameInCard(testFacility.name);
});

it("Should show validation errors for required fields", () => {
loginPage.loginByRole("nurse");

facilityPage.navigateToFacilities();
facilityPage.clickAddFacility();
facilityPage.submitFacilityCreationForm();
facilityPage.verifyValidationErrors();
});
});
7 changes: 0 additions & 7 deletions cypress/pageObject/auth/LoginPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@ export class LoginPage {
return cy.intercept("POST", this.routes.login).as("loginRequest");
}

verifyLoginResponse() {
return cy
.wait("@loginRequest")
.its("response.statusCode")
.should("eq", 200);
}

// Add selectors for existing elements
private readonly usernameInput = "[data-cy=username]";
private readonly passwordInput = "[data-cy=password]";
Expand Down
100 changes: 100 additions & 0 deletions cypress/pageObject/facility/FacilityCreation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
export class FacilityCreation {
// Navigation
navigateToFacilities() {
cy.get('[data-cy="organization-list"]').should("be.visible");
cy.verifyAndClickElement('[data-cy="organization-list"]', "Kerala");
cy.get('[data-testid="org-nav-facilities"]').should("be.visible").click();
}

clickAddFacility() {
cy.get('[data-cy="add-facility-button"]').should("be.visible").click();
}

// Individual field methods
enterFacilityName(name: string) {
cy.get('[data-cy="facility-name"]').type(name);
}

selectFacilityType() {
cy.clickAndSelectOption(
'[data-cy="facility-type"]',
"Primary Health Centres",
);
}

enterDescription(description: string) {
cy.get('[data-cy="facility-description"]').type(description);
}

enterPhoneNumber(phone: string) {
cy.get('[data-cy="facility-phone"]').type(phone);
}

enterPincode(pincode: string) {
cy.get('[data-cy="facility-pincode"]').type(pincode);
}

enterAddress(address: string) {
cy.get('[data-cy="facility-address"]').type(address);
}

enterLatitude(latitude: string) {
cy.get('[data-cy="facility-latitude"]').type(latitude);
}

enterLongitude(longitude: string) {
cy.get('[data-cy="facility-longitude"]').type(longitude);
}

// Combined methods using individual functions
fillBasicDetails(name: string, _facilityType: string, description: string) {
this.enterFacilityName(name);
this.selectFacilityType();
this.enterDescription(description);
}

selectFeatures(features: string[]) {
cy.clickAndMultiSelectOption("#facility-features", features);
}

fillContactDetails(phone: string, pincode: string, address: string) {
this.enterPhoneNumber(phone);
this.enterPincode(pincode);
this.enterAddress(address);
}

fillLocationDetails(latitude: string, longitude: string) {

Check failure

Code scanning / CodeQL

Insecure randomness High

This uses a cryptographically insecure random number generated at
Math.random()
in a security context.

Check failure

Code scanning / CodeQL

Insecure randomness High

This uses a cryptographically insecure random number generated at
Math.random()
in a security context.
this.enterLatitude(latitude);
this.enterLongitude(longitude);
}

makePublicFacility() {
cy.get('[data-cy="make-facility-public"]').click();
}

submitFacilityCreationForm() {
cy.clickSubmitButton("Create Facility");
}

// Verification Methods
verifySuccessMessage() {
cy.verifyNotification("Facility created successfully");
}

verifyValidationErrors() {
cy.verifyErrorMessage("Name is required");
cy.verifyErrorMessage("Facility type is required");
cy.verifyErrorMessage("Address is required");
cy.verifyErrorMessage(
"Phone number must start with +91 followed by 10 digits",
);
}

searchFacility(facilityName: string) {
cy.get('[data-cy="search-facility"]').type(facilityName);
}

verifyFacilityNameInCard(facilityName: string) {
cy.get('[data-cy="facility-cards"]').should("contain", facilityName);
}
}
7 changes: 5 additions & 2 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,11 @@ Cypress.Commands.add(
},
);

Cypress.Commands.add("verifyNotification", (text) => {
return cy.get(".pnotify-container").should("exist").contains(text);
Cypress.Commands.add("verifyNotification", (text: string) => {
return cy
.get("li[data-sonner-toast] div[data-title]")
.should("exist")
.contains(text);
});

Cypress.Commands.add("clearAllFilters", () => {
Expand Down
11 changes: 11 additions & 0 deletions cypress/utils/commonUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function generatePhoneNumber(): string {
// First digit should be 6, 7, 8, or 9 for Indian mobile numbers
const validFirstDigits = [6, 7, 8, 9];
const firstDigit =
validFirstDigits[Math.floor(Math.random() * validFirstDigits.length)];

// Generate remaining 9 digits
const remainingDigits = Math.random().toString().slice(2, 11);

return `${firstDigit}${remainingDigits}`;
}
180 changes: 180 additions & 0 deletions cypress/utils/facilityData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
interface FacilityTestData {
name: string;
type: string;
description: string;
address: string;
pincode: string;
coordinates: {
latitude: string;
longitude: string;
};
features: string[];
}

const FACILITY_FEATURES = [
"CT Scan",
"Maternity Care",
"X-Ray",
"Neonatal Care",
"Operation Theater",
"Blood Bank",
"Emergency Services",
];

// Facility type prefixes
const facilityPrefixes = [
"GHC", // Government Hospital
"PHC", // Primary Health Center
"CHC", // Community Health Center
"THC", // Taluk Hospital
"DH", // District Hospital
];

// Special institution prefixes
const specialPrefixes = [
"Saint Maria",
"Holy Cross",
"Little Flower",
"Mar Sleeva",
"Saint Thomas",
];

// Ernakulam district locations with real coordinates
const locations = [
{
name: "Aluva",
pincode: "683101",
coordinates: { latitude: "10.1004", longitude: "76.3570" },
},
{
name: "Angamaly",
pincode: "683572",
coordinates: { latitude: "10.1960", longitude: "76.3860" },
},
{
name: "Kalady",
pincode: "683574",
coordinates: { latitude: "10.1682", longitude: "76.4410" },
},
{
name: "Perumbavoor",
pincode: "683542",
coordinates: { latitude: "10.1071", longitude: "76.4750" },
},
{
name: "Kothamangalam",
pincode: "686691",
coordinates: { latitude: "10.0558", longitude: "76.6280" },
},
{
name: "Muvattupuzha",
pincode: "686661",
coordinates: { latitude: "9.9894", longitude: "76.5790" },
},
{
name: "Piravom",
pincode: "686664",
coordinates: { latitude: "9.8730", longitude: "76.4920" },
},
{
name: "Kolenchery",
pincode: "682311",
coordinates: { latitude: "9.9811", longitude: "76.4007" },
},
{
name: "Tripunithura",
pincode: "682301",
coordinates: { latitude: "9.9486", longitude: "76.3289" },
},
{
name: "Kakkanad",
pincode: "682030",
coordinates: { latitude: "10.0158", longitude: "76.3419" },
},
{
name: "Edappally",
pincode: "682024",
coordinates: { latitude: "10.0236", longitude: "76.3097" },
},
{
name: "Kaloor",
pincode: "682017",
coordinates: { latitude: "9.9894", longitude: "76.2998" },
},
{
name: "Fort Kochi",
pincode: "682001",
coordinates: { latitude: "9.9639", longitude: "76.2432" },
},
{
name: "Mattancherry",
pincode: "682002",
coordinates: { latitude: "9.9585", longitude: "76.2574" },
},
{
name: "Vytilla",
pincode: "682019",
coordinates: { latitude: "9.9712", longitude: "76.3186" },
},
{
name: "Palarivattom",
pincode: "682025",
coordinates: { latitude: "10.0070", longitude: "76.3050" },
},
{
name: "Thevara",
pincode: "682013",
coordinates: { latitude: "9.9312", longitude: "76.2891" },
},
{
name: "Thrikkakara",
pincode: "682021",
coordinates: { latitude: "10.0316", longitude: "76.3421" },
},
{
name: "Kalamassery",
pincode: "683104",
coordinates: { latitude: "10.0558", longitude: "76.3213" },
},
{
name: "Eloor",
pincode: "683501",
coordinates: { latitude: "10.0583", longitude: "76.2833" },
},
];

function generateFacilityName(): string {
const useSpecialPrefix = Math.random() < 0.2; // 20% chance for special prefix
const location = locations[Math.floor(Math.random() * locations.length)];

if (useSpecialPrefix) {
const specialPrefix =
specialPrefixes[Math.floor(Math.random() * specialPrefixes.length)];
return `${specialPrefix} GHC ${location.name}`;
} else {
const prefix =
facilityPrefixes[Math.floor(Math.random() * facilityPrefixes.length)];
return `${prefix} ${location.name}`;
}
}

export function generateFacilityData(): FacilityTestData {
const location = locations[Math.floor(Math.random() * locations.length)];
const name = generateFacilityName();

// Randomly select 2-4 features from the available options
const shuffledFeatures = [...FACILITY_FEATURES].sort(
() => Math.random() - 0.5,
);
const numberOfFeatures = Math.floor(Math.random() * 3) + 2; // Random number between 2 and 4

return {
name,
type: "General Hospital",
description: `Healthcare facility serving the ${location.name} region with modern medical facilities and experienced staff`,
address: `${name} Building, Main Road, ${location.name}`,
pincode: location.pincode,
coordinates: location.coordinates,
features: shuffledFeatures.slice(0, numberOfFeatures),
};
}
1 change: 1 addition & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@
"external_identifier": "External Identifier",
"facilities": "Facilities",
"facility": "Facility",
"facility_added_successfully": "Facility created successfully",
"facility_consent_requests_page_title": "Patient Consent List",
"facility_district_name": "Facility/District Name",
"facility_district_pincode": "Facility/District/Pincode",
Expand Down
Loading

0 comments on commit bb2aa77

Please sign in to comment.