Skip to content
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

e2e tests #94

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions e2e/commands/cohort-operations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { APIRequestContext, expect } from "@playwright/test";
import { Patient } from "./patient-operations";

export interface CohortType {
uuid: string;
name: string;
description: string;
display: string;
links: { rel: string; uri: string; resourceAlias: string }[];
resourceVersion: string;
}

export interface Cohort {
uuid: string;
name: string;
description: string;
attributes: any[];
links: any[];
location: any;
groupCohort: boolean | null;
startDate: Date;
endDate: Date;
voidReason: string | null;
voided: boolean;
isStarred?: boolean;
type?: string;
size: number;
cohortType?: CohortType;
resourceVersion: string;
}

export interface CohortMember {
attributes: Array<any>;
description: string;
endDate: string;
startDate: string;
name: string;
uuid: string;
patient: Patient;
}

export const generateRandomCohort = async (
api: APIRequestContext
): Promise<Cohort> => {
const cohortRes = await api.post("cohortm/cohort", {
data: {
name: `Cohort ${Math.floor(Math.random() * 10000)}`,
description: `Cohort description ${Math.floor(Math.random() * 10000)}`,
cohortType: "e71857cb-33af-4f2c-86ab-7223bcfa37ad",
groupCohort: false,
startDate: new Date().toISOString(),
},
});
await expect(cohortRes.ok()).toBeTruthy();
return await cohortRes.json();
};

export const deleteCohort = async (api: APIRequestContext, uuid: string) => {
await api.delete(`cohortm/cohort/${uuid}`, {
data: {
voidReason: "Test void reason",
},
});
};

export const addPatientToCohort = async (
api: APIRequestContext,
cohortUuid: string,
patientUuid: string
): Promise<CohortMember> => {
const cohortMemberRes = await api.post(`cohortm/cohortmember`, {
data: {
patient: patientUuid,
cohort: cohortUuid,
startDate: new Date().toISOString(),
},
});
await expect(cohortMemberRes.ok()).toBeTruthy();
return await cohortMemberRes.json();
};

export const removePatientFromCohort = async (
api: APIRequestContext,
cohortMemberUuid: string
) => {
await api.delete(`cohortm/cohortmember/${cohortMemberUuid}`, {
data: {},
});
};
44 changes: 44 additions & 0 deletions e2e/commands/encounter-operations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Encounter } from "./../../packages/esm-active-visits-app/src/visits-summary/visit.resource";
import { APIRequestContext, expect } from "@playwright/test";
import dayjs from "dayjs";

export const createEncounter = async (
api: APIRequestContext,
patientId: string,
providerId: string,
note?: string
): Promise<Encounter> => {
const observations = [];

if (note) {
observations.push({
concept: {
uuid: "162169AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
display: "",
},
value: note,
});
}
const encounterRes = await api.post("encounter", {
data: {
encounterDatetime: dayjs().format(),
form: "c75f120a-04ec-11e3-8780-2b40bef9a44b",
patient: patientId,
encounterProviders: [
{
encounterRole: "240b26f9-dd88-4172-823d-4a8bfeb7841f",
provider: providerId,
},
],
location: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID,
encounterType: "d7151f82-c1f3-4152-a605-2f9ea7414a79",
obs: observations,
},
});
await expect(encounterRes.ok()).toBeTruthy();
return await encounterRes.json();
};

export const deleteEncounter = async (api: APIRequestContext, uuid: string) => {
await api.delete(`encounter/${uuid}`, { data: {} });
};
5 changes: 5 additions & 0 deletions e2e/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./patient-operations";
export * from "./encounter-operations";
export * from "./visit-operations";
export * from "./provider-operations";
export * from "./cohort-operations";
116 changes: 116 additions & 0 deletions e2e/commands/patient-operations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { APIRequestContext, expect } from "@playwright/test";

export interface Patient {
uuid: string;
identifiers: Identifier[];
display: string;
person: {
uuid: string;
display: string;
gender: string;
age: number;
birthdate: string;
birthdateEstimated: boolean;
dead: boolean;
deathDate?: any;
causeOfDeath?: any;
preferredAddress: {
address1: string;
cityVillage: string;
country: string;
postalCode: string;
stateProvince: string;
countyDistrict: string;
};
attributes: any[];
voided: boolean;
birthtime?: any;
deathdateEstimated: boolean;
resourceVersion: string;
};
attributes: {
value: string;
attributeType: { uuid: string; display: string };
}[];
voided: boolean;
}

export interface Address {
preferred: boolean;
address1: string;
cityVillage: string;
country: string;
postalCode: string;
stateProvince: string;
}

export interface Identifier {
uuid: string;
display: string;
}

