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

happy path e2e #290

Merged
merged 5 commits into from
Jan 22, 2025
Merged
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
164 changes: 125 additions & 39 deletions query-connector/e2e/query_building.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,152 @@ import { test, expect } from "@playwright/test";
import { TEST_URL } from "../playwright-setup";
import { DEFAULT_QUERIES } from "@/app/queryBuilding/fixtures";

// consts
const QUERY_LIBRARY = "Query Library";
const CUSTOM_QUERY = "Custom Query";
const SELECT_TEMPLATES = "Select condition template(s)";
const BACKLINK_MY_QUERIES = "Back to My queries";
const BACKLINK_CONDITIONS = "Back to condition selection";

const CLICKED_CONDITION = {
name: "Cancer (Leukemia)",
labsCount: "3 / 3",
medsCount: "1 / 1",
conditionsCount: "6 / 6",
sampleLabValueSet: "Cancer (Leukemia) Lab Result",
sampleLabValueSetID: "14_20240923",
sampleMedValueSet: "Cancer (Leukemia) Medication",
sampleMedValueSetID: "3_20240909",
sampleCode: "1 ML alemtuzumab 30 MG/ML Injection",
sampleCodeID: "828265",
};
const SEARCHED_CONDITION = {
name: "Congenital syphilis",
labsCount: "97 / 97",
medsCount: "27 / 27",
conditionsCount: "79 / 79",
};

