diff --git a/cypress/e2e/patient_spec/patient_consultation.cy.ts b/cypress/e2e/patient_spec/patient_consultation.cy.ts new file mode 100644 index 00000000000..9b3248d6656 --- /dev/null +++ b/cypress/e2e/patient_spec/patient_consultation.cy.ts @@ -0,0 +1,104 @@ +import { afterEach, before, beforeEach, cy, describe, it } from "local-cypress"; +import LoginPage from "../../pageobject/Login/LoginPage"; +import { PatientPage } from "../../pageobject/Patient/PatientCreation"; +import { PatientConsultationPage } from "../../pageobject/Patient/PatientConsultation"; +import { + emergency_phone_number, + phone_number, +} from "../../pageobject/constants"; +import FacilityPage from "../../pageobject/Facility/FacilityCreation"; +import PatientMedicalHistory from "../../pageobject/Patient/PatientMedicalHistory"; + +describe("Patient Creation with consultation", () => { + const patientConsultationPage = new PatientConsultationPage(); + const loginPage = new LoginPage(); + const patientPage = new PatientPage(); + const facilityPage = new FacilityPage(); + const patientMedicalHistory = new PatientMedicalHistory(); + const patientDateOfBirth = "01012001"; + const patientOneName = "Patient With Consultation"; + const patientOneGender = "Male"; + const patientOneAddress = "Test Patient Address"; + const patientOnePincode = "682001"; + const patientOneState = "Kerala"; + const patientOneDistrict = "Ernakulam"; + const patientOneLocalbody = "Aluva"; + const patientOneWard = "4"; + const patientOneBloodGroup = "O+"; + + before(() => { + loginPage.loginAsDisctrictAdmin(); + cy.saveLocalStorage(); + }); + + beforeEach(() => { + cy.restoreLocalStorage(); + cy.clearLocalStorage(/filters--.+/); + cy.awaitUrl("/patients"); + }); + + it("Create a patient with consultation", () => { + patientPage.createPatient(); + patientPage.selectFacility("Dummy Facility 40"); + patientPage.patientformvisibility(); + patientPage.typePatientPhoneNumber(phone_number); + patientPage.typePatientEmergencyNumber(emergency_phone_number); + patientPage.typePatientDateOfBirth(patientDateOfBirth); + patientPage.typePatientName(patientOneName); + patientPage.selectPatientGender(patientOneGender); + patientPage.typePatientAddress(patientOneAddress); + facilityPage.fillPincode(patientOnePincode); + facilityPage.selectStateOnPincode(patientOneState); + facilityPage.selectDistrictOnPincode(patientOneDistrict); + facilityPage.selectLocalBody(patientOneLocalbody); + facilityPage.selectWard(patientOneWard); + patientMedicalHistory.clickNoneMedicialHistory(); + patientPage.selectPatientBloodGroup(patientOneBloodGroup); + patientPage.clickCreatePatient(); + patientPage.verifyPatientIsCreated(); + patientConsultationPage.fillIllnessHistory("history"); + patientConsultationPage.selectConsultationStatus( + "Outpatient/Emergency Room" + ); + patientConsultationPage.selectSymptoms("ASYMPTOMATIC"); + + patientConsultationPage.enterConsultationDetails( + "Stable", + "Examination details and Clinical conditions", + "70", + "170", + "IP007", + "generalnote", + "Dev Doctor" + ); + patientConsultationPage.submitConsultation(); + + // Below code for the prescription module only present while creating a new consultation + patientConsultationPage.clickAddPrescription(); + patientConsultationPage.interceptMediaBase(); + patientConsultationPage.selectMedicinebox(); + patientConsultationPage.waitForMediabaseStatusCode(); + patientConsultationPage.prescribefirstMedicine(); + patientConsultationPage.enterDosage("3"); + patientConsultationPage.selectDosageFrequency("Twice daily"); + patientConsultationPage.submitPrescriptionAndReturn(); + patientConsultationPage.verifyConsultationPatientName(patientOneName); + }); + + it("Edit created consultation to existing patient", () => { + // temporary fixing, whole file will be refactored soon + cy.get("[data-cy='patient']").first().click(); + patientConsultationPage.clickEditConsultationButton(); + patientConsultationPage.fillIllnessHistory("editted"); + patientConsultationPage.updateSymptoms("FEVER"); + patientConsultationPage.setSymptomsDate("01082023"); + patientConsultationPage.updateConsultation(); + patientConsultationPage.verifySuccessNotification( + "Consultation updated successfully" + ); + }); + + afterEach(() => { + cy.saveLocalStorage(); + }); +}); diff --git a/cypress/e2e/patient_spec/patient_crud.cy.ts b/cypress/e2e/patient_spec/patient_registration.cy.ts similarity index 55% rename from cypress/e2e/patient_spec/patient_crud.cy.ts rename to cypress/e2e/patient_spec/patient_registration.cy.ts index 156a0d4fe5f..1dce2c7c6f7 100644 --- a/cypress/e2e/patient_spec/patient_crud.cy.ts +++ b/cypress/e2e/patient_spec/patient_registration.cy.ts @@ -2,11 +2,15 @@ import { afterEach, before, beforeEach, cy, describe, it } from "local-cypress"; import LoginPage from "../../pageobject/Login/LoginPage"; import { PatientPage } from "../../pageobject/Patient/PatientCreation"; import FacilityPage from "../../pageobject/Facility/FacilityCreation"; -import { PatientConsultationPage } from "../../pageobject/Patient/PatientConsultation"; import { emergency_phone_number, phone_number, } from "../../pageobject/constants"; +import PatientTransfer from "../../pageobject/Patient/PatientTransfer"; +import PatientExternal from "../../pageobject/Patient/PatientExternal"; +import PatientInsurance from "../../pageobject/Patient/PatientInsurance"; +import PatientMedicalHistory from "../../pageobject/Patient/PatientMedicalHistory"; + const yearOfBirth = "2001"; const calculateAge = () => { @@ -17,9 +21,13 @@ const calculateAge = () => { describe("Patient Creation with consultation", () => { const loginPage = new LoginPage(); const patientPage = new PatientPage(); - const patientConsultationPage = new PatientConsultationPage(); const facilityPage = new FacilityPage(); + const patientTransfer = new PatientTransfer(); + const patientExternal = new PatientExternal(); + const patientInsurance = new PatientInsurance(); + const patientMedicalHistory = new PatientMedicalHistory(); const age = calculateAge(); + const patientFacility = "Dummy Facility 40"; const patientDateOfBirth = "01012001"; const patientOneName = "Patient With No Consultation"; const patientOneGender = "Male"; @@ -45,6 +53,10 @@ describe("Patient Creation with consultation", () => { const patientOneSecondPolicyId = "policy name 02"; const patientOneSecondInsurerId = "insurer id 02"; const patientOneSecondInsurerName = "insurer name 02"; + const patientTransferPhoneNumber = "9849511866"; + const patientTransferFacility = "Dummy Shifting Center"; + const patientTransferName = "Dummy Patient 10"; + const patientExternalName = "Patient 20"; before(() => { loginPage.loginAsDisctrictAdmin(); @@ -60,7 +72,7 @@ describe("Patient Creation with consultation", () => { it("Create a new patient with all field in registration form and no consultation", () => { // patient details with all the available fields except covid patientPage.createPatient(); - patientPage.selectFacility("Dummy Facility 40"); + patientPage.selectFacility(patientFacility); patientPage.patientformvisibility(); // Patient Details page patientPage.typePatientPhoneNumber(phone_number); @@ -75,16 +87,18 @@ describe("Patient Creation with consultation", () => { facilityPage.selectLocalBody(patientOneLocalbody); facilityPage.selectWard(patientOneWard); // Patient Medical History - patientPage.typePatientPresentHealth(patientOnePresentHealth); - patientPage.typePatientOngoingMedication(patientOneOngoingMedication); - patientPage.typeMedicalHistory(2, "Diabetes"); - patientPage.typeMedicalHistory(3, "Heart Disease"); - patientPage.typeMedicalHistory(4, "HyperTension"); - patientPage.typeMedicalHistory(5, "Kidney Diseases"); - patientPage.typeMedicalHistory(6, "Lung Diseases/Asthma"); - patientPage.typeMedicalHistory(7, "Cancer"); - patientPage.typeMedicalHistory(8, "Other"); - patientPage.typePatientAllergies(patientOneAllergies); + patientMedicalHistory.typePatientPresentHealth(patientOnePresentHealth); + patientMedicalHistory.typePatientOngoingMedication( + patientOneOngoingMedication + ); + patientMedicalHistory.typeMedicalHistory(2, "Diabetes"); + patientMedicalHistory.typeMedicalHistory(3, "Heart Disease"); + patientMedicalHistory.typeMedicalHistory(4, "HyperTension"); + patientMedicalHistory.typeMedicalHistory(5, "Kidney Diseases"); + patientMedicalHistory.typeMedicalHistory(6, "Lung Diseases/Asthma"); + patientMedicalHistory.typeMedicalHistory(7, "Cancer"); + patientMedicalHistory.typeMedicalHistory(8, "Other"); + patientMedicalHistory.typePatientAllergies(patientOneAllergies); patientPage.selectPatientBloodGroup(patientOneBloodGroup); patientPage.clickCreatePatient(); patientPage.verifyPatientIsCreated(); @@ -101,7 +115,7 @@ describe("Patient Creation with consultation", () => { yearOfBirth, patientOneBloodGroup ); - patientPage.verifyPatientMedicalDetails( + patientMedicalHistory.verifyPatientMedicalDetails( patientOnePresentHealth, patientOneOngoingMedication, patientOneAllergies, @@ -130,39 +144,47 @@ describe("Patient Creation with consultation", () => { patientPage.clickPatientAntenatalStatusYes(); patientPage.selectPatientBloodGroup(patientOneUpdatedBloodGroup); // Edit the patient consultation , select none medical history and multiple health ID - patientPage.clickNoneMedicialHistory(); - patientPage.clickAddInsruanceDetails(); - patientPage.typeSubscriberId( + patientMedicalHistory.clickNoneMedicialHistory(); + patientInsurance.clickAddInsruanceDetails(); + patientInsurance.typePatientInsuranceDetail( patientOneFirstInsuranceId, + "subscriber_id", patientOneFirstSubscriberId ); - patientPage.typePolicyId( + patientInsurance.typePatientInsuranceDetail( patientOneFirstInsuranceId, + "policy_id", patientOneFirstPolicyId ); - patientPage.typeInsurerId( + patientInsurance.typePatientInsuranceDetail( patientOneFirstInsuranceId, + "insurer_id", patientOneFirstInsurerId ); - patientPage.typeInsurerName( + patientInsurance.typePatientInsuranceDetail( patientOneFirstInsuranceId, + "insurer_name", patientOneFirstInsurerName ); - patientPage.clickAddInsruanceDetails(); - patientPage.typeSubscriberId( + patientInsurance.clickAddInsruanceDetails(); + patientInsurance.typePatientInsuranceDetail( patientOneSecondInsuranceId, + "subscriber_id", patientOneSecondSubscriberId ); - patientPage.typePolicyId( + patientInsurance.typePatientInsuranceDetail( patientOneSecondInsuranceId, + "policy_id", patientOneSecondPolicyId ); - patientPage.typeInsurerId( + patientInsurance.typePatientInsuranceDetail( patientOneSecondInsuranceId, + "insurer_id", patientOneSecondInsurerId ); - patientPage.typeInsurerName( + patientInsurance.typePatientInsuranceDetail( patientOneSecondInsuranceId, + "insurer_name", patientOneSecondInsurerName ); patientPage.clickUpdatePatient(); @@ -181,27 +203,27 @@ describe("Patient Creation with consultation", () => { patientOneUpdatedBloodGroup ); // Verify No medical history - patientPage.verifyNoSymptosPresent("Diabetes"); + patientMedicalHistory.verifyNoSymptosPresent("Diabetes"); // verify insurance details and dedicatd page cy.get("[data-testid=patient-details]") .contains(patientOneFirstSubscriberId) .scrollIntoView(); cy.wait(2000); - patientPage.verifyPatientPolicyDetails( + patientInsurance.verifyPatientPolicyDetails( patientOneFirstSubscriberId, patientOneFirstPolicyId, patientOneFirstInsurerId, patientOneFirstInsurerName ); - patientPage.clickPatientInsuranceViewDetail(); + patientInsurance.clickPatientInsuranceViewDetail(); cy.wait(3000); - patientPage.verifyPatientPolicyDetails( + patientInsurance.verifyPatientPolicyDetails( patientOneFirstSubscriberId, patientOneFirstPolicyId, patientOneFirstInsurerId, patientOneFirstInsurerName ); - patientPage.verifyPatientPolicyDetails( + patientInsurance.verifyPatientPolicyDetails( patientOneSecondSubscriberId, patientOneSecondPolicyId, patientOneSecondInsurerId, @@ -209,48 +231,59 @@ describe("Patient Creation with consultation", () => { ); }); - it("Create a New consultation to existing patient", () => { - patientPage.interceptFacilities(); - patientPage.visitConsultationPage(); - patientPage.verifyStatusCode(); - patientConsultationPage.fillIllnessHistory("history"); - patientConsultationPage.selectConsultationStatus( - "Outpatient/Emergency Room" - ); - patientConsultationPage.selectSymptoms("ASYMPTOMATIC"); - - patientConsultationPage.enterConsultationDetails( - "Stable", - "Examination details and Clinical conditions", - "70", - "170", - "IP007", - "generalnote", - "Dev Doctor" - ); - patientConsultationPage.submitConsultation(); - - // Below code for the prescription module only present while creating a new consultation - patientConsultationPage.clickAddPrescription(); - patientConsultationPage.interceptMediaBase(); - patientConsultationPage.selectMedicinebox(); - patientConsultationPage.waitForMediabaseStatusCode(); - patientConsultationPage.prescribefirstMedicine(); - patientConsultationPage.enterDosage("3"); - patientConsultationPage.selectDosageFrequency("Twice daily"); - patientConsultationPage.submitPrescriptionAndReturn(); + it("Patient Registration using the transfer with no consultation", () => { + // transfer the patient and no consulation + patientPage.createPatient(); + patientPage.selectFacility(patientTransferFacility); + patientPage.patientformvisibility(); + patientPage.typePatientPhoneNumber(patientTransferPhoneNumber); + patientTransfer.clickAdmitPatientRecordButton(); + patientTransfer.clickTransferPopupContinueButton(); + patientTransfer.clickTransferPatientNameList(patientTransferName); + patientTransfer.clickTransferPatientDob(patientDateOfBirth); + patientTransfer.clickTransferSubmitButton(); + patientTransfer.verifyFacilitySuccessfullMessage(); + patientTransfer.clickConsultationCancelButton(); + cy.wait(3000); + // allow the transfer button of a patient + patientTransfer.clickAllowPatientTransferButton(); + // Verify the patient error message for the same facility + cy.awaitUrl("/patients"); + patientPage.createPatient(); + patientPage.selectFacility(patientTransferFacility); + patientPage.patientformvisibility(); + patientPage.typePatientPhoneNumber(patientTransferPhoneNumber); + patientTransfer.clickAdmitPatientRecordButton(); + patientTransfer.clickTransferPopupContinueButton(); + patientTransfer.clickTransferPatientNameList(patientTransferName); + patientTransfer.clickTransferPatientDob(patientDateOfBirth); + patientTransfer.clickTransferSubmitButton(); + patientTransfer.verifyFacilityErrorMessage(); }); - it("Edit created consultation to existing patient", () => { - patientPage.visitPatientUrl(); - patientConsultationPage.visitEditConsultationPage(); - patientConsultationPage.fillIllnessHistory("editted"); - patientConsultationPage.updateSymptoms("FEVER"); - patientConsultationPage.setSymptomsDate("01082023"); - patientConsultationPage.updateConsultation(); - patientConsultationPage.verifySuccessNotification( - "Consultation updated successfully" - ); + it("Patient Registration using External Result Import", () => { + // copy the patient external ID from external results + cy.awaitUrl("/external_results"); + patientExternal.verifyExternalListPatientName(patientExternalName); + patientExternal.verifyExternalIdVisible(); + // cypress have a limitation to work only asynchronously + // import the result and create a new patient + let extractedId = ""; + cy.get("#patient-external-id") + .invoke("text") + .then((text) => { + extractedId = text.split("Care external results ID: ")[1]; + cy.log(`Extracted Care external results ID: ${extractedId}`); + cy.awaitUrl("/patients"); + patientPage.createPatient(); + patientPage.selectFacility(patientFacility); + patientPage.patientformvisibility(); + patientExternal.clickImportFromExternalResultsButton(); + patientExternal.typeCareExternalResultId(extractedId); + patientExternal.clickImportPatientData(); + }); + // verify the patient is successfully created + patientExternal.verifyExternalPatientName(patientExternalName); }); afterEach(() => { diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index 8570b2b8e7a..76724d85017 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -17,6 +17,10 @@ export class PatientConsultationPage { }); } + verifyConsultationPatientName(patientName: string) { + cy.get("#patient-name-consultation").should("contain", patientName); + } + fillIllnessHistory(history: string) { cy.wait(5000); cy.get("#history_of_present_illness").scrollIntoView(); @@ -145,9 +149,11 @@ export class PatientConsultationPage { cy.wait("@submitPrescription").its("response.statusCode").should("eq", 201); } - visitEditConsultationPage() { - cy.get("#view_consulation_updates").click(); - cy.get("button").contains("Edit Consultation Details").click(); + clickEditConsultationButton() { + cy.get("#consultation-buttons").scrollIntoView(); + cy.get("#consultation-buttons") + .contains("Edit Consultation Details") + .click(); } setSymptomsDate(date: string) { diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index 0cf8abd4afa..07d87e024a1 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -72,18 +72,6 @@ export class PatientPage { .type(address); } - typePatientPresentHealth(presentHealth: string) { - cy.get("#present_health").click().type(presentHealth); - } - - typePatientOngoingMedication(ongoingMedication: string) { - cy.get("#ongoing_medication").click().type(ongoingMedication); - } - - typePatientAllergies(allergies: string) { - cy.get("#allergies").click().type(allergies); - } - clickPermanentAddress() { cy.get("[data-testid=permanent-address] input").check(); } @@ -92,48 +80,10 @@ export class PatientPage { cy.get("#is_antenatal-0").click(); } - clickAddInsruanceDetails() { - cy.get("[data-testid=add-insurance-button]").click(); - } - - typeSubscriberId(id: string, subscriberId: string) { - cy.get(`#${id}`).within(() => { - cy.get("#subscriber_id").clear().type(subscriberId); - }); - } - - typePolicyId(id: string, policyid: string) { - cy.get(`#${id}`).within(() => { - cy.get("#policy_id").click().type(policyid); - }); - } - - typeInsurerId(id: string, insurerid: string) { - cy.get(`#${id}`).within(() => { - cy.get("#insurer_id").click().type(insurerid); - }); - } - - typeInsurerName(id: string, insurername: string) { - cy.get(`#${id}`).within(() => { - cy.get("#insurer_name").click().type(insurername); - }); - } - - clickNoneMedicialHistory() { - cy.get("[name=medical_history_check_1]").scrollIntoView(); - cy.get("[name=medical_history_check_1]").check(); - } - clickCancelButton() { cy.get("#cancel").click(); } - typeMedicalHistory(index, text) { - cy.get(`#medical_history_check_${index}`).click(); - cy.get(`#medical_history_${index}`).click().type(text); - } - selectPatientGender(gender: string) { cy.get("[data-testid=Gender] button") .click() @@ -229,55 +179,6 @@ export class PatientPage { }); } - verifyPatientMedicalDetails( - patientPresentHealth, - patientOngoingMedication, - patientAllergies, - patientSymptoms1, - patientSymptoms2, - patientSymptoms3, - patientSymptoms4, - patientSymptoms5, - patientSymptoms6, - patientSymptoms7 - ) { - cy.get("[data-testid=patient-details]").then(($dashboard) => { - cy.url().should("include", "/facility/"); - expect($dashboard).to.contain(patientPresentHealth); - expect($dashboard).to.contain(patientOngoingMedication); - expect($dashboard).to.contain(patientAllergies); - expect($dashboard).to.contain(patientSymptoms1); - expect($dashboard).to.contain(patientSymptoms2); - expect($dashboard).to.contain(patientSymptoms3); - expect($dashboard).to.contain(patientSymptoms4); - expect($dashboard).to.contain(patientSymptoms5); - expect($dashboard).to.contain(patientSymptoms6); - expect($dashboard).to.contain(patientSymptoms7); - }); - } - - verifyPatientPolicyDetails(subscriberId, policyId, insurerId, insurerName) { - cy.get("[data-testid=patient-details]").then(($dashboard) => { - cy.url().should("include", "/facility/"); - expect($dashboard).to.contain(subscriberId); - expect($dashboard).to.contain(policyId); - expect($dashboard).to.contain(insurerId); - expect($dashboard).to.contain(insurerName); - }); - } - - clickPatientInsuranceViewDetail() { - cy.get("#insurance-view-details").scrollIntoView(); - cy.get("#insurance-view-details").click(); - } - - verifyNoSymptosPresent(patientSymptoms1: string) { - cy.get("[data-testid=patient-details]").should( - "not.contain", - patientSymptoms1 - ); - } - visitUpdatePatientUrl() { cy.visit(patient_url + "/update"); } diff --git a/cypress/pageobject/Patient/PatientExternal.ts b/cypress/pageobject/Patient/PatientExternal.ts new file mode 100644 index 00000000000..138c212a377 --- /dev/null +++ b/cypress/pageobject/Patient/PatientExternal.ts @@ -0,0 +1,28 @@ +class PatientExternal { + verifyExternalListPatientName(patientName: string) { + cy.get("#external-result-table").contains(patientName).click(); + } + + verifyExternalIdVisible() { + cy.get("#patient-external-id").contains("Care external results ID"); + } + + clickImportFromExternalResultsButton() { + cy.get("#import-externalresult-button").click(); + } + + typeCareExternalResultId(externalId) { + cy.get("#care-external-results-id").scrollIntoView(); + cy.get("#care-external-results-id").should("be.visible"); + cy.get("#care-external-results-id").type(externalId); + } + + clickImportPatientData() { + cy.get("#submit-importexternalresult-button").click(); + } + + verifyExternalPatientName(patientName: string) { + cy.get("#name", { timeout: 10000 }).should("have.value", patientName); + } +} +export default PatientExternal; diff --git a/cypress/pageobject/Patient/PatientInsurance.ts b/cypress/pageobject/Patient/PatientInsurance.ts new file mode 100644 index 00000000000..be4c25c5535 --- /dev/null +++ b/cypress/pageobject/Patient/PatientInsurance.ts @@ -0,0 +1,32 @@ +class PatientInsurance { + typePatientInsuranceDetail( + containerId: string, + fieldId: string, + value: string + ) { + cy.get(`#${containerId}`).within(() => { + cy.get(`#${fieldId}`).click().type(value); + }); + } + + clickPatientInsuranceViewDetail() { + cy.get("#insurance-view-details").scrollIntoView(); + cy.get("#insurance-view-details").click(); + } + + clickAddInsruanceDetails() { + cy.get("[data-testid=add-insurance-button]").click(); + } + + verifyPatientPolicyDetails(subscriberId, policyId, insurerId, insurerName) { + cy.get("[data-testid=patient-details]").then(($dashboard) => { + cy.url().should("include", "/facility/"); + expect($dashboard).to.contain(subscriberId); + expect($dashboard).to.contain(policyId); + expect($dashboard).to.contain(insurerId); + expect($dashboard).to.contain(insurerName); + }); + } +} + +export default PatientInsurance; diff --git a/cypress/pageobject/Patient/PatientMedicalHistory.ts b/cypress/pageobject/Patient/PatientMedicalHistory.ts new file mode 100644 index 00000000000..1c9b733f3ba --- /dev/null +++ b/cypress/pageobject/Patient/PatientMedicalHistory.ts @@ -0,0 +1,59 @@ +class PatientMedicalHistory { + typePatientOngoingMedication(ongoingMedication: string) { + cy.get("#ongoing_medication").click().type(ongoingMedication); + } + + typePatientPresentHealth(presentHealth: string) { + cy.get("#present_health").click().type(presentHealth); + } + + typePatientAllergies(allergies: string) { + cy.get("#allergies").click().type(allergies); + } + + typeMedicalHistory(index, text) { + cy.get(`#medical_history_check_${index}`).click(); + cy.get(`#medical_history_${index}`).click().type(text); + } + + clickNoneMedicialHistory() { + cy.get("[name=medical_history_check_1]").scrollIntoView(); + cy.get("[name=medical_history_check_1]").check(); + } + + verifyPatientMedicalDetails( + patientPresentHealth, + patientOngoingMedication, + patientAllergies, + patientSymptoms1, + patientSymptoms2, + patientSymptoms3, + patientSymptoms4, + patientSymptoms5, + patientSymptoms6, + patientSymptoms7 + ) { + cy.get("[data-testid=patient-details]").then(($dashboard) => { + cy.url().should("include", "/facility/"); + expect($dashboard).to.contain(patientPresentHealth); + expect($dashboard).to.contain(patientOngoingMedication); + expect($dashboard).to.contain(patientAllergies); + expect($dashboard).to.contain(patientSymptoms1); + expect($dashboard).to.contain(patientSymptoms2); + expect($dashboard).to.contain(patientSymptoms3); + expect($dashboard).to.contain(patientSymptoms4); + expect($dashboard).to.contain(patientSymptoms5); + expect($dashboard).to.contain(patientSymptoms6); + expect($dashboard).to.contain(patientSymptoms7); + }); + } + + verifyNoSymptosPresent(patientSymptoms1: string) { + cy.get("[data-testid=patient-details]").should( + "not.contain", + patientSymptoms1 + ); + } +} + +export default PatientMedicalHistory; diff --git a/cypress/pageobject/Patient/PatientTransfer.ts b/cypress/pageobject/Patient/PatientTransfer.ts new file mode 100644 index 00000000000..293490a8bdd --- /dev/null +++ b/cypress/pageobject/Patient/PatientTransfer.ts @@ -0,0 +1,63 @@ +class PatientTransfer { + clickAdmitPatientRecordButton() { + cy.get("#transfer").click(); + } + + clickTransferPopupContinueButton() { + cy.get("#submit-continue-button").click(); + } + + clickTransferPatientNameList(facilityName: string) { + cy.get("#patient").click(); + cy.get("li[role=option]").contains(facilityName).click(); + } + + clickTransferPatientDob(dateOfBirth: string) { + cy.get("#dateofbirth-transferform").scrollIntoView(); + cy.get("#dateofbirth-transferform").should("be.visible").click(); + cy.get("#date-input").click().type(dateOfBirth); + } + + clickTransferSubmitButton() { + cy.get("#submit-transferpatient").click(); + } + + clickConsultationCancelButton() { + cy.get("#cancel").scrollIntoView(); + cy.get("#cancel").click(); + } + + clickAllowPatientTransferButton() { + cy.get("#patient-allow-transfer").click(); + } + + verifyFacilitySuccessfullMessage() { + cy.get(".pnotify") + .should("exist") + .within(() => { + cy.get(".pnotify-text") + .invoke("text") + .then((text) => { + expect(text.trim()).to.match( + /^Patient Dummy Patient 10 \(Male\) transferred successfully$/i + ); + }); + }); + } + + verifyFacilityErrorMessage() { + cy.get(".pnotify") + .should("exist") + .within(() => { + cy.get(".pnotify-text") + .invoke("text") + .then((text) => { + expect(text).to.match( + /Patient - Patient transfer cannot be completed because the patient has an active consultation in the same facility/ + ); + }); + }); + } +} + +export default PatientTransfer; diff --git a/public/config.json b/public/config.json index 9398e28c410..69d898af544 100644 --- a/public/config.json +++ b/public/config.json @@ -21,5 +21,6 @@ "kasp_full_string": "Karunya Arogya Suraksha Padhathi", "sample_format_asset_import": "https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=11JaEhNHdyCHth4YQs_44YaRlP77Rrqe81VSEfg1glko&exportFormat=xlsx", "sample_format_external_result_import": "/External-Results-Template.csv", - "enable_abdm": true + "enable_abdm": true, + "enable_hcx": false } diff --git a/src/Common/hooks/useFilters.tsx b/src/Common/hooks/useFilters.tsx index 4229ae8ab02..1c62a10d9d0 100644 --- a/src/Common/hooks/useFilters.tsx +++ b/src/Common/hooks/useFilters.tsx @@ -5,14 +5,14 @@ import GenericFilterBadge from "../../CAREUI/display/FilterBadge"; import PaginationComponent from "../../Components/Common/Pagination"; import useConfig from "./useConfig"; import { classNames } from "../../Utils/utils"; +import FiltersCache from "../../Utils/FiltersCache"; export type FilterState = Record; -export type FilterParamKeys = string | string[]; interface FilterBadgeProps { name: string; value?: string; - paramKey: FilterParamKeys; + paramKey: string | string[]; } /** @@ -32,18 +32,18 @@ export default function useFilters({ const [showFilters, setShowFilters] = useState(false); const [qParams, _setQueryParams] = useQueryParams(); + const updateCache = (query: QueryParam) => { + const blacklist = FILTERS_CACHE_BLACKLIST.concat(cacheBlacklist); + FiltersCache.set(query, blacklist); + }; + const setQueryParams = ( query: QueryParam, options?: setQueryParamsOptions ) => { - const updatedQParams = { ...query }; - - for (const param of cacheBlacklist) { - delete updatedQParams[param]; - } - + query = FiltersCache.utils.clean(query); _setQueryParams(query, options); - updateFiltersCache(updatedQParams); + updateCache(query); }; const updateQuery = (filter: FilterState) => { @@ -61,15 +61,22 @@ export default function useFilters({ const removeFilter = (param: string) => removeFilters([param]); useEffect(() => { - const cache = getFiltersCache(); const qParamKeys = Object.keys(qParams); - const canSkip = Object.keys(cache).every( - (key) => qParamKeys.includes(key) && qParams[key] === cache[key] - ); - if (canSkip) return; - if (Object.keys(cache).length) { - setQueryParams(cache); + + // If we navigate to a path that has query params set on mount, + // skip restoring the cache, instead update the cache with new filters. + if (qParamKeys.length) { + updateCache(qParams); + return; } + + const cache = FiltersCache.get(); + if (!cache) { + return; + } + + // Restore cache + setQueryParams(cache); }, []); const FilterBadge = ({ name, value, paramKey }: FilterBadgeProps) => { @@ -99,7 +106,7 @@ export default function useFilters({ }; const badgeUtils = { - badge(name: string, paramKey: FilterParamKeys) { + badge(name: string, paramKey: FilterBadgeProps["paramKey"]) { return { name, paramKey }; }, ordering(name = "Sort by", paramKey = "ordering") { @@ -109,7 +116,7 @@ export default function useFilters({ value: qParams[paramKey] && t("SortOptions." + qParams[paramKey]), }; }, - value(name: string, paramKey: FilterParamKeys, value: string) { + value(name: string, paramKey: FilterBadgeProps["paramKey"], value: string) { return { name, value, paramKey }; }, phoneNumber(name = "Phone Number", paramKey = "phone_number") { @@ -278,15 +285,3 @@ const removeFromQuery = (query: Record, params: string[]) => { }; const FILTERS_CACHE_BLACKLIST = ["page", "limit", "offset"]; - -const getFiltersCacheKey = () => `filters--${window.location.pathname}`; -const getFiltersCache = () => { - return JSON.parse(localStorage.getItem(getFiltersCacheKey()) || "{}"); -}; -const updateFiltersCache = (cache: Record) => { - const result = { ...cache }; - for (const param of FILTERS_CACHE_BLACKLIST) { - delete result[param]; - } - localStorage.setItem(getFiltersCacheKey(), JSON.stringify(result)); -}; diff --git a/src/Components/Auth/Login.tsx b/src/Components/Auth/Login.tsx index d1cd94dbab5..8dcae9bafc0 100644 --- a/src/Components/Auth/Login.tsx +++ b/src/Components/Auth/Login.tsx @@ -11,8 +11,8 @@ import useConfig from "../../Common/hooks/useConfig"; import CircularProgress from "../Common/components/CircularProgress"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; -import { invalidateFiltersCache } from "../../Utils/utils"; import { useAuthContext } from "../../Common/hooks/useAuthUser"; +import FiltersCache from "../../Utils/FiltersCache"; export const Login = (props: { forgot?: boolean }) => { const { signIn } = useAuthContext(); @@ -93,7 +93,7 @@ export const Login = (props: { forgot?: boolean }) => { const handleSubmit = async (e: any) => { e.preventDefault(); setLoading(true); - invalidateFiltersCache(); + FiltersCache.invaldiateAll(); const validated = validateData(); if (!validated) { setLoading(false); diff --git a/src/Components/Common/FacilitySelect.tsx b/src/Components/Common/FacilitySelect.tsx index 17f67a7def1..b207189d27d 100644 --- a/src/Components/Common/FacilitySelect.tsx +++ b/src/Components/Common/FacilitySelect.tsx @@ -16,7 +16,7 @@ interface FacilitySelectProps { showAll?: boolean; showNOptions?: number; freeText?: boolean; - selected: FacilityModel | FacilityModel[] | null; + selected?: FacilityModel | FacilityModel[] | null; setSelected: (selected: FacilityModel | FacilityModel[] | null) => void; } diff --git a/src/Components/ExternalResult/ResultItem.tsx b/src/Components/ExternalResult/ResultItem.tsx index 47363e02ce1..0954f704176 100644 --- a/src/Components/ExternalResult/ResultItem.tsx +++ b/src/Components/ExternalResult/ResultItem.tsx @@ -77,13 +77,18 @@ export default function ResultItem(props: any) {

- {resultItemData.name} - {resultItemData.age}{" "} - {resultItemData.age_in} | {resultItemData.result} + {resultItemData.name} -{" "} + {resultItemData.age}{" "} + {resultItemData.age_in} |{" "} + {resultItemData.result}

{t("srf_id")}: {resultItemData.srf_id}

-

+

{t("care_external_results_id")}: {resultItemData.id}

{resultItemData.patient_created ? ( diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index f644c2b54e0..82a49e3a8e3 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -318,7 +318,10 @@ export default function ResultList() { ]} /> -
+
diff --git a/src/Components/Facility/DuplicatePatientDialog.tsx b/src/Components/Facility/DuplicatePatientDialog.tsx index 46eb4e2dd7a..7a36beac685 100644 --- a/src/Components/Facility/DuplicatePatientDialog.tsx +++ b/src/Components/Facility/DuplicatePatientDialog.tsx @@ -119,6 +119,7 @@ const DuplicatePatientDialog = (props: Props) => { label={`Cancel ${isNew ? "Registration" : "Update"}`} /> handleOk(action)} disabled={!action} label="Continue" diff --git a/src/Components/Facility/FacilityFilter/DistrictSelect.tsx b/src/Components/Facility/FacilityFilter/DistrictSelect.tsx index 088048ba6dd..ef77d50221e 100644 --- a/src/Components/Facility/FacilityFilter/DistrictSelect.tsx +++ b/src/Components/Facility/FacilityFilter/DistrictSelect.tsx @@ -8,7 +8,7 @@ interface DistrictSelectProps { errors: string; className?: string; multiple?: boolean; - selected: string; + selected?: string; setSelected: (selected: string) => void; } diff --git a/src/Components/Facility/TransferPatientDialog.tsx b/src/Components/Facility/TransferPatientDialog.tsx index e6133279a9e..259d497f684 100644 --- a/src/Components/Facility/TransferPatientDialog.tsx +++ b/src/Components/Facility/TransferPatientDialog.tsx @@ -175,6 +175,7 @@ const TransferPatientDialog = (props: Props) => {
{
value && dayjs(value).isValid() && dayjs(value).toDate(); @@ -105,37 +101,24 @@ export default function PatientFilter(props: any) { diagnoses_unconfirmed: filter.diagnoses_unconfirmed || null, diagnoses_differential: filter.diagnoses_differential || null, }); - const dispatch: any = useDispatch(); - - useEffect(() => { - async function fetchData() { - if (filter.facility) { - const { data: facilityData } = await dispatch( - getAnyFacility(filter.facility, "facility") - ); - setFilterState({ facility_ref: facilityData }); - } - if (filter.district) { - const { data: districtData } = await dispatch( - getDistrict(filter.district, "district") - ); - setFilterState({ district_ref: districtData }); - } + useQuery(routes.getAnyFacility, { + pathParams: { id: filter.facility }, + prefetch: !!filter.facility, + onResponse: ({ data }) => setFilterState({ facility_ref: data }), + }); - if (filter.lsgBody) { - const { data: lsgRes } = await dispatch(getAllLocalBody({})); - const lsgBodyData = lsgRes.results; + useQuery(routes.getDistrict, { + pathParams: { id: filter.district }, + prefetch: !!filter.district, + onResponse: ({ data }) => setFilterState({ district_ref: data }), + }); - setFilterState({ - lsgBody_ref: lsgBodyData.filter( - (obj: any) => obj.id.toString() === filter.lsgBody.toString() - )[0], - }); - } - } - fetchData(); - }, [dispatch]); + useQuery(routes.getLocalBody, { + pathParams: { id: filter.lsgBody }, + prefetch: !!filter.lsgBody, + onResponse: ({ data }) => setFilterState({ lsgBody_ref: data }), + }); const VACCINATED_FILTER = [ { id: "0", text: "Unvaccinated" }, @@ -161,21 +144,19 @@ export default function PatientFilter(props: any) { { id: "false", text: "No" }, ]; - const setFacility = (selected: any, name: string) => { - const filterData: any = { ...filterState }; - filterData[`${name}_ref`] = selected; - filterData[name] = (selected || {}).id; - - setFilterState(filterData); + const setFilterWithRef = (name: string, selected?: any) => { + setFilterState({ + [`${name}_ref`]: selected, + [name]: selected?.id, + }); }; - const lsgSearch = useCallback( - async (search: string) => { - const res = await dispatch(getAllLocalBody({ local_body_name: search })); - return res?.data?.results; - }, - [dispatch] - ); + const lsgSearch = async (search: string) => { + const { data } = await request(routes.getAllLocalBody, { + query: { local_body_name: search }, + }); + return data?.results; + }; const applyFilter = () => { const { @@ -585,7 +566,7 @@ export default function PatientFilter(props: any) { name="facility" showAll={false} selected={filterState.facility_ref} - setSelected={(obj) => setFacility(obj, "facility")} + setSelected={(obj) => setFilterWithRef("facility", obj)} />
{filterState.facility && ( @@ -629,13 +610,7 @@ export default function PatientFilter(props: any) { name="lsg_body" selected={filterState.lsgBody_ref} fetchData={lsgSearch} - onChange={(selected) => - setFilterState({ - ...filterState, - lsgBody_ref: selected, - lsgBody: selected.id, - }) - } + onChange={(obj) => setFilterWithRef("lsgBody", obj)} optionLabel={(option) => option.name} compareBy="id" /> @@ -648,7 +623,7 @@ export default function PatientFilter(props: any) { multiple={false} name="district" selected={filterState.district_ref} - setSelected={(obj: any) => setFacility(obj, "district")} + setSelected={(obj) => setFilterWithRef("district", obj)} errors={""} />
diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index 22cc35a170e..9b719ba31dd 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -795,6 +795,7 @@ export const PatientHome = (props: any) => {
)} -
+
{!!consultation?.discharge_date && (
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx index ce63d5019de..2f18ef36dbb 100644 --- a/src/Components/Patient/PatientRegister.tsx +++ b/src/Components/Patient/PatientRegister.tsx @@ -1126,6 +1126,7 @@ export const PatientRegister = (props: PatientRegisterProps) => { />