Skip to content

Commit dd038d1

Browse files
committed
link together customize query
1 parent eccdaed commit dd038d1

File tree

19 files changed

+669
-775
lines changed

19 files changed

+669
-775
lines changed

containers/tefca-viewer/e2e/query_workflow.spec.ts

Lines changed: 62 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@
22

33
import { test, expect } from "@playwright/test";
44
import { TEST_URL } from "../playwright-setup";
5-
6-
test.describe("querying with the TryTEFCA viewer", () => {
5+
import { STEP_ONE_PAGE_TITLE } from "@/app/query/components/searchForm/SearchForm";
6+
import { hyperUnluckyPatient } from "@/app/constants";
7+
import {
8+
CONTACT_US_DISCLAIMER_EMAIL,
9+
CONTACT_US_DISCLAIMER_TEXT,
10+
} from "@/app/query/designSystem/SiteAlert";
11+
import { STEP_TWO_PAGE_TITLE } from "@/app/query/components/patientSearchResults/PatientSearchResultsTable";
12+
import { STEP_THREE_PAGE_TITLE } from "@/app/query/components/selectQuery/SelectSavedQuery";
13+
14+
const TEST_PATIENT = hyperUnluckyPatient;
15+
const TEST_PATIENT_NAME =
16+
hyperUnluckyPatient.FirstName + " A. " + hyperUnluckyPatient.LastName;
17+
18+
test.describe("querying with the Query Connector", () => {
719
test.beforeEach(async ({ page }) => {
820
// Start every test on our main landing page
921
await page.goto(TEST_URL);
@@ -32,18 +44,9 @@ test.describe("querying with the TryTEFCA viewer", () => {
3244

3345
test("unsuccessful user query: no patients", async ({ page }) => {
3446
await page.getByRole("button", { name: "Go to the demo" }).click();
35-
await page
36-
.getByLabel("Query", { exact: true })
37-
.selectOption("social-determinants");
38-
await page.getByRole("button", { name: "Advanced" }).click();
39-
await page
40-
.getByLabel("FHIR Server (QHIN)", { exact: true })
41-
.selectOption("HELIOS Meld: Direct");
42-
43-
await page.getByLabel("First Name").fill("Ellie");
44-
await page.getByLabel("Last Name").fill("Williams");
45-
await page.getByLabel("Phone Number").fill("5555555555");
46-
await page.getByLabel("Medical Record Number").fill("TLOU1TLOU2");
47+
await page.getByRole("button", { name: "Fill fields" }).click();
48+
await page.getByLabel("First Name").fill("Shouldnt");
49+
await page.getByLabel("Last Name").fill("Findanyone");
4750
await page.getByRole("button", { name: "Search for patient" }).click();
4851

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

61-
test("successful demo user query: the quest for watermelon mcgee", async ({
62-
page,
63-
}) => {
64+
test("successful demo user query", async ({ page }) => {
6465
await page.getByRole("button", { name: "Go to the demo" }).click();
6566

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

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

86+
await page.getByRole("link", { name: "Select patient" }).click();
87+
await expect(
88+
page.getByRole("heading", { name: "Select a query" }),
89+
).toBeVisible();
90+
await page.getByRole("button", { name: "Submit" }).click();
91+
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
92+
9293
// Make sure we have a results page with a single patient
9394
// Non-interactive 'div' elements in the table should be located by text
9495
await expect(
9596
page.getByRole("heading", { name: "Patient Record" }),
9697
).toBeVisible();
9798
await expect(page.getByText("Patient Name")).toBeVisible();
98-
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
99+
await expect(page.getByText(TEST_PATIENT_NAME)).toBeVisible();
99100
await expect(page.getByText("Patient Identifiers")).toBeVisible();
100-
await expect(page.getByText("MRN: 18091")).toBeVisible();
101+
await expect(
102+
page.getByText(`Medical Record Number: ${TEST_PATIENT.MRN}`),
103+
).toBeVisible();
101104

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

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

124127
test("query using form-fillable demo patient by phone number", async ({
125128
page,
126129
}) => {
127130
await page.getByRole("button", { name: "Go to the demo" }).click();
128-
129-
await page.getByLabel("Query", { exact: true }).selectOption("syphilis");
130-
await page
131-
.getByLabel("Patient", { exact: true })
132-
.selectOption("sti-syphilis-positive");
133131
await page.getByRole("button", { name: "Fill fields" }).click();
134132

135133
// Delete last name and MRN to force phone number as one of the 3 fields
@@ -140,25 +138,39 @@ test.describe("querying with the TryTEFCA viewer", () => {
140138
await page.getByRole("button", { name: "Search for patient" }).click();
141139
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
142140
await expect(
143-
page.getByRole("heading", { name: "Patient Record" }),
141+
page.getByRole("heading", { name: STEP_TWO_PAGE_TITLE }),
144142
).toBeVisible();
143+
await page.getByRole("link", { name: "Select patient" }).click();
144+
await expect(
145+
page.getByRole("heading", { name: STEP_THREE_PAGE_TITLE }),
146+
).toBeVisible();
147+
await page.getByRole("button", { name: "Submit" }).click();
148+
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
149+
145150
await expect(page.getByText("Patient Name")).toBeVisible();
146-
await expect(page.getByText("Hyper A. Unlucky")).toBeVisible();
151+
await expect(page.getByText(TEST_PATIENT_NAME)).toBeVisible();
147152
await expect(page.getByText("Contact")).toBeVisible();
148-
await expect(page.getByText("517-425-1398")).toBeVisible();
153+
await expect(page.getByText(TEST_PATIENT.Phone)).toBeVisible();
149154
await expect(page.getByText("Patient Identifiers")).toBeVisible();
150-
await expect(page.getByText("8692756")).toBeVisible();
155+
await expect(page.getByText(TEST_PATIENT.MRN)).toBeVisible();
151156
});
152157

153158
test("social determinants query with generalized function", async ({
154159
page,
155160
}) => {
156161
await page.getByRole("button", { name: "Go to the demo" }).click();
157-
await page
158-
.getByLabel("Query", { exact: true })
159-
.selectOption("social-determinants");
160162
await page.getByRole("button", { name: "Fill fields" }).click();
161163
await page.getByRole("button", { name: "Search for patient" }).click();
164+
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
165+
166+
await page.getByRole("link", { name: "Select patient" }).click();
167+
await expect(
168+
page.getByRole("heading", { name: "Select a query" }),
169+
).toBeVisible();
170+
await page.getByTestId("Select").selectOption("social-determinants");
171+
await page.getByRole("button", { name: "Submit" }).click();
172+
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
173+
162174
await expect(
163175
page.getByRole("heading", { name: "Patient Record" }),
164176
).toBeVisible();
@@ -168,127 +180,16 @@ test.describe("querying with the TryTEFCA viewer", () => {
168180
page,
169181
}) => {
170182
await page.getByRole("button", { name: "Go to the demo" }).click();
171-
await page.getByLabel("Query", { exact: true }).selectOption("chlamydia");
172183
await page.getByRole("button", { name: "Fill fields" }).click();
173184
await page.getByRole("button", { name: "Search for patient" }).click();
174185
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
186+
await page.getByRole("link", { name: "Select patient" }).click();
187+
await page.getByTestId("Select").selectOption("chlamydia");
188+
await page.getByRole("button", { name: "Submit" }).click();
189+
await expect(page.getByText("Loading")).toHaveCount(0, { timeout: 10000 });
175190

176191
await expect(
177192
page.getByRole("heading", { name: "Patient Record" }),
178193
).toBeVisible();
179194
});
180195
});
181-
182-
test.describe("Test the user journey of a 'tester'", () => {
183-
test.beforeEach(async ({ page }) => {
184-
// Start every test on direct tester page
185-
await page.goto("http://localhost:3000/tefca-viewer/query/test", {
186-
waitUntil: "load",
187-
});
188-
});
189-
190-
test("query/test page loads", async ({ page }) => {
191-
// Check that interactable elements are present
192-
await expect(
193-
page.getByRole("button", { name: "Data Usage Policy" }),
194-
).toBeVisible();
195-
await expect(
196-
page.getByRole("link", { name: "TEFCA Viewer" }),
197-
).toBeVisible();
198-
199-
// Check that each expected text section is present
200-
await expect(
201-
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
202-
).toBeVisible();
203-
await expect(page.getByLabel("Query", { exact: true })).toBeVisible();
204-
await expect(page.getByLabel("Patient", { exact: true })).toBeVisible();
205-
await expect(page.getByRole("button", { name: "Advanced" })).toBeVisible();
206-
});
207-
208-
test("Query for patient using auto-filled data", async ({ page }) => {
209-
await page
210-
.getByLabel("Query", { exact: true })
211-
.selectOption({ value: "newborn-screening" });
212-
await page
213-
.getByLabel("Patient", { exact: true })
214-
.selectOption({ value: "newborn-screening-referral" });
215-
await page.getByRole("button", { name: "Fill fields" }).click();
216-
await page.getByRole("button", { name: "Search for patient" }).click();
217-
218-
// Make sure we have a results page with a single patient
219-
await expect(
220-
page.getByRole("heading", { name: "Patient Record" }),
221-
).toBeVisible();
222-
await expect(page.getByText("Patient Name")).toBeVisible();
223-
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
224-
await expect(page.getByText("Patient Identifiers")).toBeVisible();
225-
await expect(page.getByText("MRN: 18091")).toBeVisible();
226-
});
227-
228-
test("Query for patient by filling in data", async ({ page }) => {
229-
await page
230-
.getByLabel("Query", { exact: true })
231-
.selectOption("Newborn screening follow-up");
232-
await page.getByRole("button", { name: "Advanced" }).click();
233-
await page
234-
.getByLabel("FHIR Server (QHIN)", { exact: true })
235-
.selectOption("HELIOS Meld: Direct");
236-
await page.getByLabel("First Name").fill("Watermelon");
237-
await page.getByLabel("Last Name").fill("McGee");
238-
await page.getByLabel("Phone Number").fill("5555555555");
239-
await page.getByLabel("Date of Birth").fill("2024-07-12");
240-
await page.getByLabel("Medical Record Number").fill("18091");
241-
242-
await page.getByRole("button", { name: "Search for patient" }).click();
243-
244-
// Make sure we have a results page with a single patient
245-
await expect(
246-
page.getByRole("heading", { name: "Patient Record" }),
247-
).toBeVisible();
248-
await expect(page.getByText("Patient Name")).toBeVisible();
249-
await expect(page.getByText("WATERMELON SPROUT MCGEE")).toBeVisible();
250-
await expect(page.getByText("Patient Identifiers")).toBeVisible();
251-
await expect(page.getByText("MRN: 18091")).toBeVisible();
252-
});
253-
254-
test("Query with multiple patients returned", async ({ page }) => {
255-
// Query for a patient with multiple results
256-
await page
257-
.getByLabel("Query", { exact: true })
258-
.selectOption("Chlamydia case investigation");
259-
await page.getByRole("button", { name: "Advanced" }).click();
260-
await page
261-
.getByLabel("FHIR Server (QHIN)", { exact: true })
262-
.selectOption("JMC Meld: Direct");
263-
await page.getByLabel("Last Name").fill("JMC");
264-
265-
await page.getByRole("button", { name: "Search for patient" }).click();
266-
// Make sure all the elements for the multiple patients view appear
267-
await expect(
268-
page.getByRole("heading", { name: "Select a patient" }),
269-
).toBeVisible();
270-
// Check that there is a Table element with the correct headers
271-
await expect(page.locator("thead").locator("tr")).toHaveText(
272-
"NameDOBContactAddressMRNActions",
273-
);
274-
275-
// Check that there are multiple rows in the table
276-
await expect(page.locator("tbody").locator("tr")).toHaveCount(10);
277-
278-
// Click on the first patient's "Select patient" button
279-
await page.locator(':nth-match(:text("Select patient"), 1)').click();
280-
281-
// Make sure we have a results page with a single patient & appropriate back buttons
282-
await expect(
283-
page.getByRole("heading", { name: "Patient Record" }),
284-
).toBeVisible();
285-
await expect(
286-
page.getByRole("button", { name: "New patient search" }),
287-
).toBeVisible();
288-
289-
await page.getByRole("button", { name: "New patient search" }).click();
290-
await expect(
291-
page.getByRole("heading", { name: "Search for a Patient", exact: true }),
292-
).toBeVisible();
293-
});
294-
});

containers/tefca-viewer/src/app/CustomQuery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export class CustomQuery {
7575
: "";
7676
this.medicationRequestQuery =
7777
rxnormFilter !== ""
78-
? `/MedicationRequest?subject=${patientId}&code=${rxnormFilter}&_include=MedicationRequest:medication&_include=MedicationRequest:medication.administration`
78+
? `/MedicationRequest?subject=${patientId}&code=${rxnormFilter}&_include=MedicationRequest:medication&_include=MedicationRequest:intended-performer`
7979
: "";
8080
this.socialHistoryQuery = `/Observation?subject=${patientId}&category=social-history`;
8181
this.encounterQuery =

containers/tefca-viewer/src/app/constants.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ export const demoQueryOptions = [
3737
{ value: "syphilis", label: "Syphilis case investigation" },
3838
];
3939

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

101+
export const DEFAULT_DEMO_FHIR_SERVER = "Public HAPI: Direct";
93102
/*
94103
* Common "Hyper Unlucky" patient data used for all non-newborn screening use cases
95104
*/
96-
const hyperUnluckyPatient: DemoDataFields = {
105+
export const hyperUnluckyPatient: DemoDataFields = {
97106
FirstName: "Hyper",
98107
LastName: "Unlucky",
99108
DOB: "1975-12-06",
100109
MRN: "8692756",
101110
Phone: "517-425-1398",
102-
FhirServer: "Public HAPI: Direct",
111+
FhirServer: DEFAULT_DEMO_FHIR_SERVER,
103112
UseCase: "cancer", // UseCase will be updated per case
104113
};
105114

@@ -276,12 +285,7 @@ export const stateOptions = [
276285
];
277286

278287
/* Mode that pages can be in; determines what is displayed to the user */
279-
export type Mode =
280-
| "search"
281-
| "results"
282-
| "customize-queries"
283-
| "select-query"
284-
| "patient-results";
288+
export type Mode = "search" | "results" | "select-query" | "patient-results";
285289

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

0 commit comments

Comments
 (0)