-
Notifications
You must be signed in to change notification settings - Fork 248
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
(test) O3-2428: E2E test for appointment scheduling #1664
Conversation
@jayasanka-sack May you can look into this PR.
|
@jayasanka-sack @RandilaP May you can check this PR? |
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.
Great progress, @Vijaykv5! 🎉 I've reviewed the changes and added some comments. Well done!
e2e/specs/add-appointments.spec.ts
Outdated
await test.step('When I click on appointment tab', async () => { | ||
await appointmentsPage.goto(patient.uuid); | ||
}); | ||
//test to add appointment |
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.
The test steps are sufficiently descriptive; therefore, additional comments are unnecessary.
e2e/specs/add-appointments.spec.ts
Outdated
const appointmentsPage = new AppointmentsPage(page); | ||
await test.step('When I click on appointment tab', async () => { |
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.
const appointmentsPage = new AppointmentsPage(page); | |
await test.step('When I click on appointment tab', async () => { | |
const appointmentsPage = new AppointmentsPage(page); | |
await test.step('When I go to the appointment tab in the patient chart', async () => { |
e2e/specs/add-appointments.spec.ts
Outdated
await page.click('button:has-text("Add")'); | ||
}); | ||
|
||
await test.step('When I select Mobile Clinic location', async () => { |
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.
await test.step('When I select Mobile Clinic location', async () => { | |
await test.step('And I select Mobile Clinic location', async () => { |
e2e/specs/add-appointments.spec.ts
Outdated
}); | ||
|
||
await test.step('When I select Mobile Clinic location', async () => { | ||
await page.locator('#location').selectOption('8d9045ad-50f0-45b8-93c8-3ed4bce19dbf'); |
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.
Please refer to @ibacher 's comment on slack:
Always prefer grabbing the element by user-facing text (in this case the ARIA label) rather than technical details like id / class / tag as we want our tests to be robust to markup changes.
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.
@jayasanka-sack There's no element under options other than changing their values of location.
We have used the same here
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.
Can we try with something akin to what's showcased in the Playwright documentation (link)?
await page.getByLabel('Choose a color').selectOption({ label: 'Blue' });
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.
This applies for other fields as well.
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.
Oops I missed that!
Fixed now :)
Thanks
e2e/specs/add-appointments.spec.ts
Outdated
await page.locator('#datePickerInput').fill('18/02/2024'); | ||
}); | ||
|
||
await test.step('And I set the “Duration”', async () => { |
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.
await test.step('And I set the “Duration”', async () => { | |
await test.step('And I set the “Duration” to 60', async () => { |
e2e/specs/add-appointments.spec.ts
Outdated
await expect(page.getByText(/Appointment scheduled/i)).toBeVisible(); | ||
}); | ||
// test for editing the appointment | ||
await test.step('And I choose the "Edit" option from the popup menu', async () => { |
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.
Break this down to two steps:
- When I click the options kebab menu in the appointment
- And I choose the "Edit" option
This applies to the deletion too.
Also add the following step
- Then I should see the Edit an appointment workspace
e2e/specs/add-appointments.spec.ts
Outdated
await page.getByRole('menuitem', { name: 'Cancel' }).click(); | ||
}); | ||
|
||
await test.step('And I cancel the appointmen', async () => { |
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.
- Then I should see a confirmation modal
- When I click the "Cancel appointment" button to confirm
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.
Good job @Vijaykv5
e2e/pages/appointments-page.ts
Outdated
export class AppointmentsPage { | ||
constructor(readonly page: Page) {} | ||
|
||
readonly appointmentsTable = () => this.page.getByRole('table', { name: /appointments/i }); |
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.
readonly appointmentsTable = () => this.page.getByRole('table', { name: /appointments/i }); | |
readonly appointmentsTable = () => this.page.getByRole('table', { name: /appointments/i }); |
I think it's best to Add a getByTestId to the table locator
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.
It's better to avoid the use of ids, classes as much as possible. #1664 (comment)
e2e/specs/add-appointments.spec.ts
Outdated
}); | ||
|
||
await test.step('And I set the “Duration” to 60', async () => { | ||
await page.locator('#duration').fill('60'); |
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.
await page.locator('#duration').fill('60'); | |
await page.locator('#duration').fill('60'); |
Use getById
e2e/specs/add-appointments.spec.ts
Outdated
}); | ||
|
||
await test.step('And I set the “Duration” of the appointment”', async () => { | ||
await page.locator('#duration').fill('80'); |
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.
await page.locator('#duration').fill('80'); | |
await page.locator('#duration').fill('80'); |
Here as well
Thanks for the Review @jayasanka-sack @RandilaP |
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.
@Vijaykv5 Good to see your progress
e2e/specs/add-appointments.spec.ts
Outdated
await test.step('And I set date for tomorrow', async () => { | ||
await page.fill('input[placeholder="dd/mm/yyyy"]', '30/03/2024'); | ||
}); |
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.
await test.step('And I set date for tomorrow', async () => { | |
await page.fill('input[placeholder="dd/mm/yyyy"]', '30/03/2024'); | |
}); | |
await test.step('And I set date for tomorrow', async () => { | |
await page.fill('input[placeholder="dd/mm/yyyy"]', '30/03/2024'); | |
}); |
Nice to see your progress in tests @Vijaykv5. I would like to highlight that we are using these E2E tests again and again when someone sends a PR. So after the date that u added in this test these tests will fail because this appointment is going to move to the past appointment section. I would like to suggest you if you are adding a date manually make sure add a previous date and in the test make sure to go through the past appointment section.
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.
You can use Js to get tomorrow's date.
ex:
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
await page.fill('input[placeholder="dd/mm/yyyy"]', tomorrow.toLocaleDateString('en-GB'));
btw, can't we use page.getByLabel().fill
here?
e2e/specs/add-appointments.spec.ts
Outdated
await test.step('And I change the date to Today', async () => { | ||
await page.fill('input[placeholder="dd/mm/yyyy"]', '28/03/2024'); | ||
}); |
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.
Here as well
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.
Yes but I think as @jayasanka-sack It would best way to make into today's date.
@Vijaykv5 Make this PR a draft PR |
You can try to view the report and check what's going wrong: https://o3-docs.openmrs.org/docs/frontend-modules/testing#view-test-reports-from-github-actions--bamboo |
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.
@Vijaykv5 Good job
e2e/specs/add-appointments.spec.ts
Outdated
}); | ||
|
||
await test.step('When I change to “Inpatient ward” location', async () => { | ||
await page.getByLabel('Select location').selectOption('Inpatient Ward'); |
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.
await page.getByLabel('Select location').selectOption('Inpatient Ward'); | |
await page.getByLabel('Select location').selectOption('Inpatient Ward'); |
Can you check in other E2E tests how they select options in the tests. Test is failing because of it. Download the test report and check the video where it's failing.
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.
Great work @Vijaykv5! 👍
I've added a few comments to address.
e2e/specs/add-appointments.spec.ts
Outdated
let patient: Patient; | ||
|
||
test.beforeEach(async ({ api }) => { | ||
patient = await generateRandomPatient(api); |
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.
Should we start patient visit before recording the appointment, @Vijaykv5 what do you think?
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.
Oops I missed that out. Yes that right!
Thank you @kdaud
I've updated new changes
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.
Appointments should be able to be scheduled without requiring an active visit. That's a kind of basic feature of an appointment scheduling application.
e2e/specs/add-appointments.spec.ts
Outdated
patient = await generateRandomPatient(api); | ||
}); | ||
|
||
test('Add appointment for a patient, edit the added appointment and cancel it', async ({ page, api }) => { |
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.
I would suggest we re-title the test to
Add, edit and cancel an appointment
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.
I would suggest this be broken up into three tests, as it's three features:
- Add an appointment
- Edit an existing appointment
- Cancel an existing appointment
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.
I would suggest this be broken up into three tests, as it's three features:
- Add an appointment
- Edit an existing appointment
- Cancel an existing appointment
@ibacher we are following this doc for the tests. So for adding tests for appointment section, is it better to do it as a whole test for appointment section?
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.
I would suggest this be broken up into three tests, as it's three features:
@jayasanka-sack what do you think concerning Ian's idea?
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.
I suggested using a single flow to minimize API usage for the data population. But, after seeing how lengthy the test will be, I also think breaking it into three tests would simplify it.
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.
I also think breaking into three tests would make it much simpler.
@jayasanka-sack will this apply across all tests with the add, edit and delete workflows? cc: @denniskigen
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.
We've got just a few that contains in single flow. Let's leave them as is for the time being and beef them up later when we can. Our priority is to expand our coverage. But, if you happen to have some extra time, feel free to tweak them too.
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.
There's definitely a balance of concerns, but if the main concern is how much data is created during, it should be possible, for example, to create a single patient and run a suite of tests using that single patient (i.e., there's no reason here that the patient needs to be created in a beforeEach()
rather than a beforeAll()
, especially since we're fundamentally only working on data attached to the patient record rather than the patient record itself).
My concern here is related to this point in that doc: "We want business-level users to easily be able to see a report that reassures them about what functionality is covered". Specifically, if the "Add appointment for a patient, edit the added appointment and cancel it" test fails, then, as a business user, I'm stuck regarding that whole feature as broken, which is much more concerning than saying "We can currently add appointments, but something broke the cancellation flow", for example.
I also agree with @jayasanka-sack's point that the priority should be improving test coverage, not going back and revising everything to match some "gold standard" for how tests are written.
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.
Created a ticket to monitor the proposed E2E test approach.
I would suggest to rename the spec file to 'appointments.spec.ts'. @Vijaykv5 let me know your thought? |
@Vijaykv5 as a result of O3-2891 we need to move the work on this PR to https://github.com/openmrs/openmrs-esm-patient-management/ |
Do I need to add the PR there? |
yes |
I'm closing this in favour of a new PR in https://github.com/openmrs/openmrs-esm-patient-management following #1739. Let me know if you need any help setting that up, @Vijaykv5. |
@denniskigen I have made a New PR here |
I've responded to your question in the other PR. |
Requirements
Summary
This PR covers E2E test to test the appointment workflow.
The test involves adding an appointment for a patient, edit the added appointment, and cancel it.
Screenshots
appointments-test.mov
Related Issue
O3-2428