Skip to content

Commit

Permalink
link together customize query
Browse files Browse the repository at this point in the history
  • Loading branch information
fzhao99 committed Oct 16, 2024
1 parent eccdaed commit dd038d1
Show file tree
Hide file tree
Showing 19 changed files with 669 additions and 775 deletions.
223 changes: 62 additions & 161 deletions containers/tefca-viewer/e2e/query_workflow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

import { test, expect } from "@playwright/test";
import { TEST_URL } from "../playwright-setup";

test.describe("querying with the TryTEFCA viewer", () => {
import { STEP_ONE_PAGE_TITLE } from "@/app/query/components/searchForm/SearchForm";
import { hyperUnluckyPatient } from "@/app/constants";
import {
CONTACT_US_DISCLAIMER_EMAIL,
CONTACT_US_DISCLAIMER_TEXT,
} from "@/app/query/designSystem/SiteAlert";
import { STEP_TWO_PAGE_TITLE } from "@/app/query/components/patientSearchResults/PatientSearchResultsTable";
import { STEP_THREE_PAGE_TITLE } from "@/app/query/components/selectQuery/SelectSavedQuery";

const TEST_PATIENT = hyperUnluckyPatient;
const TEST_PATIENT_NAME =
hyperUnluckyPatient.FirstName + " A. " + hyperUnluckyPatient.LastName;

test.describe("querying with the Query Connector", () => {
test.beforeEach(async ({ page }) => {
// Start every test on our main landing page
await page.goto(TEST_URL);
Expand Down Expand Up @@ -32,18 +44,9 @@ test.describe("querying with the TryTEFCA viewer", () => {

test("unsuccessful user query: no patients", async ({ page }) => {
await page.getByRole("button", { name: "Go to the demo" }).click();
await page
.getByLabel("Query", { exact: true })
.selectOption("social-determinants");
await page.getByRole("button", { name: "Advanced" }).click();
await page
.getByLabel("FHIR Server (QHIN)", { exact: true })
.selectOption("HELIOS Meld: Direct");

await page.getByLabel("First Name").fill("Ellie");
await page.getByLabel("Last Name").fill("Williams");
await page.getByLabel("Phone Number").fill("5555555555");
await page.getByLabel("Medical Record Number").fill("TLOU1TLOU2");
await page.getByRole("button", { name: "Fill fields" }).click();
await page.getByLabel("First Name").fill("Shouldnt");
await page.getByLabel("Last Name").fill("Findanyone");
await page.getByRole("button", { name: "Search for patient" }).click();

// Better luck next time, user!
Expand All @@ -58,9 +61,7 @@ test.describe("querying with the TryTEFCA viewer", () => {
.click();
});

test("successful demo user query: the quest for watermelon mcgee", async ({
page,
}) => {
test("successful demo user query", async ({ page }) => {
await page.getByRole("button", { name: "Go to the demo" }).click();

// Check that the info alert is visible and contains the correct text
Expand All @@ -70,40 +71,42 @@ test.describe("querying with the TryTEFCA viewer", () => {
"This site is for demo purposes only. Please do not enter PII on this website.",
);
await expect(
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
page.getByRole("heading", { name: STEP_ONE_PAGE_TITLE, exact: true }),
).toBeVisible();

// Put in the search parameters for the elusive fruit person
await page
.getByLabel("Query", { exact: true })
.selectOption("newborn-screening");
await page
.getByLabel("Patient", { exact: true })
.selectOption("newborn-screening-referral");
await page.getByRole("button", { name: "Fill fields" }).click();
await page.getByLabel("First Name").fill("Watermelon");
await page.getByLabel("Last Name").fill("McGee");
await page.getByLabel("Date of Birth").fill("2024-07-12");
await page.getByLabel("Medical Record Number").fill("18091");
await page.getByLabel("Phone Number").fill("5555555555");
await page.getByLabel("First Name").fill(TEST_PATIENT.FirstName);
await page.getByLabel("Last Name").fill(TEST_PATIENT.LastName);
await page.getByLabel("Date of Birth").fill(TEST_PATIENT.DOB);
await page.getByLabel("Medical Record Number").fill(TEST_PATIENT.MRN);
await page.getByLabel("Phone Number").fill(TEST_PATIENT.Phone);
await page.getByRole("button", { name: "Search for patient" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

await page.getByRole("link", { name: "Select patient" }).click();
await expect(
page.getByRole("heading", { name: "Select a query" }),
).toBeVisible();
await page.getByRole("button", { name: "Submit" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

// Make sure we have a results page with a single patient
// Non-interactive 'div' elements in the table should be located by text
await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
await expect(page.getByText("Patient Name")).toBeVisible();
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
await expect(page.getByText(TEST_PATIENT_NAME)).toBeVisible();
await expect(page.getByText("Patient Identifiers")).toBeVisible();
await expect(page.getByText("MRN: 18091")).toBeVisible();
await expect(
page.getByText(`Medical Record Number: ${TEST_PATIENT.MRN}`),
).toBeVisible();

// Check that the info alert is visible and has updated to the correct text
const alert2 = page.locator(".custom-alert");
await expect(alert2).toBeVisible();
await expect(alert2).toHaveText(
"Interested in learning more about using the TEFCA Query Connector for your jurisdiction? Send us an email at [email protected]",
`${CONTACT_US_DISCLAIMER_TEXT} ${CONTACT_US_DISCLAIMER_EMAIL}`,
);

// Check to see if the accordion button is open
Expand All @@ -117,19 +120,14 @@ test.describe("querying with the TryTEFCA viewer", () => {
// Now let's use the return to search to go back to a blank form
await page.getByRole("button", { name: "New patient search" }).click();
await expect(
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
page.getByRole("heading", { name: STEP_ONE_PAGE_TITLE, exact: true }),
).toBeVisible();
});

test("query using form-fillable demo patient by phone number", async ({
page,
}) => {
await page.getByRole("button", { name: "Go to the demo" }).click();

await page.getByLabel("Query", { exact: true }).selectOption("syphilis");
await page
.getByLabel("Patient", { exact: true })
.selectOption("sti-syphilis-positive");
await page.getByRole("button", { name: "Fill fields" }).click();

// Delete last name and MRN to force phone number as one of the 3 fields
Expand All @@ -140,25 +138,39 @@ test.describe("querying with the TryTEFCA viewer", () => {
await page.getByRole("button", { name: "Search for patient" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
await expect(
page.getByRole("heading", { name: "Patient Record" }),
page.getByRole("heading", { name: STEP_TWO_PAGE_TITLE }),
).toBeVisible();
await page.getByRole("link", { name: "Select patient" }).click();
await expect(
page.getByRole("heading", { name: STEP_THREE_PAGE_TITLE }),
).toBeVisible();
await page.getByRole("button", { name: "Submit" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

await expect(page.getByText("Patient Name")).toBeVisible();
await expect(page.getByText("Hyper A. Unlucky")).toBeVisible();
await expect(page.getByText(TEST_PATIENT_NAME)).toBeVisible();
await expect(page.getByText("Contact")).toBeVisible();
await expect(page.getByText("517-425-1398")).toBeVisible();
await expect(page.getByText(TEST_PATIENT.Phone)).toBeVisible();
await expect(page.getByText("Patient Identifiers")).toBeVisible();
await expect(page.getByText("8692756")).toBeVisible();
await expect(page.getByText(TEST_PATIENT.MRN)).toBeVisible();
});

test("social determinants query with generalized function", async ({
page,
}) => {
await page.getByRole("button", { name: "Go to the demo" }).click();
await page
.getByLabel("Query", { exact: true })
.selectOption("social-determinants");
await page.getByRole("button", { name: "Fill fields" }).click();
await page.getByRole("button", { name: "Search for patient" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

await page.getByRole("link", { name: "Select patient" }).click();
await expect(
page.getByRole("heading", { name: "Select a query" }),
).toBeVisible();
await page.getByTestId("Select").selectOption("social-determinants");
await page.getByRole("button", { name: "Submit" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
Expand All @@ -168,127 +180,16 @@ test.describe("querying with the TryTEFCA viewer", () => {
page,
}) => {
await page.getByRole("button", { name: "Go to the demo" }).click();
await page.getByLabel("Query", { exact: true }).selectOption("chlamydia");
await page.getByRole("button", { name: "Fill fields" }).click();
await page.getByRole("button", { name: "Search for patient" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
await page.getByRole("link", { name: "Select patient" }).click();
await page.getByTestId("Select").selectOption("chlamydia");
await page.getByRole("button", { name: "Submit" }).click();
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });

await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
});
});

test.describe("Test the user journey of a 'tester'", () => {
test.beforeEach(async ({ page }) => {
// Start every test on direct tester page
await page.goto("http://localhost:3000/tefca-viewer/query/test", {
waitUntil: "load",
});
});

test("query/test page loads", async ({ page }) => {
// Check that interactable elements are present
await expect(
page.getByRole("button", { name: "Data Usage Policy" }),
).toBeVisible();
await expect(
page.getByRole("link", { name: "TEFCA Viewer" }),
).toBeVisible();

// Check that each expected text section is present
await expect(
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
).toBeVisible();
await expect(page.getByLabel("Query", { exact: true })).toBeVisible();
await expect(page.getByLabel("Patient", { exact: true })).toBeVisible();
await expect(page.getByRole("button", { name: "Advanced" })).toBeVisible();
});

test("Query for patient using auto-filled data", async ({ page }) => {
await page
.getByLabel("Query", { exact: true })
.selectOption({ value: "newborn-screening" });
await page
.getByLabel("Patient", { exact: true })
.selectOption({ value: "newborn-screening-referral" });
await page.getByRole("button", { name: "Fill fields" }).click();
await page.getByRole("button", { name: "Search for patient" }).click();

// Make sure we have a results page with a single patient
await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
await expect(page.getByText("Patient Name")).toBeVisible();
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
await expect(page.getByText("Patient Identifiers")).toBeVisible();
await expect(page.getByText("MRN: 18091")).toBeVisible();
});

test("Query for patient by filling in data", async ({ page }) => {
await page
.getByLabel("Query", { exact: true })
.selectOption("Newborn screening follow-up");
await page.getByRole("button", { name: "Advanced" }).click();
await page
.getByLabel("FHIR Server (QHIN)", { exact: true })
.selectOption("HELIOS Meld: Direct");
await page.getByLabel("First Name").fill("Watermelon");
await page.getByLabel("Last Name").fill("McGee");
await page.getByLabel("Phone Number").fill("5555555555");
await page.getByLabel("Date of Birth").fill("2024-07-12");
await page.getByLabel("Medical Record Number").fill("18091");

await page.getByRole("button", { name: "Search for patient" }).click();

// Make sure we have a results page with a single patient
await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
await expect(page.getByText("Patient Name")).toBeVisible();
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
await expect(page.getByText("Patient Identifiers")).toBeVisible();
await expect(page.getByText("MRN: 18091")).toBeVisible();
});

test("Query with multiple patients returned", async ({ page }) => {
// Query for a patient with multiple results
await page
.getByLabel("Query", { exact: true })
.selectOption("Chlamydia case investigation");
await page.getByRole("button", { name: "Advanced" }).click();
await page
.getByLabel("FHIR Server (QHIN)", { exact: true })
.selectOption("JMC Meld: Direct");
await page.getByLabel("Last Name").fill("JMC");

await page.getByRole("button", { name: "Search for patient" }).click();
// Make sure all the elements for the multiple patients view appear
await expect(
page.getByRole("heading", { name: "Select a patient" }),
).toBeVisible();
// Check that there is a Table element with the correct headers
await expect(page.locator("thead").locator("tr")).toHaveText(
"NameDOBContactAddressMRNActions",
);

// Check that there are multiple rows in the table
await expect(page.locator("tbody").locator("tr")).toHaveCount(10);

// Click on the first patient's "Select patient" button
await page.locator(':nth-match(:text("Select patient"), 1)').click();

// Make sure we have a results page with a single patient & appropriate back buttons
await expect(
page.getByRole("heading", { name: "Patient Record" }),
).toBeVisible();
await expect(
page.getByRole("button", { name: "New patient search" }),
).toBeVisible();

await page.getByRole("button", { name: "New patient search" }).click();
await expect(
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
).toBeVisible();
});
});
2 changes: 1 addition & 1 deletion containers/tefca-viewer/src/app/CustomQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class CustomQuery {
: "";
this.medicationRequestQuery =
rxnormFilter !== ""
? `/MedicationRequest?subject=${patientId}&code=${rxnormFilter}&_include=MedicationRequest:medication&_include=MedicationRequest:medication.administration`
? `/MedicationRequest?subject=${patientId}&code=${rxnormFilter}&_include=MedicationRequest:medication&_include=MedicationRequest:intended-performer`
: "";
this.socialHistoryQuery = `/Observation?subject=${patientId}&category=social-history`;
this.encounterQuery =
Expand Down
20 changes: 12 additions & 8 deletions containers/tefca-viewer/src/app/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ export const demoQueryOptions = [
{ value: "syphilis", label: "Syphilis case investigation" },
];

type DemoQueryOptionValue = (typeof demoQueryLabels)[number];
export const demoQueryValToLabelMap = demoQueryOptions.reduce(
(acc, curVal) => {
acc[curVal.value as DemoQueryOptionValue] = curVal.label;
return acc;
},
{} as Record<DemoQueryOptionValue, string>,
);
/*
* Map between the queryType property used to define a demo use case's options,
* and the name of that query for purposes of searching the DB.
Expand Down Expand Up @@ -90,16 +98,17 @@ export type PatientType =
| "social-determinants"
| "sti-syphilis-positive";

export const DEFAULT_DEMO_FHIR_SERVER = "Public HAPI: Direct";
/*
* Common "Hyper Unlucky" patient data used for all non-newborn screening use cases
*/
const hyperUnluckyPatient: DemoDataFields = {
export const hyperUnluckyPatient: DemoDataFields = {
FirstName: "Hyper",
LastName: "Unlucky",
DOB: "1975-12-06",
MRN: "8692756",
Phone: "517-425-1398",
FhirServer: "Public HAPI: Direct",
FhirServer: DEFAULT_DEMO_FHIR_SERVER,
UseCase: "cancer", // UseCase will be updated per case
};

Expand Down Expand Up @@ -276,12 +285,7 @@ export const stateOptions = [
];

/* Mode that pages can be in; determines what is displayed to the user */
export type Mode =
| "search"
| "results"
| "customize-queries"
| "select-query"
| "patient-results";
export type Mode = "search" | "results" | "select-query" | "patient-results";

/*Type to specify the expected components for each item in a value set that will be
displayed in the CustomizeQuery component*/
Expand Down
Loading

0 comments on commit dd038d1

Please sign in to comment.