Skip to content

Commit

Permalink
Merge branch 'main' into fix-O3-4312
Browse files Browse the repository at this point in the history
  • Loading branch information
usamaidrsk authored Jan 8, 2025
2 parents d9890c8 + 0aff26e commit 4d4e1b3
Show file tree
Hide file tree
Showing 308 changed files with 8,349 additions and 1,077 deletions.
20 changes: 14 additions & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest-dom/recommended",
"plugin:testing-library/react"
],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:jest-dom/recommended"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "import", "jest-dom", "react-hooks", "testing-library"],
"overrides": [
{
"files": ["**/*.test.tsx"],
"extends": ["plugin:testing-library/react"]
},
{
"files": ["e2e/**/*.spec.ts"],
"extends": ["plugin:playwright/recommended"],
"rules": {
"testing-library/prefer-screen-queries": "off"
}
}
],
"rules": {
"react-hooks/exhaustive-deps": "warn",
"react-hooks/rules-of-hooks": "error",
Expand Down
12 changes: 6 additions & 6 deletions e2e/commands/visit-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ export const startVisit = async (api: APIRequestContext, patientId: string): Pro
},
});

await expect(visitRes.ok()).toBeTruthy();
expect(visitRes.ok()).toBeTruthy();
return await visitRes.json();
};

