-
Notifications
You must be signed in to change notification settings - Fork 532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Cypress Test Suite for Facility Notice Board Functionality Verification #9045
Changes from all commits
66d6ef4
1566910
dd38cef
76dac1e
db8c5ec
cbe768d
9a1ad6c
d3d2034
e6970b7
73d44a1
b800349
c2069bf
28d43b0
87196e3
1d187b2
b7bed31
4c84e13
ec37084
f196fbe
958f148
f030749
0fb706c
7fa0842
e076c3e
461dc91
9f80448
07b9d8b
0690862
c306fce
93924c6
edc48d2
1ff02f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2,13 +2,15 @@ | |||||||||||||||||||||||||||||||||
import { AssetPagination } from "../../pageobject/Asset/AssetPagination"; | ||||||||||||||||||||||||||||||||||
import FacilityPage from "../../pageobject/Facility/FacilityCreation"; | ||||||||||||||||||||||||||||||||||
import FacilityHome from "../../pageobject/Facility/FacilityHome"; | ||||||||||||||||||||||||||||||||||
import FacilityNotify from "../../pageobject/Facility/FacilityNotify"; | ||||||||||||||||||||||||||||||||||
import LoginPage from "../../pageobject/Login/LoginPage"; | ||||||||||||||||||||||||||||||||||
import ManageUserPage from "../../pageobject/Users/ManageUserPage"; | ||||||||||||||||||||||||||||||||||
import { UserPage } from "../../pageobject/Users/UserSearch"; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
describe("Facility Homepage Function", () => { | ||||||||||||||||||||||||||||||||||
const loginPage = new LoginPage(); | ||||||||||||||||||||||||||||||||||
const facilityHome = new FacilityHome(); | ||||||||||||||||||||||||||||||||||
const facilityNotify = new FacilityNotify(); | ||||||||||||||||||||||||||||||||||
const facilityPage = new FacilityPage(); | ||||||||||||||||||||||||||||||||||
const manageUserPage = new ManageUserPage(); | ||||||||||||||||||||||||||||||||||
const userPage = new UserPage(); | ||||||||||||||||||||||||||||||||||
|
@@ -22,6 +24,8 @@ describe("Facility Homepage Function", () => { | |||||||||||||||||||||||||||||||||
const district = "Ernakulam"; | ||||||||||||||||||||||||||||||||||
const localBody = "Aikaranad"; | ||||||||||||||||||||||||||||||||||
const facilityType = "Private Hospital"; | ||||||||||||||||||||||||||||||||||
const notificationErrorMsg = "Message cannot be empty"; | ||||||||||||||||||||||||||||||||||
const notificationMessage = "Test Notification"; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
before(() => { | ||||||||||||||||||||||||||||||||||
loginPage.loginAsDistrictAdmin(); | ||||||||||||||||||||||||||||||||||
|
@@ -30,6 +34,7 @@ describe("Facility Homepage Function", () => { | |||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
beforeEach(() => { | ||||||||||||||||||||||||||||||||||
cy.restoreLocalStorage(); | ||||||||||||||||||||||||||||||||||
cy.clearLocalStorage(/filters--.+/); | ||||||||||||||||||||||||||||||||||
cy.awaitUrl("/facility"); | ||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
|
@@ -41,9 +46,6 @@ describe("Facility Homepage Function", () => { | |||||||||||||||||||||||||||||||||
facilityHome.clickViewCnsButton(); | ||||||||||||||||||||||||||||||||||
facilityHome.verifyCnsUrl(); | ||||||||||||||||||||||||||||||||||
facilityHome.navigateBack(); | ||||||||||||||||||||||||||||||||||
// view notify button | ||||||||||||||||||||||||||||||||||
facilityHome.clickFacilityNotifyButton(); | ||||||||||||||||||||||||||||||||||
facilityHome.verifyAndCloseNotifyModal(); | ||||||||||||||||||||||||||||||||||
// view facility button | ||||||||||||||||||||||||||||||||||
facilityHome.clickViewFacilityDetails(); | ||||||||||||||||||||||||||||||||||
facilityPage.getFacilityName().should("be.visible"); | ||||||||||||||||||||||||||||||||||
|
@@ -134,6 +136,51 @@ describe("Facility Homepage Function", () => { | |||||||||||||||||||||||||||||||||
facilityHome.verifyLiveMonitorUrl(); | ||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
it("Verify Notice Board Functionality", () => { | ||||||||||||||||||||||||||||||||||
// search facility and verify it's loaded or not | ||||||||||||||||||||||||||||||||||
manageUserPage.interceptFacilitySearchReq(); | ||||||||||||||||||||||||||||||||||
manageUserPage.typeFacilitySearch(facilityName); | ||||||||||||||||||||||||||||||||||
manageUserPage.verifyFacilitySearchReq(); | ||||||||||||||||||||||||||||||||||
// verify facility name and card reflection | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyUrlContains("Dummy+Facility+40"); | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid hardcoding URLs in tests. Using a hardcoded URL - facilityNotify.verifyUrlContains("Dummy+Facility+40");
+ facilityNotify.verifyUrlContains(encodeURIComponent(facilityName));
|
||||||||||||||||||||||||||||||||||
facilityPage.verifyFacilityBadgeContent(facilityName); | ||||||||||||||||||||||||||||||||||
manageUserPage.assertFacilityInCard(facilityName); | ||||||||||||||||||||||||||||||||||
// send notification to a facility | ||||||||||||||||||||||||||||||||||
facilityHome.clickFacilityNotifyButton(); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyFacilityName(facilityName); | ||||||||||||||||||||||||||||||||||
facilityNotify.fillNotifyText(notificationMessage); | ||||||||||||||||||||||||||||||||||
facilityNotify.interceptPostNotificationReq(); | ||||||||||||||||||||||||||||||||||
cy.submitButton("Notify"); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyPostNotificationReq(); | ||||||||||||||||||||||||||||||||||
cy.verifyNotification("Facility Notified"); | ||||||||||||||||||||||||||||||||||
cy.closeNotification(); | ||||||||||||||||||||||||||||||||||
cy.wait(2000); | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Replace hardcoded wait with explicit wait conditions. Using
- cy.wait(2000);
+ cy.get('[data-testid="notification-popup"]')
+ .should('not.exist');
- loginPage.ensureLoggedIn();
- loginPage.clickSignOutBtn();
+ cy.session('nurse', () => {
+ loginPage.loginManuallyAsNurse();
+ }); Also applies to: 180-181 |
||||||||||||||||||||||||||||||||||
// Verify the frontend error on empty message | ||||||||||||||||||||||||||||||||||
facilityHome.clickFacilityNotifyButton(); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyFacilityName(facilityName); | ||||||||||||||||||||||||||||||||||
cy.submitButton("Notify"); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyErrorMessage(notificationErrorMsg); | ||||||||||||||||||||||||||||||||||
// close pop-up and verify | ||||||||||||||||||||||||||||||||||
facilityHome.verifyAndCloseNotifyModal(); | ||||||||||||||||||||||||||||||||||
// signout as district admin and login as a Nurse | ||||||||||||||||||||||||||||||||||
loginPage.ensureLoggedIn(); | ||||||||||||||||||||||||||||||||||
loginPage.clickSignOutBtn(); | ||||||||||||||||||||||||||||||||||
loginPage.loginManuallyAsNurse(); | ||||||||||||||||||||||||||||||||||
// Verify Notice Board Reflection | ||||||||||||||||||||||||||||||||||
facilityNotify.interceptGetNotificationReq("MESSAGE"); | ||||||||||||||||||||||||||||||||||
facilityNotify.visitNoticeBoard(); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyGetNotificationReq(); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyFacilityNoticeBoardMessage(notificationMessage); | ||||||||||||||||||||||||||||||||||
facilityNotify.interceptGetNotificationReq(); | ||||||||||||||||||||||||||||||||||
// Verify Sidebar Notification Reflection | ||||||||||||||||||||||||||||||||||
facilityNotify.openNotificationSlide(); | ||||||||||||||||||||||||||||||||||
facilityNotify.verifyGetNotificationReq(); | ||||||||||||||||||||||||||||||||||
cy.verifyContentPresence("#notification-slide-msg", [notificationMessage]); | ||||||||||||||||||||||||||||||||||
Comment on lines
+173
to
+178
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add explicit wait conditions for notification visibility. The notification checks might be flaky without proper wait conditions. - facilityNotify.verifyFacilityNoticeBoardMessage(notificationMessage);
+ cy.get('#notification-message')
+ .should('be.visible')
+ .and('contain.text', notificationMessage);
facilityNotify.interceptGetNotificationReq();
facilityNotify.openNotificationSlide();
facilityNotify.verifyGetNotificationReq();
- cy.verifyContentPresence("#notification-slide-msg", [notificationMessage]);
+ cy.get("#notification-slide-msg")
+ .should('be.visible')
+ .and('contain.text', notificationMessage); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||
facilityNotify.closeNotificationSlide(); | ||||||||||||||||||||||||||||||||||
loginPage.ensureLoggedIn(); | ||||||||||||||||||||||||||||||||||
loginPage.clickSignOutBtn(); | ||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||
Comment on lines
+139
to
+182
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Test case needs to be split into smaller, focused tests. The current test case is doing too much and violates the Single Responsibility Principle. It should be split into smaller, focused tests following the AAA (Arrange-Act-Assert) pattern. Split into these focused test cases: describe('Notice Board Functionality', () => {
beforeEach(() => {
cy.restoreLocalStorage();
// Common setup
manageUserPage.interceptFacilitySearchReq();
manageUserPage.typeFacilitySearch(facilityName);
manageUserPage.verifyFacilitySearchReq();
});
it('should validate empty notification message', () => {
facilityHome.clickFacilityNotifyButton();
cy.submitButton("Notify");
facilityNotify.verifyErrorMessage(notificationErrorMsg);
});
it('should successfully send notification as district admin', () => {
facilityHome.clickFacilityNotifyButton();
facilityNotify.fillNotifyText(notificationMessage);
facilityNotify.interceptPostNotificationReq();
cy.submitButton("Notify");
facilityNotify.verifyPostNotificationReq();
cy.verifyNotification("Facility Notified");
});
it('should display notification to nurse', () => {
loginPage.loginManuallyAsNurse();
facilityNotify.interceptGetNotificationReq();
facilityNotify.visitNoticeBoard();
facilityNotify.verifyGetNotificationReq();
cy.verifyContentPresence("#notification-message", [notificationMessage]);
facilityNotify.openNotificationSlide();
cy.verifyContentPresence("#notification-slide-msg", [notificationMessage]);
});
}); 🛠️ Refactor suggestion Add error handling test cases. The test suite lacks error scenarios that could occur in production. Add these test cases: it('should handle network failure when sending notification', () => {
facilityHome.clickFacilityNotifyButton();
facilityNotify.fillNotifyText(notificationMessage);
cy.intercept('POST', '**/api/v1/notification/notify', {
forceNetworkError: true
}).as('networkError');
cy.submitButton("Notify");
cy.wait('@networkError');
cy.verifyNotification("Failed to send notification");
});
it('should handle server error when sending notification', () => {
facilityHome.clickFacilityNotifyButton();
facilityNotify.fillNotifyText(notificationMessage);
cy.intercept('POST', '**/api/v1/notification/notify', {
statusCode: 500,
body: { error: 'Internal Server Error' }
}).as('serverError');
cy.submitButton("Notify");
cy.wait('@serverError');
cy.verifyNotification("Server error occurred");
}); 🛠️ Refactor suggestion Add cleanup in afterEach hook. The test modifies application state but doesn't clean up afterwards. afterEach(() => {
cy.saveLocalStorage();
+ // Clean up notifications created during tests
+ if (cy.state('test').title.includes('Notice Board')) {
+ facilityNotify.interceptDeleteNotificationReq();
+ facilityNotify.deleteAllNotifications();
+ facilityNotify.verifyDeleteNotificationReq();
+ }
});
|
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
afterEach(() => { | ||||||||||||||||||||||||||||||||||
cy.saveLocalStorage(); | ||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,58 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
export default class FacilityNotify { | ||||||||||||||||||||||||||||||||||||||||||||||||||
verifyFacilityName(facilityName: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.verifyContentPresence("#notify-facility-name", [facilityName]); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
verifyErrorMessage(errorMessage: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.verifyContentPresence(".error-text", [errorMessage]); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+2
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance UI verification methods with better TypeScript and error handling. The verification methods could be more robust with proper type annotations and error handling. - verifyFacilityName(facilityName: string) {
+ verifyFacilityName(facilityName: string): void {
cy.verifyContentPresence("#notify-facility-name", [facilityName])
+ .then($elements => {
+ if ($elements.length === 0) {
+ throw new Error(`Facility name "${facilityName}" not found in the DOM`);
+ }
+ });
}
- verifyErrorMessage(errorMessage: string) {
+ verifyErrorMessage(errorMessage: string): void {
cy.verifyContentPresence(".error-text", [errorMessage])
+ .then($elements => {
+ if ($elements.length === 0) {
+ throw new Error(`Error message "${errorMessage}" not found in the DOM`);
+ }
+ });
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
fillNotifyText(message: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#NotifyModalMessageInput").scrollIntoView(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#NotifyModalMessageInput").click().type(message); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize notification text input method. The method has duplicate - fillNotifyText(message: string) {
+ fillNotifyText(message: string): void {
- cy.get("#NotifyModalMessageInput").scrollIntoView();
- cy.get("#NotifyModalMessageInput").click().type(message);
+ cy.get("#NotifyModalMessageInput")
+ .scrollIntoView()
+ .should('be.visible')
+ .click()
+ .clear()
+ .type(message, { delay: 50 })
+ .should('have.value', message);
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
verifyFacilityNoticeBoardMessage(message: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#notification-message", { timeout: 10000 }).should("be.visible"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.verifyContentPresence("#notification-message", [message]); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+15
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add retry and error handling for notification message verification. The message verification could be more robust with proper error handling and retry logic. verifyFacilityNoticeBoardMessage(message: string): void {
- cy.get("#notification-message", { timeout: 10000 }).should("be.visible");
- cy.verifyContentPresence("#notification-message", [message]);
+ cy.get("#notification-message", { timeout: 10000 })
+ .should("be.visible")
+ .then($el => {
+ if (!$el.length) {
+ throw new Error('Notification message element not found');
+ }
+ cy.wrap($el)
+ .invoke('text')
+ .should('include', message, {
+ retry: {
+ tries: 3,
+ delay: 1000
+ }
+ });
+ });
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
openNotificationSlide() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#notification-slide-btn").should("be.visible").click(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
closeNotificationSlide() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#close-slide-over").should("be.visible").click(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
visitNoticeBoard() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("a[href='/notice_board']").should("be.visible").click(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
visitNotificationSideBar() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.get("#notification-slide-btn").should("be.visible").click(); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
verifyUrlContains(substring: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.url().should("include", substring); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
interceptPostNotificationReq() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.intercept("POST", "**/api/v1/notification/notify").as("notifyFacility"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
verifyPostNotificationReq() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.wait("@notifyFacility").its("response.statusCode").should("eq", 204); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
interceptGetNotificationReq(event: string = "") { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.intercept( | ||||||||||||||||||||||||||||||||||||||||||||||||||
"GET", | ||||||||||||||||||||||||||||||||||||||||||||||||||
`**/api/v1/notification/?offset=0&event=${event}&*=SYSTEM`, | ||||||||||||||||||||||||||||||||||||||||||||||||||
).as("getNotifications"); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
verifyGetNotificationReq() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
cy.wait("@getNotifications").its("response.statusCode").should("eq", 200); | ||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,6 +99,14 @@ export class ManageUserPage { | |
cy.get("#search").click().type(facilityName); | ||
} | ||
|
||
interceptFacilitySearchReq() { | ||
cy.intercept("GET", "**/api/v1/facility/**").as("searchFacility"); | ||
} | ||
|
||
verifyFacilitySearchReq() { | ||
cy.wait("@searchFacility").its("response.statusCode").should("eq", 200); | ||
} | ||
Comment on lines
+106
to
+108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider enhancing error handling for API verification. While the status code check is good, we should also verify the response structure to ensure data integrity. Consider this enhancement: verifyFacilitySearchReq() {
- cy.wait("@searchFacility").its("response.statusCode").should("eq", 200);
+ cy.wait("@searchFacility").then((interception) => {
+ expect(interception.response?.statusCode).to.eq(200);
+ expect(interception.response?.body).to.have.property("data");
+ // Add more specific response body checks based on API contract
+ });
}
|
||
|
||
assertFacilityInCard(facilityName: string) { | ||
cy.get("#facility-name-card").should("contain", facilityName); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance test notification message content.
The current test message is too simple and may not catch real-world issues. Consider using a more realistic message that includes:
📝 Committable suggestion