From b54bcc5c6f1b73d45b02dd13d0a2cf9515bf7463 Mon Sep 17 00:00:00 2001 From: Mohammed Nihal <57055998+nihal467@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:49:01 +0300 Subject: [PATCH] New Cypress test for the patient discussion notes (#8554) * doctor notes cypress test without tab switching * doctor notes cypress test without tab switching * Adds utility fn. to extract keys of obj. in type-safe manner. * i18n for patient notes thread titles and add id for tabs * discussion note tab switching functionality test * made success notification as variables * corrected the test description --------- Co-authored-by: rithviknishad --- .../e2e/patient_spec/PatientDoctorNotes.cy.ts | 61 +++++++++++++++++++ cypress/e2e/patient_spec/PatientManage.cy.ts | 48 --------------- cypress/pageobject/Login/LoginPage.ts | 6 ++ .../pageobject/Patient/PatientConsultation.ts | 26 -------- cypress/pageobject/Patient/PatientCreation.ts | 1 + .../pageobject/Patient/PatientDoctorNotes.ts | 29 +++++++++ .../Facility/ConsultationDetails/index.tsx | 2 +- .../ConsultationDoctorNotes/index.tsx | 16 ++--- .../Facility/PatientNotesSlideover.tsx | 18 +++--- src/Components/Patient/PatientNotes.tsx | 16 ++--- src/Locale/en/Consultation.json | 6 +- src/Utils/utils.ts | 7 +++ 12 files changed, 128 insertions(+), 108 deletions(-) create mode 100644 cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts delete mode 100644 cypress/e2e/patient_spec/PatientManage.cy.ts create mode 100644 cypress/pageobject/Patient/PatientDoctorNotes.ts diff --git a/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts new file mode 100644 index 00000000000..5b0ceac0c8e --- /dev/null +++ b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts @@ -0,0 +1,61 @@ +import LoginPage from "../../pageobject/Login/LoginPage"; +import { PatientPage } from "../../pageobject/Patient/PatientCreation"; +import { PatientDoctorNotes } from "../../pageobject/Patient/PatientDoctorNotes"; + +describe("Patient Discussion notes in the consultation page", () => { + const loginPage = new LoginPage(); + const patientPage = new PatientPage(); + const patientDoctorNotes = new PatientDoctorNotes(); + const patientName = "Dummy Patient 4"; + const patientNurseNote = "Test nurse Notes"; + const patientNurseReplyNote = "Test nurse reply Notes"; + const discussionNotesSubscribeWarning = + "Please subscribe to notifications to get live updates on discussion notes."; + const discussionNotesSuccessMessage = "Note added successfully"; + + before(() => { + loginPage.loginAsDisctrictAdmin(); + cy.saveLocalStorage(); + }); + + beforeEach(() => { + cy.restoreLocalStorage(); + cy.clearLocalStorage(/filters--.+/); + cy.awaitUrl("/patients"); + }); + + it("Create a nurse note for a patient and verify both ID received the messages", () => { + // Create a doctor notes a with a district admin + patientPage.visitPatient(patientName); + patientDoctorNotes.visitDiscussionNotesPage(); + cy.verifyNotification(discussionNotesSubscribeWarning); + cy.closeNotification(); + // switch the switch to nurse note, as the bydefault is doctornotes + patientDoctorNotes.selectNurseDiscussion(); + patientDoctorNotes.addDiscussionNotes(patientNurseNote); + patientDoctorNotes.postDiscussionNotes(); + cy.verifyNotification(discussionNotesSuccessMessage); + cy.closeNotification(); + // verify the auto-switching of tab to nurse notes if the user is a nurse + cy.get("p").contains("Sign Out").click(); + loginPage.loginManuallyAsNurse(); + loginPage.ensureLoggedIn(); + cy.visit("/patients"); + patientPage.visitPatient(patientName); + patientDoctorNotes.visitDiscussionNotesPage(); + // verify the message is received from admin + cy.verifyNotification(discussionNotesSubscribeWarning); + cy.closeNotification(); + patientDoctorNotes.verifyDiscussionMessage(patientNurseNote); + // Post a reply comment to the message + patientDoctorNotes.addDiscussionNotes(patientNurseReplyNote); + patientDoctorNotes.postDiscussionNotes(); + cy.verifyNotification(discussionNotesSuccessMessage); + cy.closeNotification(); + patientDoctorNotes.verifyDiscussionMessage(patientNurseReplyNote); + }); + + afterEach(() => { + cy.saveLocalStorage(); + }); +}); diff --git a/cypress/e2e/patient_spec/PatientManage.cy.ts b/cypress/e2e/patient_spec/PatientManage.cy.ts deleted file mode 100644 index 22d77aa2fda..00000000000 --- a/cypress/e2e/patient_spec/PatientManage.cy.ts +++ /dev/null @@ -1,48 +0,0 @@ -import LoginPage from "../../pageobject/Login/LoginPage"; -import { PatientConsultationPage } from "../../pageobject/Patient/PatientConsultation"; -import { PatientPage } from "../../pageobject/Patient/PatientCreation"; - -describe("Patient", () => { - const loginPage = new LoginPage(); - const patientPage = new PatientPage(); - const patientConsultationPage = new PatientConsultationPage(); - - before(() => { - loginPage.loginAsDisctrictAdmin(); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/patients"); - }); - - // it("Create Patient shift requests.", () => { - // patientPage.visitPatient(); - // patientConsultationPage.visitShiftRequestPage(); - // patientConsultationPage.enterPatientShiftDetails( - // "Test User", - // phone_number, - // "Dummy Shifting", - // "Reason" - // ); - // patientConsultationPage.createShiftRequest(); - // patientConsultationPage.verifySuccessNotification( - // "Shift request created successfully" - // ); - // }); - // commented out the shifting request, as logic need to be re-visited - - it("Post discussion notes for an already created patient", () => { - patientPage.visitPatient("Dummy Patient 3"); - patientConsultationPage.visitDoctorNotesPage(); - patientConsultationPage.addDoctorsNotes("Test Doctor Notes"); - patientConsultationPage.postDoctorNotes(); - cy.verifyNotification("Note added successfully"); - }); - - afterEach(() => { - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/pageobject/Login/LoginPage.ts b/cypress/pageobject/Login/LoginPage.ts index c75a024ae03..3dfd267fab2 100644 --- a/cypress/pageobject/Login/LoginPage.ts +++ b/cypress/pageobject/Login/LoginPage.ts @@ -19,6 +19,12 @@ class LoginPage { cy.get("button").contains("Login").click(); } + loginManuallyAsNurse(): void { + cy.get("input[id='username']").click().type("dummynurse1"); + cy.get("input[id='password']").click().type("Coronasafe@123"); + cy.get("button").contains("Login").click(); + } + login(username: string, password: string): void { cy.loginByApi(username, password); } diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index e4a9810141e..cc5b8e19465 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -110,30 +110,4 @@ export class PatientConsultationPage { ); cy.wait(3000); } - - visitShiftRequestPage() { - cy.get("#create_shift_request").click(); - } - - createShiftRequest() { - cy.intercept("POST", "**/api/v1/shift/").as("createShiftRequest"); - cy.get("#submit").click(); - cy.wait("@createShiftRequest").its("response.statusCode").should("eq", 201); - } - - visitDoctorNotesPage() { - cy.get("#patient_doctor_notes").scrollIntoView(); - cy.get("#patient_doctor_notes").click(); - } - - addDoctorsNotes(notes: string) { - cy.get("#doctor_notes_textarea").scrollIntoView(); - cy.get("#doctor_notes_textarea").click().type(notes); - } - - postDoctorNotes() { - cy.intercept("POST", "**/api/v1/patient/*/notes").as("postDoctorNotes"); - cy.get("#add_doctor_note_button").click(); - cy.wait("@postDoctorNotes").its("response.statusCode").should("eq", 201); - } } diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index 739601d5b56..db3c10fdcb5 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -14,6 +14,7 @@ export class PatientPage { cy.get("#name").click().type(patientName); cy.intercept("GET", "**/api/v1/consultation/**").as("getPatient"); cy.get("#patient-name-list").contains(patientName).click(); + cy.wait(2000); cy.wait("@getPatient").its("response.statusCode").should("eq", 200); cy.get("#patient-name-consultation") .should("be.visible") diff --git a/cypress/pageobject/Patient/PatientDoctorNotes.ts b/cypress/pageobject/Patient/PatientDoctorNotes.ts new file mode 100644 index 00000000000..9538b0eed3b --- /dev/null +++ b/cypress/pageobject/Patient/PatientDoctorNotes.ts @@ -0,0 +1,29 @@ +export class PatientDoctorNotes { + visitDiscussionNotesPage() { + cy.get("#patient_discussion_notes").scrollIntoView(); + cy.get("#patient_discussion_notes").click(); + } + + addDiscussionNotes(notes: string) { + cy.wait(2000); + cy.get("#discussion_notes_textarea").scrollIntoView(); + cy.get("#discussion_notes_textarea").click().type(notes); + } + + selectNurseDiscussion() { + cy.get("#patient-note-tab-Nurses").scrollIntoView(); + cy.get("#patient-note-tab-Nurses").click(); + } + + verifyDiscussionMessage(text: string) { + cy.get("#patient-notes-list").contains(text); + } + + postDiscussionNotes() { + cy.intercept("POST", "**/api/v1/patient/*/notes").as("postDiscussionNotes"); + cy.get("#add_doctor_note_button").click(); + cy.wait("@postDiscussionNotes") + .its("response.statusCode") + .should("eq", 201); + } +} diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx index f2c2644afda..78f7022b683 100644 --- a/src/Components/Facility/ConsultationDetails/index.tsx +++ b/src/Components/Facility/ConsultationDetails/index.tsx @@ -288,7 +288,7 @@ export const ConsultationDetails = (props: any) => { Patient Details showPatientNotesPopup ? navigate( diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx index ccf71cdb0b6..cf7d9c61ef9 100644 --- a/src/Components/Facility/ConsultationDoctorNotes/index.tsx +++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx @@ -11,7 +11,7 @@ import routes from "../../../Redux/api.js"; import request from "../../../Utils/request/request.js"; import useQuery from "../../../Utils/request/useQuery.js"; import useKeyboardShortcut from "use-keyboard-shortcut"; -import { classNames, isAppleDevice } from "../../../Utils/utils.js"; +import { classNames, isAppleDevice, keysOf } from "../../../Utils/utils.js"; import AutoExpandingTextInputFormField from "../../Form/FormFields/AutoExpandingTextInputFormField.js"; import { PATIENT_NOTES_THREADS } from "../../../Common/constants.js"; import useAuthUser from "../../../Common/hooks/useAuthUser.js"; @@ -123,23 +123,19 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { >
- {Object.values(PATIENT_NOTES_THREADS).map((current) => ( + {keysOf(PATIENT_NOTES_THREADS).map((current) => ( ))}
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx index 9b1f7e2424d..d7847c3add7 100644 --- a/src/Components/Facility/PatientNotesSlideover.tsx +++ b/src/Components/Facility/PatientNotesSlideover.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, Dispatch, SetStateAction } from "react"; import * as Notification from "../../Utils/Notifications.js"; import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; import CareIcon from "../../CAREUI/icons/CareIcon"; -import { classNames, isAppleDevice } from "../../Utils/utils"; +import { classNames, isAppleDevice, keysOf } from "../../Utils/utils"; import ButtonV2 from "../Common/components/ButtonV2"; import { useMessageListener } from "../../Common/hooks/useMessageListener"; import PatientConsultationNotesList from "./PatientConsultationNotesList"; @@ -193,23 +193,19 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { {notesActionIcons}
- {Object.values(PATIENT_NOTES_THREADS).map((current) => ( + {keysOf(PATIENT_NOTES_THREADS).map((current) => ( ))}
@@ -223,7 +219,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { />
{ >
- {Object.values(PATIENT_NOTES_THREADS).map((current) => ( + {keysOf(PATIENT_NOTES_THREADS).map((current) => ( ))}
diff --git a/src/Locale/en/Consultation.json b/src/Locale/en/Consultation.json index 65ea63e875c..8282656b560 100644 --- a/src/Locale/en/Consultation.json +++ b/src/Locale/en/Consultation.json @@ -55,5 +55,7 @@ "back_dated_encounter_date_caution": "You are creating an encounter for", "encounter_duration_confirmation": "The duration of this encounter would be", "consultation_notes": "General Instructions (Advice)", - "procedure_suggestions": "Procedure Suggestions" -} + "procedure_suggestions": "Procedure Suggestions", + "patient_notes_thread__Doctors": "Doctor's Discussions", + "patient_notes_thread__Nurses": "Nurse's Discussions" +} \ No newline at end of file diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index 716f0851464..46832e76228 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -525,3 +525,10 @@ export const celsiusToFahrenheit = (celsius: number) => { export const fahrenheitToCelsius = (fahrenheit: number) => { return ((fahrenheit - 32) * 5) / 9; }; + +/** + * Although same as `Objects.keys(...)`, this provides better type-safety. + */ +export const keysOf = (obj: T) => { + return Object.keys(obj) as (keyof T)[]; +};