From 293dafc1dde069a4bd8750b169b67d9065ede156 Mon Sep 17 00:00:00 2001 From: kdaud Date: Thu, 26 Sep 2024 20:50:19 +0300 Subject: [PATCH 1/3] =?UTF-8?q?OZ-715:=20Adapted=20E2E=20test=20suite=20to?= =?UTF-8?q?=20run=20test=20profiles=20+=20renamed=20goToDrugOrderForm()=20?= =?UTF-8?q?=E2=86=92=20navigateToDrugOrderForm()=20and=20goToLabOrderForm(?= =?UTF-8?q?)=20=E2=86=92=20navigateToLabOrderForm().?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/e2e.yml | 84 ++++++++++++++++++++++++ .github/workflows/foss.yml | 57 ---------------- e2e/tests/erpnext-openmrs-flows.spec.ts | 40 +++++------ e2e/tests/odoo-openmrs-flows.spec.ts | 44 +++++++------ e2e/tests/odoo-superset-flows.spec.ts | 8 +-- e2e/tests/openmrs-senaite-flows.spec.ts | 24 +++---- e2e/tests/openmrs-superset-flows.spec.ts | 12 ++-- e2e/utils/functions/erpnext.ts | 4 +- e2e/utils/functions/odoo.ts | 23 +++---- e2e/utils/functions/openmrs.ts | 37 ++++++----- package.json | 3 +- 11 files changed, 183 insertions(+), 153 deletions(-) create mode 100644 .github/workflows/e2e.yml delete mode 100644 .github/workflows/foss.yml diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 00000000..bb701a81 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,84 @@ +name: E2E Test Profile + +on: + workflow_dispatch: + + inputs: + o3_url: + description: 'O3 URL' + required: true + odoo_url: + description: 'Odoo URL' + required: false + senaite_url: + description: 'SENAITE URL' + required: false + superset_url: + description: 'Superset URL' + required: false + test_pro: + description: 'Running Ozone on Pro?' + required: true + default: 'true' + type: choice + options: + - true + - false + test_profile: + description: 'Choose test profile' + required: true + default: 'e2e-tests-pro' + type: choice + options: + - e2e-tests-pro + - e2e-tests-foss + - e2e-tests-openmrs-his +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + repository: ${{ github.repository }} + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Cache dependencies + id: cache + uses: actions/cache@v4 + with: + path: '**/node_modules' + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: Install dependencies + run: yarn install + + - name: Install Playwright browsers + run: npx playwright install chromium + + - name: Run E2E tests + id: jobStatusPretty + env: + O3_URL_DEV: '${{ github.event.inputs.o3_url }}' + ODOO_URL_DEV: '${{ github.event.inputs.odoo_url }}' + SENAITE_URL_DEV: '${{ github.event.inputs.senaite_url }}' + SUPERSET_URL_DEV: '${{ github.event.inputs.superset_url }}' + TEST_PRO: '${{ github.event.inputs.test_pro }}' + TEST_ENVIRONMENT: '${{ github.event.inputs.environment }}' + TEST_PROFILE: '${{ github.event.inputs.test_profile }}' + + run: | + npm run $TEST_PROFILE + + - name: Upload report + uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.github/workflows/foss.yml b/.github/workflows/foss.yml deleted file mode 100644 index 4e6bb2e2..00000000 --- a/.github/workflows/foss.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Ozone FOSS E2E Tests - -on: - - workflow_dispatch: - inputs: - e2e_base_url_input: - description: 'O3 URL' - required: true - e2e_odoo_url_input: - description: 'Odoo URL' - required: true - e2e_senaite_url_input: - description: 'SENAITE URL' - required: true -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - repository: ${{ github.repository }} - - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Cache dependencies - id: cache - uses: actions/cache@v4 - with: - path: '**/node_modules' - key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - - name: Install dependencies - run: yarn install - - - name: Install Playwright browsers - run: npx playwright install chromium --with-deps - - - name: Run E2E tests - env: - O3_DEV: '${{ github.event.inputs.e2e_base_url_input }}' - ODOO_URL_DEV: '${{ github.event.inputs.e2e_odoo_url_input }}' - SENAITE_URL_DEV: '${{ github.event.inputs.e2e_senaite_url_input }}' - RUNNING_OZONE_ON_PRO: 'false' - run: npm run e2e-tests-foss - - - name: Upload report - uses: actions/upload-artifact@v4 - if: always() - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 diff --git a/e2e/tests/erpnext-openmrs-flows.spec.ts b/e2e/tests/erpnext-openmrs-flows.spec.ts index 696c77ca..39f0a8dd 100644 --- a/e2e/tests/erpnext-openmrs-flows.spec.ts +++ b/e2e/tests/erpnext-openmrs-flows.spec.ts @@ -17,8 +17,8 @@ test.beforeEach(async ({ page }) => { test('Ordering a lab test for an OpenMRS patient creates the corresponding ERPNext customer.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); // verify @@ -31,8 +31,8 @@ test('Ordering a lab test for an OpenMRS patient creates the corresponding ERPNe test('Ordering a drug for an OpenMRS patient creates the corresponding ERPNext customer with a filled quotation.', async ({ page }) => { // replay - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); @@ -50,8 +50,8 @@ test('Ordering a drug for an OpenMRS patient creates the corresponding ERPNext c test('Editing the details of an OpenMRS patient with a synced lab order edits the corresponding ERPNext customer details.', async ({ page }) => { // setup - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await erpnext.open(); await erpnext.searchCustomer(); @@ -72,8 +72,8 @@ test('Editing the details of an OpenMRS patient with a synced lab order edits th test('Editing the details of an OpenMRS patient with a synced drug order edits the corresponding ERPNext customer details.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await erpnext.open(); @@ -95,8 +95,8 @@ test('Editing the details of an OpenMRS patient with a synced drug order edits t test('Ending an OpenMRS patient visit with a synced drug order updates the corresponding ERPNext draft quotation to an open state.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await erpnext.open(); @@ -117,10 +117,10 @@ test('Ending an OpenMRS patient visit with a synced drug order updates the corre await erpnext.deleteQuotation(); }); -test('Revising a synced OpenMRS drug order edits the corresponding ERPNext quotation item.', async ({ page }) => { +test('Revising details of a synced OpenMRS drug order modifies the corresponding ERPNext quotation item.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await erpnext.open(); @@ -131,7 +131,7 @@ test('Revising a synced OpenMRS drug order edits the corresponding ERPNext quota // replay await page.goto(`${O3_URL}`); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.editDrugOrder(); + await openmrs.modifyDrugOrderDescription(); // verify await page.goto(`${ERPNEXT_URL}/app/home`); @@ -162,8 +162,8 @@ test('Ordering a drug with a free text medication dosage for an OpenMRS patient test('Discontinuing a synced OpenMRS drug order for an ERPNext customer with a single quotation line removes the corresponding quotation.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await erpnext.open(); @@ -185,8 +185,8 @@ test('Discontinuing a synced OpenMRS drug order for an ERPNext customer with a s test('Ordering a drug for an OpenMRS patient within a visit creates the corresponding ERPNext customer with a filled quotation linked to the visit.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await erpnext.open(); @@ -198,8 +198,8 @@ test('Ordering a drug for an OpenMRS patient within a visit creates the correspo await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); await openmrs.endPatientVisit(); await openmrs.startPatientVisit(); - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 81mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 81mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); diff --git a/e2e/tests/odoo-openmrs-flows.spec.ts b/e2e/tests/odoo-openmrs-flows.spec.ts index f46b7aa6..826f343c 100644 --- a/e2e/tests/odoo-openmrs-flows.spec.ts +++ b/e2e/tests/odoo-openmrs-flows.spec.ts @@ -17,8 +17,8 @@ test.beforeEach(async ({ page }) => { test('Ordering a lab test for an OpenMRS patient creates the corresponding Odoo customer with a filled quotation.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); // verify @@ -27,12 +27,13 @@ test('Ordering a lab test for an OpenMRS patient creates the corresponding Odoo await odoo.searchCustomer(); await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(4)')).toContainText(`${patientName.firstName + ' ' + patientName.givenName}`); await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(8) span')).toHaveText('Quotation'); + await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(7) span')).toHaveText('$ 27.50'); }); test('Editing the details of an OpenMRS patient with a synced lab order edits the corresponding Odoo customer details.', async ({ page }) => { // setup - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await odoo.open(); await odoo.navigateToSales(); @@ -55,8 +56,8 @@ test('Editing the details of an OpenMRS patient with a synced lab order edits th test('Ordering a drug for an OpenMRS patient creates the corresponding Odoo customer with a filled quotation.', async ({ page }) => { // replay - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); @@ -66,12 +67,13 @@ test('Ordering a drug for an OpenMRS patient creates the corresponding Odoo cust await odoo.searchCustomer(); await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(4)')).toContainText(`${patientName.firstName + ' ' + patientName.givenName}`); await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(8) span')).toHaveText('Quotation'); + await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(7) span')).toHaveText('$ 14.88'); }); test('Editing the details of an OpenMRS patient with a synced drug order edits the corresponding Odoo customer details.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await odoo.open(); @@ -93,10 +95,10 @@ test('Editing the details of an OpenMRS patient with a synced drug order edits t await expect(page.locator('tr.o_data_row:nth-child(1) td:nth-child(8) span')).toHaveText('Quotation'); }); -test('Revising a synced OpenMRS drug order edits the corresponding Odoo quotation line.', async ({ page }) => { +test('Revising details of a synced OpenMRS drug order modifies the corresponding Odoo quotation line.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await odoo.open(); @@ -107,11 +109,12 @@ test('Revising a synced OpenMRS drug order edits the corresponding Odoo quotatio const drugOrderItem = await page.locator('table tbody td.o_data_cell:nth-child(3) span'); await expect(drugOrderItem).toContainText('4.0 Tablet'); await expect(drugOrderItem).toContainText('Twice daily - 5 day'); + await expect(page.locator('td.o_data_cell:nth-child(9) span')).toHaveText('$ 14.88'); // replay await page.goto(`${O3_URL}`); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.editDrugOrder(); + await openmrs.modifyDrugOrderDescription(); // verify await page.goto(`${ODOO_URL}`); @@ -120,12 +123,13 @@ test('Revising a synced OpenMRS drug order edits the corresponding Odoo quotatio await page.getByRole('cell', { name: `${patientName.firstName + ' ' + patientName.givenName}` }).click(); await expect(drugOrderItem).toContainText('8.0 Tablet'); await expect(drugOrderItem).toContainText('Thrice daily - 6 day'); + await expect(page.locator('td.o_data_cell:nth-child(9) span')).toHaveText('$ 9.92'); }); test('Discontinuing a synced OpenMRS drug order for an Odoo customer with a single quotation line removes the corresponding quotation.', async ({ page }) => { // setup - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await odoo.open(); @@ -153,12 +157,12 @@ test('Discontinuing a synced OpenMRS drug order for an Odoo customer with a sing test('Discontinuing a synced OpenMRS drug order for an Odoo customer with multiple quotation lines removes the corresponding quoatation.', async ({ page }) => { // setup - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.goToDrugOrderForm(); - await page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await openmrs.navigateToDrugOrderForm(); + await page.getByRole('searchbox').fill('Aspirin 325mg'); await openmrs.fillDrugOrderForm(); await openmrs.saveDrugOrder(); await odoo.open(); @@ -198,8 +202,8 @@ test('Ordering a drug with a free text medication dosage for an OpenMRS patient test('Discontinuing a synced OpenMRS lab order for an Odoo customer with a single quotation line cancels the corresponding quotation.', async ({ page }) => { // setup - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await odoo.open(); await odoo.navigateToSales(); diff --git a/e2e/tests/odoo-superset-flows.spec.ts b/e2e/tests/odoo-superset-flows.spec.ts index a0c8e428..3622e582 100644 --- a/e2e/tests/odoo-superset-flows.spec.ts +++ b/e2e/tests/odoo-superset-flows.spec.ts @@ -21,8 +21,8 @@ test.beforeEach(async ({ page }) => { test(`Creating an Odoo sale order line generates an entry in Superset's sale_order_lines table.`, async ({ page }) => { // setup await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Complete blood count'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Complete blood count'); await openmrs.saveLabOrder(); await superset.open(); await superset.selectDBSchema(); @@ -75,8 +75,8 @@ test(`A (synced) sale order line in Odoo generates an entry in Superset's sale_o await superset.clearSQLEditor(); await page.goto(`${O3_URL}`); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Haemoglobin'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Haemoglobin'); await openmrs.saveLabOrder(); // replay diff --git a/e2e/tests/openmrs-senaite-flows.spec.ts b/e2e/tests/openmrs-senaite-flows.spec.ts index c18e3833..91cda879 100644 --- a/e2e/tests/openmrs-senaite-flows.spec.ts +++ b/e2e/tests/openmrs-senaite-flows.spec.ts @@ -17,8 +17,8 @@ test.beforeEach(async ({ page }) => { test('Ordering a lab test for an OpenMRS patient creates the corresponding SENAITE client with an analysis request.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); // verify @@ -29,8 +29,8 @@ test('Ordering a lab test for an OpenMRS patient creates the corresponding SENAI test('Editing the details of an OpenMRS patient with a synced lab order edits the corresponding SENAITE client details.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await senaite.open(); await senaite.searchClient(); @@ -47,8 +47,8 @@ test('Editing the details of an OpenMRS patient with a synced lab order edits th test('Voiding a synced OpenMRS lab order cancels the corresponding SENAITE analysis request.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await senaite.open(); await senaite.searchClient(); @@ -71,8 +71,8 @@ test('Voiding a synced OpenMRS lab order cancels the corresponding SENAITE analy test('Published coded lab results from SENAITE are viewable in the OpenMRS lab results viewer.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Hepatitis C test - qualitative'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Hepatitis C test - qualitative'); await openmrs.saveLabOrder(); await senaite.open(); await senaite.searchClient(); @@ -89,8 +89,8 @@ test('Published coded lab results from SENAITE are viewable in the OpenMRS lab r test('Published numeric lab results from SENAITE are viewable in the OpenMRS lab results viewer.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Total bilirubin'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Total bilirubin'); await openmrs.saveLabOrder(); await senaite.open(); await senaite.searchClient(); @@ -107,8 +107,8 @@ test('Published numeric lab results from SENAITE are viewable in the OpenMRS lab test('Published free text lab results from SENAITE are viewable in the OpenMRS lab results viewer.', async ({ page }) => { // replay - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Stool microscopy with concentration'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Stool microscopy with concentration'); await openmrs.saveLabOrder(); await senaite.open(); await senaite.searchClient(); diff --git a/e2e/tests/openmrs-superset-flows.spec.ts b/e2e/tests/openmrs-superset-flows.spec.ts index 0d36b487..bf008238 100644 --- a/e2e/tests/openmrs-superset-flows.spec.ts +++ b/e2e/tests/openmrs-superset-flows.spec.ts @@ -109,8 +109,8 @@ test(`Creating an OpenMRS order creates the order in Superset's orders table.`, // replay await page.goto(`${O3_URL}`); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); // verify @@ -157,8 +157,8 @@ test(`Creating an OpenMRS encounter creates the encounter in Superset's encounte // replay await page.goto(`${O3_URL}`); await openmrs.searchPatient(`${patientName.firstName + ' ' + patientName.givenName}`); - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); // verify @@ -424,8 +424,8 @@ test(`Voiding an OpenMRS encounter updates the encounter in Superset's encounter await openmrs.searchPatientId(); const patientIdentifier = await page.locator('#demographics section p:nth-child(2)').textContent(); await openmrs.startPatientVisit(); - await openmrs.goToLabOrderForm(); - await page.getByPlaceholder('Search for a test type').fill('Blood urea nitrogen'); + await openmrs.navigateToLabOrderForm(); + await page.getByRole('searchbox').fill('Blood urea nitrogen'); await openmrs.saveLabOrder(); await superset.open(); await superset.selectDBSchema(); diff --git a/e2e/utils/functions/erpnext.ts b/e2e/utils/functions/erpnext.ts index a41e0520..53952e36 100644 --- a/e2e/utils/functions/erpnext.ts +++ b/e2e/utils/functions/erpnext.ts @@ -18,7 +18,7 @@ export class ERPNext { await this.page.getByRole('link', { name: 'Customer', exact: true }).click(); await this.page.getByPlaceholder('Customer Name').clear(); await this.page.getByPlaceholder('Customer Name').fill(`${patientName.givenName}`); - await delay(3000); + await delay(5000); } async searchQuotation() { @@ -27,7 +27,7 @@ export class ERPNext { await this.page.getByPlaceholder(/title/i).clear(); await this.page.getByPlaceholder(/party/i).clear(); await this.page.getByPlaceholder(/title/i).fill(`${patientName.givenName}`); - await delay(3000); + await delay(5000); } async deleteQuotation() { diff --git a/e2e/utils/functions/odoo.ts b/e2e/utils/functions/odoo.ts index 557fcb97..4c11ef29 100644 --- a/e2e/utils/functions/odoo.ts +++ b/e2e/utils/functions/odoo.ts @@ -1,7 +1,6 @@ import { expect, Page } from '@playwright/test'; -import { patientName } from '../functions/openmrs'; import { ODOO_URL } from '../configs/globalSetup'; -import { delay } from './openmrs'; +import { delay, patientName } from './openmrs'; export class Odoo { constructor(readonly page: Page) {} @@ -9,33 +8,27 @@ export class Odoo { async open() { await this.page.goto(`${ODOO_URL}`); if (`${process.env.TEST_PRO}` == 'true') { - await this.page.getByRole('link', { name: 'Login with Single Sign-On' }).click(); + await this.page.locator('div.o_login_auth div a').click(); } else { await this.page.locator('#login').fill(`${process.env.ODOO_USERNAME_ON_FOSS}`); - await delay(1000); await this.page.locator('#password').fill(`${process.env.ODOO_PASSWORD_ON_FOSS}`); - await delay(1000); await this.page.locator('button[type="submit"]').click(); } await expect(this.page).toHaveURL(/.*web/); } - async createCustomer() { - await this.page.getByPlaceholder('Search...').type(`${patientName.firstName + ' ' + patientName.givenName}`); - await this.page.getByPlaceholder('Search...').press('Enter'); - await delay(2000); - } - async searchCustomer() { - await this.page.getByPlaceholder('Search...').type(`${patientName.firstName + ' ' + patientName.givenName}`); - await this.page.getByPlaceholder('Search...').press('Enter'); + await expect(this.page.locator('.o_searchview_input')).toBeVisible(); + await this.page.locator('.o_searchview_input').fill(`${patientName.firstName + ' ' + patientName.givenName}`); + await this.page.locator('.o_searchview_input').press('Enter'); await delay(2000); } async navigateToSales() { await this.page.locator("//a[contains(@class, 'full')]").click(); - await this.page.getByRole('menuitem', { name: 'Sales' }).click(); - await expect(this.page.locator('.breadcrumb-item')).toHaveText('Quotations'); + await expect(this.page.getByRole('menuitem', { name: /sales/i })).toBeVisible(); + await this.page.getByRole('menuitem', { name: /sales/i }).click(); + await expect(this.page.locator('.breadcrumb-item')).toHaveText(/quotations/i); } async createSaleOrderLine() { diff --git a/e2e/utils/functions/openmrs.ts b/e2e/utils/functions/openmrs.ts index 5ea56cc6..abe68875 100644 --- a/e2e/utils/functions/openmrs.ts +++ b/e2e/utils/functions/openmrs.ts @@ -136,7 +136,7 @@ export class OpenMRS { await this.page.locator('label').filter({ hasText: 'Facility Visit' }).locator('span').first().click(); await this.page.locator('form').getByRole('button', { name: 'Start visit' }).click(); await expect(this.page.getByText('Facility Visit started successfully')).toBeVisible(); - await delay(4000); + await delay(5000); } async endPatientVisit() { @@ -150,13 +150,12 @@ export class OpenMRS { async voidPatient() { await this.page.goto(`${O3_URL}/openmrs/admin/patients/index.htm`); - await expect(await this.page.getByPlaceholder(' ')).toBeVisible(); + await expect(this.page.getByPlaceholder(' ')).toBeVisible(); await this.page.getByPlaceholder(' ').type(`${patientName.firstName + ' ' + patientName.givenName}`); await this.page.locator('#openmrsSearchTable tbody tr.odd td:nth-child(1)').click(); await this.page.locator('input[name="voidReason"]').fill('Void patient created by smoke test'); await this.page.getByRole('button', { name: 'Delete Patient', exact: true }).click(); - const message = await this.page.locator('//*[@id="patientFormVoided"]').textContent(); - await expect(message?.includes('This patient has been deleted')).toBeTruthy(); + await expect(this.page.locator('//*[@id="patientFormVoided"]')).toContainText('This patient has been deleted'); } async addPatientCondition() { @@ -219,8 +218,11 @@ export class OpenMRS { await expect(this.page.getByText('Appointment cancelled successfully')).toBeVisible(); } - async goToLabOrderForm() { - await this.page.getByLabel('Order basket', { exact: true }).click(); + async navigateToLabOrderForm() { + await expect(this.page.getByLabel('Order basket')).toBeVisible(); + await this.page.getByLabel('Order basket').click(); + await delay(2000); + await expect(this.page.getByRole('button', { name: 'Add', exact: true }).nth(1)).toBeVisible(); await this.page.getByRole('button', { name: 'Add', exact: true }).nth(1).click(); } @@ -256,14 +258,16 @@ export class OpenMRS { await this.page.getByRole('link', { name: 'Results Viewer' }).click(); } - async goToDrugOrderForm() { - await this.page.getByLabel('Order basket', { exact: true }).click(); + async navigateToDrugOrderForm() { + await expect(this.page.getByLabel('Order basket')).toBeVisible(); + await this.page.getByLabel('Order basket').click(); + await delay(2000); + await expect(this.page.getByRole('button', { name: 'Add', exact: true }).nth(0)).toBeVisible(); await this.page.getByRole('button', { name: 'Add', exact: true }).nth(0).click(); } async fillDrugOrderForm() { await this.page.getByRole('button', { name: 'Order form' }).click(); - await delay(2000); await this.page.getByPlaceholder('Dose').fill('4'); await this.page.getByRole('button', { name: 'Open', exact: true }).nth(1).click(); await this.page.getByText('Intravenous', {exact: true}).click(); @@ -273,7 +277,7 @@ export class OpenMRS { await this.page.getByLabel('Duration', { exact: true }).fill('5'); await this.page.getByLabel('Quantity to dispense').fill('12'); await this.page.getByLabel('Prescription refills').fill('3'); - await this.page.getByPlaceholder('e.g. "Hypertension"').type('Hypertension'); + await this.page.locator('#indication').fill('Hypertension'); } async saveDrugOrder() { @@ -287,17 +291,19 @@ export class OpenMRS { } async createDrugOrderWithFreeTextDosage() { - await this.page.getByLabel('Order basket', { exact: true }).click(); + await expect(this.page.getByLabel('Order basket')).toBeVisible(); + await this.page.getByLabel('Order basket').click(); + await delay(2000); + await expect(this.page.getByRole('button', { name: 'Add', exact: true }).nth(0)).toBeVisible(); await this.page.getByRole('button', { name: 'Add', exact: true }).nth(0).click(); - await this.page.getByPlaceholder('Search for a drug or orderset (e.g. "Aspirin")').fill('Aspirin 325mg'); + await this.page.getByRole('searchbox').fill('Aspirin 325mg'); await this.page.getByRole('button', { name: 'Order form' }).click(); - await delay(2000); await this.page.locator('div').filter({ hasText: /^Off$/ }).locator('div').click(); await this.page.getByPlaceholder('Free text dosage').fill('Take up to three tablets per day'); await this.page.getByLabel('Duration', { exact: true }).fill('3'); await this.page.getByLabel('Quantity to dispense').fill('9'); await this.page.getByLabel('Prescription refills').fill('2'); - await this.page.getByPlaceholder('e.g. "Hypertension"').type('Hypertension'); + await this.page.locator('#indication').fill('Hypertension'); await this.page.getByRole('button', { name: 'Save order' }).focus(); await expect(this.page.getByText('Save order')).toBeVisible(); await this.page.getByRole('button', { name: 'Save order' }).click(); @@ -307,7 +313,7 @@ export class OpenMRS { await delay(5000); } - async editDrugOrder() { + async modifyDrugOrderDescription() { await this.page.getByRole('button', { name: 'Options', exact: true }).click(); await this.page.getByRole('menuitem', { name: 'Modify', exact: true }).click(); await this.page.getByPlaceholder('Dose').clear(); @@ -340,7 +346,6 @@ export class OpenMRS { await this.page.getByRole('button', { name: 'Actions', exact: true }).click(); await this.page.getByRole('menuitem', { name: 'Edit patient details' }).click(); await delay(4000); - await this.page.getByLabel('First Name').click(); await this.page.getByLabel('First Name').clear(); await this.page.getByLabel('First Name').type(`${patientName.updatedFirstName}`); await delay(4000); diff --git a/package.json b/package.json index 28afc93a..319d803b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ ], "scripts": { "e2e-tests-pro": "npx playwright test", - "e2e-tests-foss": "npx playwright test odoo-openmrs erpnext-openmrs openmrs-senaite" + "e2e-tests-foss": "npx playwright test odoo-openmrs erpnext-openmrs openmrs-senaite", + "e2e-tests-openmrs-his": "npx playwright test odoo-openmrs openmrs-senaite" }, "publishConfig": { "registry": "https://nexus.mekomsolutions.net/repository/npm-public/" From 8bffc1031c54d29171301c14ff46d1aa25ef763f Mon Sep 17 00:00:00 2001 From: kdaud Date: Mon, 30 Sep 2024 12:09:10 +0300 Subject: [PATCH 2/3] Rename test profiles --- .github/workflows/e2e.yml | 8 ++++---- .github/workflows/pro.yml | 2 +- package.json | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index bb701a81..b94d2bc1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -27,12 +27,12 @@ on: test_profile: description: 'Choose test profile' required: true - default: 'e2e-tests-pro' + default: 'ozone-pro' type: choice options: - - e2e-tests-pro - - e2e-tests-foss - - e2e-tests-openmrs-his + - ozone-pro + - ozone-foss + - openmrs-distro-his jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/pro.yml b/.github/workflows/pro.yml index 1465efe1..ed5af27b 100644 --- a/.github/workflows/pro.yml +++ b/.github/workflows/pro.yml @@ -53,7 +53,7 @@ jobs: KEYCLOAK_USERNAME: '${{ secrets.KEYCLOAK_USERNAME }}' KEYCLOAK_PASSWORD: '${{ secrets.KEYCLOAK_PASSWORD }}' run: | - npm run e2e-tests-pro + npm run ozone-pro if: ${{ github.event_name != 'pull_request' }} if [[ ${{ job.status }} == "success" ]]; then diff --git a/package.json b/package.json index 319d803b..95484af5 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ "!playwright-report/" ], "scripts": { - "e2e-tests-pro": "npx playwright test", - "e2e-tests-foss": "npx playwright test odoo-openmrs erpnext-openmrs openmrs-senaite", - "e2e-tests-openmrs-his": "npx playwright test odoo-openmrs openmrs-senaite" + "ozone-pro": "npx playwright test", + "ozone-foss": "npx playwright test odoo-openmrs erpnext-openmrs openmrs-senaite", + "openmrs-distro-his": "npx playwright test odoo-openmrs openmrs-senaite" }, "publishConfig": { "registry": "https://nexus.mekomsolutions.net/repository/npm-public/" From e861f425c13b4ae7dfaa62a7b37c4d800887bf2a Mon Sep 17 00:00:00 2001 From: kdaud Date: Tue, 1 Oct 2024 12:53:45 +0300 Subject: [PATCH 3/3] Address reviews --- .github/workflows/e2e.yml | 4 ++-- .github/workflows/pro.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index b94d2bc1..3098c2b1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -17,7 +17,7 @@ on: description: 'Superset URL' required: false test_pro: - description: 'Running Ozone on Pro?' + description: 'Running Ozone Pro?' required: true default: 'true' type: choice @@ -81,4 +81,4 @@ jobs: with: name: playwright-report path: playwright-report/ - retention-days: 30 + retention-days: 7 diff --git a/.github/workflows/pro.yml b/.github/workflows/pro.yml index ed5af27b..d95fd0ef 100644 --- a/.github/workflows/pro.yml +++ b/.github/workflows/pro.yml @@ -123,4 +123,4 @@ jobs: with: name: playwright-report path: playwright-report/ - retention-days: 30 + retention-days: 7