From 3b9da999e99fa7f3150a63f9f79306d7ecbbd31b Mon Sep 17 00:00:00 2001 From: kdaud Date: Thu, 22 Aug 2024 22:23:32 +0300 Subject: [PATCH] C2C-345: E2E tests for Bahmni-Odoo flows --- e2e/tests/bahmni-odoo-flows.spec.ts | 195 +++++++++++++++++++++++++++- e2e/tests/lab-orders.spec.ts | 1 + e2e/tests/medications.spec.ts | 16 +-- e2e/utils/functions/bahmni.ts | 88 ++++++++++++- e2e/utils/functions/odoo.ts | 1 - playwright.config.ts | 1 - 6 files changed, 274 insertions(+), 28 deletions(-) diff --git a/e2e/tests/bahmni-odoo-flows.spec.ts b/e2e/tests/bahmni-odoo-flows.spec.ts index 1295daa..d7e547f 100644 --- a/e2e/tests/bahmni-odoo-flows.spec.ts +++ b/e2e/tests/bahmni-odoo-flows.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from '@playwright/test'; import { Odoo } from '../utils/functions/odoo'; +import { BAHMNI_URL, ODOO_URL } from '../utils/configs/globalSetup'; import { Bahmni, patientName } from '../utils/functions/bahmni'; let bahmni: Bahmni; @@ -15,17 +16,16 @@ test.beforeEach(async ({ page }) => { await expect(page.getByText(/admin/i)).toBeVisible(); await expect(page.getByText(/appointment scheduling/i)).toBeVisible(); await expect(page.getByText(/patient documents/i)).toBeVisible(); + await bahmni.registerPatient(); + await bahmni.goToHomePage(); }); test('Ordering a lab test for a Bahmni patient creates the corresponding Odoo customer with a filled quotation.', async ({ page }) => { // setup - await bahmni.registerPatient(); + await bahmni.goToLabSamples(); // replay - await bahmni.goToLabSamples(); - await page.getByText('Blood', { exact: true }).click(); - await page.getByText('Malaria').click(); - await bahmni.saveOrder(); + await bahmni.createLabOrder(); // verify await odoo.open(); @@ -42,6 +42,191 @@ test('Ordering a lab test for a Bahmni patient creates the corresponding Odoo cu await expect(labTest).toContainText('Malaria'); }); + +test('Editing the details of a Bahmni patient with a synced lab order edits the corresponding Odoo customer details.', async ({ page }) => { + // setup + await bahmni.goToLabSamples(); + await bahmni.createLabOrder(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + const statusSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(8) span"); + await expect(statusSelector).toHaveText("Devis"); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.updatePatientDetails(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + const updatedCustomer = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(updatedCustomer).toHaveText(`${patientName.updatedGivenName}` + ' ' + `${patientName.familyName}`); + await expect(statusSelector).toHaveText("Devis"); +}); + +test('Revising a synced Bahmni lab order edits the corresponding Odoo quotation line.', async ({ page }) => { + // setup + await bahmni.goToLabSamples(); + await bahmni.createLabOrder(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + const statusSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(8) span"); + await expect(statusSelector).toHaveText("Devis"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName}` }).click(); + const labTest = await page.locator("td.o_data_cell.o_field_cell.o_list_many2one.o_product_configurator_cell.o_required_modifier>span"); + await expect(labTest).toHaveText('Malaria'); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.goToLabSamples(); + await bahmni.reviseLabOrder(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + await expect(statusSelector).toHaveText("Devis"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).first().click(); + await expect(labTest).not.toContainText('Malaria'); + await expect(labTest).toHaveText('Hematocrite'); +}); + +test('Discontinuing a synced Bahmni lab order edits the corresponding Odoo quotation line.', async ({ page }) => { + // setup + await bahmni.goToLabSamples(); + await bahmni.createLabOrder(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + const statusSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(8) span"); + await expect(statusSelector).toHaveText("Devis"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName}` }).click(); + const labTest = await page.locator("td.o_data_cell.o_field_cell.o_list_many2one.o_product_configurator_cell.o_required_modifier>span"); + await expect(labTest).toHaveText('Malaria'); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.goToLabSamples(); + await bahmni.discontinueLabOrder(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + await expect(statusSelector).toHaveText("Annulé"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).first().click(); + await expect(page.getByText('Malaria')).not.toBeVisible(); +}); + +test('Ordering a drug for a Bahmni patient creates the corresponding Odoo customer with a filled quotation.', async ({ page }) => { + // setup + await bahmni.goToMedications(); + + // replay + await bahmni.createMedication(); + + // verify + await odoo.open(); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + + const statusSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(8) span"); + await expect(statusSelector).toHaveText("Devis"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName}` }).click(); + const drugNameSelector = await page.locator("td.o_data_cell.o_field_cell.o_list_many2one.o_product_configurator_cell.o_required_modifier>span"); + await expect(drugNameSelector).toContainText('Aspirine Co 81mg'); +}); + + +test('Editing the details of a Bahmni patient with a synced drug order edits the corresponding Odoo customer details.', async ({ page }) => { + // setup + await bahmni.goToMedications(); + await bahmni.createMedication(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.updatePatientDetails(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + const updatedCustomer = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(updatedCustomer).toHaveText(`${patientName.updatedGivenName}` + ' ' + `${patientName.familyName}`); +}); + +test('Revising a synced OpenMRS drug order edits the corresponding Odoo quotation line.', async ({ page }) => { + // setup + await bahmni.goToMedications(); + await bahmni.createMedication(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).click(); + const medicationDescrptionSelector = await page.locator("td.o_data_cell.o_field_cell.o_list_text.o_section_and_note_text_cell.o_required_modifier span"); + const drugNameSelector = await page.locator("td.o_data_cell.o_field_cell.o_list_many2one.o_product_configurator_cell.o_required_modifier>span"); + await expect(drugNameSelector).toContainText('Aspirine Co 81mg'); + await expect(medicationDescrptionSelector).toContainText('Aspirine Co 81mg | 560.0 Ampoule(s) | 2.0 Application(s) - Q3H - 5 Semaine(s)'); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.goToMedications(); + await bahmni.editMedicationDetails(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).click(); + await expect(drugNameSelector).toContainText('Aspirine Co 81mg'); + await expect(medicationDescrptionSelector).toContainText('Aspirine Co 81mg | 120.0 Comprime(s) | 4.0 Comprime(s) - Q4H - 5 Jour(s)'); +}); + +test('Discontinuing a synced Bahmni drug order for an Odoo customer with a single quotation line removes the corresponding quotation.', async ({ page }) => { + // setup + await bahmni.goToMedications(); + await bahmni.createMedication(); + await odoo.open(); + await expect(page).toHaveURL(/.*web/); + await odoo.searchCustomer(); + const customerSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(4)"); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + const statusSelector = await page.locator("tr.o_data_row:nth-child(1) td:nth-child(8) span"); + await expect(statusSelector).toHaveText("Devis"); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).click(); + const medicationDescrptionSelector = await page.locator("td.o_data_cell.o_field_cell.o_list_text.o_section_and_note_text_cell.o_required_modifier span"); + const drugNameSelector = await page.locator("td.o_data_cell.o_field_cell.o_list_many2one.o_product_configurator_cell.o_required_modifier>span"); + await expect(drugNameSelector).toContainText('Aspirine Co 81mg'); + await expect(medicationDescrptionSelector).toContainText('Aspirine Co 81mg | 560.0 Ampoule(s) | 2.0 Application(s) - Q3H - 5 Semaine(s)'); + + // replay + await page.goto(`${BAHMNI_URL}`); + await bahmni.goToMedications(); + await bahmni.discontinueMedication(); + + // verify + await page.goto(`${ODOO_URL}`); + await odoo.searchCustomer(); + await expect(customerSelector).toHaveText(`${patientName.givenName + ' ' + patientName.familyName}`); + await expect(statusSelector).toHaveText('Annulé'); + await page.getByRole('cell', { name: `${patientName.givenName + ' ' + patientName.familyName }` }).click(); + await expect(page.getByText('Aspirine Co 81mg')).not.toBeVisible(); +}); + test.afterEach(async ({ page }) => { await bahmni.voidPatient(); await page.close(); diff --git a/e2e/tests/lab-orders.spec.ts b/e2e/tests/lab-orders.spec.ts index 32897d5..9de941e 100644 --- a/e2e/tests/lab-orders.spec.ts +++ b/e2e/tests/lab-orders.spec.ts @@ -19,6 +19,7 @@ test('Create, revise and discontinue lab tests.', async ({ page }) => { await bahmni.registerPatient(); // replay + await bahmni.goToHomePage(); await bahmni.goToLabSamples(); await page.getByText('Blood', { exact: true }).click(); await page.getByText('Malaria').click(); diff --git a/e2e/tests/medications.spec.ts b/e2e/tests/medications.spec.ts index fa3bd11..23bcca6 100644 --- a/e2e/tests/medications.spec.ts +++ b/e2e/tests/medications.spec.ts @@ -19,21 +19,9 @@ test('Create, revise and discontinue a drug order.', async ({ page }) => { await bahmni.registerPatient(); // replay + await bahmni.goToHomePage(); await bahmni.goToMedications(); - await page.locator('#drug-name').type('Aspirine Co 81mg'); - await page.getByText('Aspirine Co 81mg (Comprime)').click(); - await page.locator('#uniform-dose').fill('2'); - await page.locator('#uniform-dose-unit').selectOption('string:Application(s)'); - await page.locator('#frequency').selectOption('string:Q3H'); - await page.locator('#route').selectOption('string:Topique'); - await page.locator('#start-date').fill('2024-08-16'); - await page.locator('#duration').fill('5'); - await page.locator('#duration-unit').selectOption('string:Semaine(s)'); - await page.locator('#total-quantity-unit').selectOption('string:Ampoule(s)'); - await page.locator('#instructions').selectOption('string:Estomac vide'); - await page.locator('#additional-instructions').fill('Take after a meal'); - await page.getByRole('button', { name: 'Add' }).click(); - await bahmni.saveOrder(); + await bahmni.createMedication(); // verify creation const drugNameSelector = await page.locator('#ordered-drug-orders strong.drug-name').first(); diff --git a/e2e/utils/functions/bahmni.ts b/e2e/utils/functions/bahmni.ts index ede1c3f..442d6dd 100644 --- a/e2e/utils/functions/bahmni.ts +++ b/e2e/utils/functions/bahmni.ts @@ -4,6 +4,7 @@ import { BAHMNI_URL } from '../configs/globalSetup'; export var patientName = { givenName : '', familyName : '', + updatedGivenName: '', } export class Bahmni { @@ -20,15 +21,16 @@ export class Bahmni { async registerPatient() { patientName = { - givenName : `e2e_test_${Math.floor(Math.random() * 10000)}`, - familyName : `${(Math.random() + 1).toString(36).substring(2)}`, + givenName : `E2e_test_${Array.from({ length: 4 }, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')}`, + familyName : `${Array.from({ length: 8 }, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')}`, + updatedGivenName : `${Array.from({ length: 8 }, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')}`, } await this.page.goto(`${BAHMNI_URL}/bahmni/registration`); await this.page.locator('a').filter({ hasText: 'Create New' }).click(); await this.page.locator('#givenName').fill(`${patientName.givenName}`); await this.page.locator('#familyName').fill(`${patientName.familyName}`); await this.page.locator('#gender').selectOption('F'); - await this.page.locator('#ageYears').fill('34'); + await this.page.locator('#ageYears').fill(`${Math.floor(Math.random() * 99)}`); await this.page.locator('#view-content div>ul>li button').click(); await expect(this.page.getByRole('button', { name: 'Save' })).toBeEnabled(); await this.page.getByRole('button', { name: 'Priority' }).click(); @@ -41,6 +43,17 @@ export class Bahmni { await this.page.getByText(`${patientName.givenName + ' ' + patientName.familyName}`).click(); } + async updatePatientDetails() { + await this.page.getByRole('link', { name: 'Registration' }).click(); + await this.page.locator('#name').fill(`${patientName.familyName}`); + await this.page.locator('form[name="searchByNameForm"]').getByRole('button', { name: 'Search' }).click(); + await this.page.locator('#view-content td:nth-child(1) a').click(); + await this.page.locator('#givenName').clear(); + await this.page.locator('#givenName').fill(`${patientName.updatedGivenName}`); + await this.page.getByRole('button', { name: 'Save' }).click(); + patientName.givenName = `${patientName.updatedGivenName}`; + }; + async voidPatient() { await this.page.goto(`${BAHMNI_URL}/openmrs/admin/patients/index.htm`); await this.page.getByPlaceholder(' ').type(`${patientName.familyName}`); @@ -52,24 +65,85 @@ export class Bahmni { } async goToLabSamples() { - await this.page.locator('i.fa.fa-home').click(); await this.page.getByRole('link', { name: 'Clinical' }).click(); await this.searchPatient(); await this.page.locator('#view-content :nth-child(1).btn--success').click(); - await this.page.getByText('Orders', { exact: true }).click(); + await this.page.locator('#opd-tabs').getByText('Orders').click(); await expect(this.page.getByText('Lab Samples')).toBeVisible(); } + async createLabOrder() { + await this.page.getByText('Blood', { exact: true }).click(); + await this.page.getByText('Malaria').click(); + await this.saveOrder(); + } + + async reviseLabOrder() { + await this.page.getByText('Blood', { exact: true }).click(); + await this.page.locator('#selected-orders li').filter({ hasText: 'Malaria' }).locator('i').nth(1).click(); + await this.page.getByText('Hematocrit').click(); + await this.saveOrder(); + } + + async discontinueLabOrder() { + await this.page.getByText('Blood', { exact: true }).click(); + await this.page.locator('#selected-orders li').filter({ hasText: 'Malaria' }).locator('i').nth(1).click(); + await this.saveOrder(); + } + + async goToHomePage() { + await this.page.goto(`${BAHMNI_URL}/bahmni/home/`); + await expect(this.page).toHaveURL(/.*home/); + } + async goToMedications() { - await this.page.locator('i.fa.fa-home').click(); await this.page.getByRole('link', { name: 'Clinical' }).click(); await this.searchPatient(); await this.page.locator('#view-content :nth-child(1).btn--success').click(); - await this.page.getByText('Medications', { exact: true }).click(); + await this.page.locator('#opd-tabs').getByText('Medications').click(); await expect(this.page.getByText('Order Drug')).toBeVisible(); await expect(this.page.getByText('Order an Order Set')).toBeVisible(); } + async createMedication() { + await this.page.locator('#drug-name').type('Aspirine Co 81mg'); + await this.page.getByText('Aspirine Co 81mg (Comprime)').click(); + await this.page.locator('#uniform-dose').fill('2'); + await this.page.locator('#uniform-dose-unit').selectOption('string:Application(s)'); + await this.page.locator('#frequency').selectOption('string:Q3H'); + await this.page.locator('#route').selectOption('string:Topique'); + await this.page.locator('#start-date').fill('2024-08-16'); + await this.page.locator('#duration').fill('5'); + await this.page.locator('#duration-unit').selectOption('string:Semaine(s)'); + await this.page.locator('#total-quantity-unit').selectOption('string:Ampoule(s)'); + await this.page.locator('#instructions').selectOption('string:Estomac vide'); + await this.page.locator('#additional-instructions').fill('Take after a meal'); + await expect(this.page.locator('#quantity')).toHaveValue('560'); + await this.page.getByRole('button', { name: 'Add' }).click(); + await this.saveOrder(); + } + + async editMedicationDetails() { + await this.page.locator('i.fa.fa-edit').first().click(); + await this.page.locator('#uniform-dose').clear(); + await this.page.locator('#uniform-dose').fill('4'); + await this.page.locator('#frequency').selectOption('string:Q4H'); + await this.page.locator('#uniform-dose-unit').selectOption('string:Comprime(s)'); + await this.page.locator('#route').selectOption('string:Inhalation'); + await expect(this.page.locator('#quantity')).toHaveValue('560'); + await this.page.getByRole('button', { name: 'Add' }).click(); + await this.saveOrder(); + } + + async discontinueMedication() { + await this.page.getByRole('button', { name: 'Stop' }).first().click(); + await this.page.getByPlaceholder('Notes').fill('Patient allergic to medicine'); + await this.saveOrder(); + await this.page.locator('#dashboard-link span.patient-name').click(); + const medicationStatus = await this.page.locator('#dashboard-treatments span.discontinued-text').first(); + await expect(medicationStatus).toContainText('Stopped'); + } + async saveOrder() { await this.page.getByRole('button', { name: 'Save' }).click(); await expect(this.page.getByText('Saved', {exact: true})).toBeVisible(); diff --git a/e2e/utils/functions/odoo.ts b/e2e/utils/functions/odoo.ts index dceb326..93485e0 100644 --- a/e2e/utils/functions/odoo.ts +++ b/e2e/utils/functions/odoo.ts @@ -8,7 +8,6 @@ export class Odoo { async open() { await this.page.goto(`${ODOO_URL}`); await this.page.getByPlaceholder('Email').fill(`${process.env.ODOO_USERNAME}`); - await this.page.getByPlaceholder('Password').click(); await this.page.getByPlaceholder('Password').fill(`${process.env.ODOO_PASSWORD}`); await this.page.locator('button[type="submit"]').click(); } diff --git a/playwright.config.ts b/playwright.config.ts index e85b4da..23720b1 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -27,7 +27,6 @@ const config: PlaywrightTestConfig = { slowMo: 500 } }, - }, ], };