export const endVisit = async (api: APIRequestContext, uuid: string) => {
const visitRes = await api.post(`visit/${uuid}`, {
export const endVisit = async (api: APIRequestContext, visit: Visit) => {
const visitRes = await api.post(`visit/${visit.uuid}`, {
data: {
location: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID,
startDatetime: dayjs().subtract(1, 'D').format('YYYY-MM-DDTHH:mm:ss.SSSZZ'),
visitType: '7b0f5697-27e3-40c4-8bae-f4049abfb4ed',
location: visit.location.uuid,
startDatetime: visit.startDatetime,
visitType: visit.visitType.uuid,
stopDatetime: dayjs().format('YYYY-MM-DDTHH:mm:ss.SSSZZ'),
},
});
Expand Down
1 change: 1 addition & 0 deletions e2e/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './immunizations-page';
export * from './medications-page';
export * from './orders-page';
export * from './program-page';
export * from './mark-patient-deceased-page';
export * from './results-viewer-page';
export * from './visits-page';
export * from './vitals-and-biometrics-page';
10 changes: 10 additions & 0 deletions e2e/pages/mark-patient-deceased-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type Page } from '@playwright/test';

export class MarkPatientDeceasedPage {
constructor(readonly page: Page) {}

async goTo(patientUuid: string) {
await this.page.goto('/openmrs/spa/patient/' + patientUuid + '/chart/Patient%20Summary');
}

}
2 changes: 1 addition & 1 deletion e2e/specs/biometrics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ test('Record biometrics', async ({ page }) => {
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
2 changes: 1 addition & 1 deletion e2e/specs/clinical-forms.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,6 @@ test('Form state is retained when minimizing a form in the workspace', async ({
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
2 changes: 1 addition & 1 deletion e2e/specs/drug-orders.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,6 @@ test('Record, edit and discontinue a drug order', async ({ page }) => {
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
16 changes: 9 additions & 7 deletions e2e/specs/lab-orders.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,12 @@ test.describe.serial('Running laboratory order tests sequentially', () => {
await page.getByLabel(/additional instructions/i).fill(' N/A');
});

await test.step('Add I save the lab order form', async () => {
await test.step('And I save the lab order form', async () => {
await page.getByRole('button', { name: /save order/i }).click();
});

await test.step('And I click the `Sign and close` button', async () => {
await expect(page.getByRole('status', { name: /new/i })).toBeVisible();
await page.getByRole('button', { name: /sign and close/i }).click();
});

Expand All @@ -70,7 +74,6 @@ test.describe.serial('Running laboratory order tests sequentially', () => {

test('Modify a lab order', async ({ page }) => {
const ordersPage = new OrdersPage(page);
const orderBasket = page.locator('[data-extension-slot-name="order-basket-slot"]');

await test.step('When I visit the orders page', async () => {
await ordersPage.goTo(patient.uuid);
Expand Down Expand Up @@ -101,8 +104,8 @@ test.describe.serial('Running laboratory order tests sequentially', () => {
});

await test.step('Then the order status should be changed to `Modify`', async () => {
await expect(orderBasket.getByText(/new/i)).not.toBeVisible();
await expect(orderBasket.getByText(/modify/i)).toBeVisible();
await expect(page.getByRole('status', { name: /new/i })).not.toBeVisible();
await expect(page.getByRole('status', { name: /modify/i })).toBeVisible();
});

await test.step('When I click on the `Sign and close` button', async () => {
Expand All @@ -116,7 +119,6 @@ test.describe.serial('Running laboratory order tests sequentially', () => {

test('Discontinue a lab order', async ({ page }) => {
const ordersPage = new OrdersPage(page);
const orderBasket = page.locator('[data-extension-slot-name="order-basket-slot"]');

await test.step('When I visit the orders page', async () => {
await ordersPage.goTo(patient.uuid);
Expand All @@ -138,7 +140,7 @@ test.describe.serial('Running laboratory order tests sequentially', () => {
});

await test.step('Then the order status should be changed to `Discontinue`', async () => {
await expect(orderBasket.getByText(/discontinue/i)).toBeVisible();
await expect(page.getByRole('status', { name: /discontinue/i })).toBeVisible();
});

await test.step('And I click on the `Sign and close` button', async () => {
Expand All @@ -156,6 +158,6 @@ test.describe.serial('Running laboratory order tests sequentially', () => {
});

test.afterAll(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
60 changes: 60 additions & 0 deletions e2e/specs/mark-patient-deceased.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { expect } from '@playwright/test';
import { generateRandomPatient, deletePatient, type Patient } from '../commands';
import { test } from '../core';
import { MarkPatientDeceasedPage } from '../pages/mark-patient-deceased-page';

let patient: Patient;

test.beforeEach(async ({ api }) => {
patient = await generateRandomPatient(api);
});

test('Mark a patient as deceased', async ({ page }) => {
const markPatientDeceasedPage = new MarkPatientDeceasedPage(page);
const todayDate = new Date().toLocaleDateString('en-GB').replace(/\//g, '-');
const causeOfDeath = 'Neoplasm';
const actionsButton = () => page.getByRole('button', { name: /actions/i });
const markDeceasedMenuItem = () => page.getByRole('menuitem', { name: /mark patient deceased/i });
const deathDetailsForm = () => page.locator('form');
const dateOfDeathInput = () => page.getByPlaceholder(/dd\/mm\/yyyy/i);
const saveAndCloseButton = () => page.getByRole('button', { name: /save and close/i });

await test.step('Given that I have a patient and I am on the Patient’s chart page', async () => {
await markPatientDeceasedPage.goTo(patient.uuid);
});

await test.step('When I click on the "Actions" button and select "Mark patient deceased"', async () => {
await actionsButton().click();
await markDeceasedMenuItem().click();
});

await test.step('Then I should see a form to enter the patient\'s death details', async () => {
await expect(deathDetailsForm()).toBeVisible();
await expect(dateOfDeathInput()).toBeVisible();
await expect(page.getByRole('radio', { name: causeOfDeath })).toBeVisible();
});

await test.step('When I enter the "Date of death" to today’s date', async () => {
await dateOfDeathInput().fill(todayDate);
await page.keyboard.press('Enter');
});

await test.step('And the "Cause of death" to Neoplasm', async () => {
await page.locator('text=Neoplasm').click();
});

await test.step('And I click "Save and close"', async () => {
await page.getByRole('button', { name: /save and close/i }).click();
});

await test.step('Then I should see a “deceased” patient tag in the patient banner', async () => {
const deceasedTagLocator = page.locator(
'[data-extension-id="deceased-patient-tag"] span[title="Deceased"]'
);
await expect(deceasedTagLocator).toBeVisible();
});
});

test.afterEach(async ({ api }) => {
await deletePatient(api, patient.uuid);
});
23 changes: 15 additions & 8 deletions e2e/specs/results-viewer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable playwright/no-nested-step */
import { expect } from '@playwright/test';
import { type Visit } from '@openmrs/esm-framework';
import { generateRandomPatient, type Patient, startVisit, endVisit, deletePatient } from '../commands';
import { test } from '../core';
import { ResultsViewerPage, VisitsPage } from '../pages';
import { ChartPage, ResultsViewerPage, VisitsPage } from '../pages';

let patient: Patient;
let visit: Visit;
Expand All @@ -13,6 +14,7 @@ test.beforeEach(async ({ api }) => {
});

test('Record and edit test results', async ({ page }) => {
const chartPage = new ChartPage(page);
const resultsViewerPage = new ResultsViewerPage(page);
const visitsPage = new VisitsPage(page);
const form = page.locator('[data-extension-slot-name="form-widget-slot"]');
Expand Down Expand Up @@ -209,12 +211,12 @@ test('Record and edit test results', async ({ page }) => {
},
];

await test.step('When I visit the results viewer page', async () => {
await resultsViewerPage.goTo(patient.uuid);
await test.step('When I visit the chart summary page', async () => {
await chartPage.goTo(patient.uuid);
});

await test.step('And I click on the `Clinical forms` button on the siderail', async () => {
await page.getByLabel(/clinical forms/i).click();
await test.step('And I click the `Clinical forms` button on the siderail', async () => {
await page.getByLabel(/clinical forms/i, { exact: true }).click();
});

await test.step('Then I should see the clinical forms workspace', async () => {
Expand All @@ -226,11 +228,15 @@ test('Record and edit test results', async ({ page }) => {
await expect(page.getByRole('cell', { name: /laboratory test results/i })).toBeVisible();
});

await test.step('When I launch the `Laboratory Test Results` form', async () => {
await test.step('When I click the `Laboratory Test Results` link to launch the form', async () => {
await page.getByText(/laboratory test results/i).click();
});

await test.step('And I fill the "Complete Blood Count" section', async () => {
await test.step('Then I should see the `Laboratory Test Results` form launch in the workspace', async () => {
await expect(page.getByText(/laboratory test results/i)).toBeVisible();
});

await test.step('When I fill the "Complete Blood Count" section', async () => {
for (const { label, value } of completeBloodCountData) {
await test.step(label, async () => {
await form.getByLabel(label, { exact: true }).fill(value);
Expand Down Expand Up @@ -276,6 +282,7 @@ test('Record and edit test results', async ({ page }) => {
});
}
});

for (const { resultsPageReference, value } of chemistryResultsData) {
await test.step(resultsPageReference, async () => {
const row = page.locator(`tr:has-text("${resultsPageReference}"):has(td:has-text("${value}"))`).first();
Expand Down Expand Up @@ -364,6 +371,6 @@ test('Record and edit test results', async ({ page }) => {
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
2 changes: 1 addition & 1 deletion e2e/specs/visit-note.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,6 @@ test('Add and delete a visit note', async ({ page }) => {
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
2 changes: 1 addition & 1 deletion e2e/specs/vitals.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,6 @@ test('Record vital signs', async ({ page }) => {
});

test.afterEach(async ({ api }) => {
await endVisit(api, visit.uuid);
await endVisit(api, visit);
await deletePatient(api, patient.uuid);
});
2 changes: 1 addition & 1 deletion e2e/support/bamboo/playwright.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# The image version should match the Playwright version specified in the package.json file
FROM mcr.microsoft.com/playwright:v1.48.2-jammy
FROM mcr.microsoft.com/playwright:v1.49.0-jammy

ARG USER_ID
ARG GROUP_ID
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@openmrs/esm-patient-chart",
"private": true,
"version": "8.2.0",
"version": "9.0.0",
"workspaces": [
"packages/*"
],
Expand All @@ -25,7 +25,7 @@
},
"devDependencies": {
"@openmrs/esm-framework": "next",
"@playwright/test": "1.48.2",
"@playwright/test": "1.49.0",
"@swc/cli": "^0.1.62",
"@swc/core": "^1.3.89",
"@swc/jest": "^0.2.29",
Expand Down
8 changes: 4 additions & 4 deletions packages/esm-form-engine-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openmrs/esm-form-engine-app",
"version": "8.2.0",
"version": "9.0.0",
"license": "MPL-2.0",
"description": "Wrapper ESM for the O3 React Form Engine",
"browser": "dist/openmrs-esm-form-engine-app.js",
Expand All @@ -17,7 +17,7 @@
"test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color",
"coverage": "yarn test --coverage",
"typescript": "tsc",
"extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js"
"extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.modal.tsx' 'src/**/*.extension.tsx' 'src/**/*.workspace.tsx' 'src/**/*.hook.tsx' 'src/index.ts' --config ../../tools/i18next-parser.config.js"
},
"browserslist": [
"extends browserslist-config-openmrs"
Expand All @@ -43,8 +43,8 @@
"react-error-boundary": "^4.0.13"
},
"peerDependencies": {
"@openmrs/esm-framework": "5.x",
"@openmrs/esm-patient-common-lib": "8.x",
"@openmrs/esm-framework": "6.x",
"@openmrs/esm-patient-common-lib": "9.x",
"dayjs": "1.x",
"react": "18.x",
"react-i18next": "11.x",
Expand Down
15 changes: 15 additions & 0 deletions packages/esm-form-engine-app/translations/bn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"cancel": "Cancel",
"closeThisPanel": "Close this panel",
"collapseAll": "Collapse all",
"deleteQuestion": "Delete question",
"deleteQuestionConfirmation": "Are you sure you want to delete this question?",
"deleteQuestionExplainerText": "This action cannot be undone.",
"errorTitle": "There was an error with this form",
"expandAll": "Expand all",
"loading": "Loading",
"or": "or",
"thisList": "this list",
"toggleCollapseOrExpand": "Toggle collapse or expand",
"tryAgainMessage": "Try opening another form from"
}
15 changes: 15 additions & 0 deletions packages/esm-form-engine-app/translations/lg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"cancel": "Cancel",
"closeThisPanel": "Close this panel",
"collapseAll": "Collapse all",
"deleteQuestion": "Delete question",
"deleteQuestionConfirmation": "Are you sure you want to delete this question?",
"deleteQuestionExplainerText": "This action cannot be undone.",
"errorTitle": "There was an error with this form",
"expandAll": "Expand all",
"loading": "Loading",
"or": "or",
"thisList": "this list",
"toggleCollapseOrExpand": "Toggle collapse or expand",
"tryAgainMessage": "Try opening another form from"
}
Loading

0 comments on commit 4d4e1b3

Please sign in to comment.