test.describe("building a new query", () => {
// Start every test by navigating to the customize query workflow
// Start every test by navigating to the query building workflow
test.beforeEach(async ({ page }) => {
await page.goto(`${TEST_URL}/queryBuilding`);
await expect(
page.getByRole("heading", {
name: "Query Library",
name: QUERY_LIBRARY,
exact: true,
}),
).toBeVisible();
});

test("happy path works works", async ({ page }) => {
test("happy path works", async ({ page }) => {
page.getByText("Create Query").click();

// expect the Condition Selection page:
await expect(
page.getByRole("heading", {
name: "Custom query",
name: CUSTOM_QUERY,
}),
).toBeVisible();
await expect(
page.getByRole("heading", {
name: "Select condition template(s)",
}),
).toBeVisible();

expect(page.getByText("Customize query")).toBeVisible();
expect(page.getByText("Customize query")).toBeDisabled();

await page.getByText("Cancer (Leukemia)", { exact: true }).click();
await page.getByText("Cleft lip", { exact: true }).click();

await page.getByPlaceholder("Search conditions").fill("syp");
await page.getByText("Congenital syphilis", { exact: true }).click();

await page.getByLabel("Query name").fill("Test Query");

expect(page.getByText("Customize query")).toBeEnabled();
await page.getByText("Customize query", { exact: true }).click();

await expect(
page.getByRole("button", {
name: "Save query",
name: SELECT_TEMPLATES,
}),
).toBeEnabled();

expect(
page.getByTestId("accordionItem_labs").getByText("3 / 3"),
).toBeVisible();
expect(
page.getByTestId("accordionItem_conditions").getByText("6 / 6"),
).toBeVisible();
expect(
page.getByTestId("accordionItem_medications").getByText("1 / 1"),
).toBeVisible();

await page.getByText("Conditions", { exact: true }).click();
expect(
page.getByTestId("accordionItem_conditions").getByText("5/5"),
).toBeVisible();
const backLink = await page.getByTestId("backArrowLink");
expect(backLink).toContainText(BACKLINK_MY_QUERIES);

const actionButton = await page.getByTestId("createSaveQueryBtn");
expect(actionButton).toBeVisible();
expect(actionButton).toHaveText("Customize query");
expect(actionButton).toBeDisabled();

const input = await page.getByTestId("queryNameInput");
const hasFocus = await input.evaluate(
(node) => document.activeElement === node,
);
expect(hasFocus).toBeTruthy();

// start adding conditions:
await page.getByText(CLICKED_CONDITION.name, { exact: true }).click();
expect(page.getByText(CLICKED_CONDITION.name, { exact: true })).toBeChecked;

await page.getByLabel("Query name").fill(Math.random().toString());
await expect(actionButton).toBeEnabled();

await input.fill("syp");
await page.getByText(SEARCHED_CONDITION.name, { exact: true }).click();
expect(page.getByText(SEARCHED_CONDITION.name, { exact: true }))
.toBeChecked;

// move to value set selection:
await actionButton.click();

const labsHeader = await page.getByTestId("accordionButton_labs");
const conditionsHeader = await page.getByTestId(
"accordionButton_conditions",
);
const medicationsHeader = await page.getByTestId(
"accordionButton_medications",
);

await expect(labsHeader).toBeVisible();
expect(labsHeader).toContainText(CLICKED_CONDITION.labsCount);

await expect(conditionsHeader).toBeVisible();
expect(conditionsHeader).toContainText(CLICKED_CONDITION.conditionsCount);

await expect(medicationsHeader).toBeVisible();
expect(medicationsHeader).toContainText(CLICKED_CONDITION.medsCount);

expect(actionButton).toContainText("Save query");
expect(backLink).toContainText(BACKLINK_CONDITIONS);

// customize value sets:
await labsHeader.click();
const expandedLabValueSet = page.getByText(
CLICKED_CONDITION.sampleLabValueSet,
{ exact: true },
);
expect(expandedLabValueSet).toBeVisible();
expect(expandedLabValueSet).toBeChecked();

await expandedLabValueSet.click();
await expect(expandedLabValueSet).not.toBeChecked();

await medicationsHeader.click();
const expandedMedValueSet = page.getByText(
CLICKED_CONDITION.sampleMedValueSet,
{ exact: true },
);
expect(expandedLabValueSet).not.toBeVisible();
expect(expandedMedValueSet).toBeVisible();
expect(expandedMedValueSet).toBeChecked();

// customize codes:
const openDrawer = page.getByTestId("drawer-open-true");
await expect(openDrawer).not.toBeVisible();

await expandedMedValueSet.hover();
await page.getByTestId(CLICKED_CONDITION.sampleMedValueSetID).click();
await expect(openDrawer).toBeVisible();

const code = page
.locator("tr", { has: page.getByText(CLICKED_CONDITION.sampleCodeID) })
.getByTestId("checkbox");
await expect(code.getByRole("checkbox")).toBeChecked();

await code.click();
await expect(code.getByRole("checkbox")).not.toBeChecked();

// close the drawer:
const closeBtn = openDrawer.getByLabel("Close drawer");
await closeBtn.click();
await expect(openDrawer).not.toBeVisible();
});

// test("backnav and add/remove data", async ({ page }) => {
});

test.describe("editing an exisiting new query", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Backlink: React.FC<BacklinkProps> = ({ onClick, label }) => {
onClick={onClick}
className="back-link unchanged-color-on-visit text-no-underline"
aria-label="Back arrow indicating ability to navigate back a page if clicked"
data-testid="backArrowLink"
>
<Icon.ArrowBack aria-label="Arrow point left indicating return to previous step" />{" "}
{label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const Drawer: React.FC<DrawerProps> = ({
<div
className={`${styles.drawer} ${isOpen ? styles.open : styles.closed}`}
role="dialog"
data-testid={`drawer-open-${isOpen}`}
>
<div className={styles.drawerContent}>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ const BuildFromTemplates: React.FC<BuildFromTemplatesProps> = ({
? handleCreateQueryClick
: handleSaveQuery
}
data-testid="createSaveQueryBtn"
>
{buildStep == "condition" ? "Customize query" : "Save query"}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,15 @@ const ConceptTypeAccordionBody: React.FC<ConceptTypeAccordionBodyProps> = ({
id={dibbsVs.valueSetId}
checked={checked}
isMinusState={isMinusState}
data-testid={dibbsVs.valueSetId}
/>
</div>
<div className={styles.accordionBodyExpanded__right}>
<div className={styles.displayCount}>
{selectedCount}/{totalCount}
</div>
<div
data-testid={dibbsVs.valueSetId}
className={styles.viewCodesBtn}
role="button"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ export const ValueSetSelection: React.FC<ConditionSelectionProps> = ({
const condition = conditionsDetailsMap[conditionId];
return (
<div
key={conditionId}
data-testid={
activeCondition == conditionId
? "conditionCard-active"
: "conditionCard"
}
className={classNames(
"align-items-center",
activeCondition == conditionId
Expand Down
14 changes: 7 additions & 7 deletions query-connector/src/app/queryBuilding/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import QueryBuilding from "./page";
import { render, screen, waitFor } from "@testing-library/react";
import { DataContext } from "@/app/DataProvider";
import { getConditionsData, getCustomQueries } from "../database-service";
import { conditionIdToNameMap, defaultQueries } from "./fixtures";
import { conditionIdToNameMap, DEFAULT_QUERIES } from "./fixtures";

jest.mock("../database-service", () => ({
getCustomQueries: jest.fn(),
Expand Down Expand Up @@ -32,14 +32,14 @@ describe("tests the query building steps", () => {
expect(screen).toMatchSnapshot();
});
it("renders the default state", async () => {
(getCustomQueries as jest.Mock).mockResolvedValue(defaultQueries);
(getCustomQueries as jest.Mock).mockResolvedValue(DEFAULT_QUERIES);
(getConditionsData as jest.Mock).mockResolvedValue({
conditionIdToNameMap,
});

const mockSetData = jest.fn();
const mockContextValue = {
data: defaultQueries,
data: DEFAULT_QUERIES,
setData: mockSetData,
};

Expand All @@ -49,15 +49,15 @@ describe("tests the query building steps", () => {
</DataContext.Provider>,
);

const expectedQueryNames = defaultQueries.map((q) => q.query_name);
const expectedQueryNames = DEFAULT_QUERIES.map((q) => q.query_name);

await waitFor(() => {
expect(screen.queryByText("Loading")).not.toBeInTheDocument();
});

expect(screen.getByText("Query Library")).toBeInTheDocument();
expectedQueryNames.forEach((name) => {
expect(screen.getByText(name)).toBeInTheDocument();
await expect(screen.getByText("Query Library")).toBeInTheDocument();
expectedQueryNames.forEach(async (name) => {
await expect(screen.getByText(name)).toBeInTheDocument();
});

expect(screen).toMatchSnapshot();
Expand Down
Loading