export const generateRandomPatient = async (
api: APIRequestContext
): Promise<Patient> => {
const identifierRes = await api.post(
"idgen/identifiersource/8549f706-7e85-4c1d-9424-217d50a2988b/identifier",
{
data: {},
}
);
await expect(identifierRes.ok()).toBeTruthy();
const { identifier } = await identifierRes.json();

const patientRes = await api.post("patient", {
// TODO: This is not configurable right now. It probably should be.
data: {
identifiers: [
{
identifier,
identifierType: "05a29f94-c0ed-11e2-94be-8c13b969e334",
location: "44c3efb0-2583-4c80-a79e-1f756a03c0a1",
preferred: true,
},
],
person: {
addresses: [
{
address1: "Bom Jesus Street",
address2: "",
cityVillage: "Recife",
country: "Brazil",
postalCode: "50030-310",
stateProvince: "Pernambuco",
},
],
attributes: [],
birthdate: "2020-02-01",
birthdateEstimated: false,
dead: false,
gender: "M",
names: [
{
familyName: `Smith${Math.floor(Math.random() * 10000)}`,
givenName: `John${Math.floor(Math.random() * 10000)}`,
middleName: "",
preferred: true,
},
],
},
},
});
await expect(patientRes.ok()).toBeTruthy();
return await patientRes.json();
};

export const getPatient = async (
api: APIRequestContext,
uuid: string
): Promise<Patient> => {
const patientRes = await api.get(`patient/${uuid}?v=full`);
return await patientRes.json();
};

export const deletePatient = async (api: APIRequestContext, uuid: string) => {
await api.delete(`patient/${uuid}`, { data: {} });
};
13 changes: 13 additions & 0 deletions e2e/commands/provider-operations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Provider } from "../../packages/esm-appointments-app/src/types/index";
import { APIRequestContext, expect } from "@playwright/test";

export const getProvider = async (
api: APIRequestContext
): Promise<Provider> => {
const providerRes = await api.get("provider?q=admin", {
data: {},
});
await expect(providerRes.ok()).toBeTruthy();
const { results } = await providerRes.json();
return await results[0];
};
34 changes: 34 additions & 0 deletions e2e/commands/visit-operations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { APIRequestContext, expect } from "@playwright/test";
import { Visit } from "@openmrs/esm-framework";
import dayjs from "dayjs";

export const startVisit = async (
api: APIRequestContext,
patientId: string
): Promise<Visit> => {
const visitRes = await api.post("visit", {
data: {
startDatetime: dayjs().format("YYYY-MM-DDTHH:mm:ss.SSSZZ"),
patient: patientId,
location: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID,
visitType: "7b0f5697-27e3-40c4-8bae-f4049abfb4ed",
attributes: [],
},
});

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

export const endVisit = async (api: APIRequestContext, uuid: string) => {
await api.post(`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",
stopDatetime: dayjs().format("YYYY-MM-DDTHH:mm:ss.SSSZZ"),
},
});
};
32 changes: 32 additions & 0 deletions e2e/core/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { request } from "@playwright/test";
import * as dotenv from "dotenv";

dotenv.config();

/**
* This configuration is to reuse the signed-in state in the tests
* by log in only once using the API and then skip the log in step for all the tests.
*
* https://playwright.dev/docs/auth#reuse-signed-in-state
*/

async function globalSetup() {
const requestContext = await request.newContext();
const token = Buffer.from(
`${process.env.E2E_USER_ADMIN_USERNAME}:${process.env.E2E_USER_ADMIN_PASSWORD}`
).toString("base64");
await requestContext.post(`${process.env.E2E_BASE_URL}/ws/rest/v1/session`, {
data: {
sessionLocation: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID,
locale: "en",
},
headers: {
"Content-Type": "application/json",
Authorization: `Basic ${token}`,
},
});
await requestContext.storageState({ path: "e2e/storageState.json" });
await requestContext.dispose();
}

export default globalSetup;
1 change: 1 addition & 0 deletions e2e/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./test";
20 changes: 20 additions & 0 deletions e2e/core/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { APIRequestContext, Page, test as base } from "@playwright/test";
import { api } from "../fixtures";

// This file sets up our custom test harness using the custom fixtures.
// See https://playwright.dev/docs/test-fixtures#creating-a-fixture for details.
// If a spec intends to use one of the custom fixtures, the special `test` function
// exported from this file must be used instead of the default `test` function
// provided by playwright.

export interface CustomTestFixtures {
loginAsAdmin: Page;
}

export interface CustomWorkerFixtures {
api: APIRequestContext;
}

export const test = base.extend<CustomTestFixtures, CustomWorkerFixtures>({
api: [api, { scope: "worker" }],
});
33 changes: 33 additions & 0 deletions e2e/fixtures/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
type APIRequestContext,
type PlaywrightWorkerArgs,
type WorkerFixture,
} from "@playwright/test";

/**
* A fixture which initializes an [`APIRequestContext`](https://playwright.dev/docs/api/class-apirequestcontext)
* that is bound to the configured OpenMRS API server. The context is automatically authenticated
* using the configured admin account.
*
* Use the request context like this:
* ```ts
* test('your test', async ({ api }) => {
* const res = await api.get('patient/1234');
* await expect(res.ok()).toBeTruthy();
* });
* ```
*/
export const api: WorkerFixture<
APIRequestContext,
PlaywrightWorkerArgs
> = async ({ playwright }, use) => {
const ctx = await playwright.request.newContext({
baseURL: `${process.env.E2E_BASE_URL}/ws/rest/v1/`,
httpCredentials: {
username: process.env.E2E_USER_ADMIN_USERNAME,
password: process.env.E2E_USER_ADMIN_PASSWORD,
},
});

await use(ctx);
};
1 change: 1 addition & 0 deletions e2e/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./api";
Loading
Loading