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

MLR E2E Updates #11389

Merged
merged 36 commits into from Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ccdefe4
Update Overlay page to use submit function
Jul 21, 2023
38716a6
Bring down wait times in cypress tests
Jul 24, 2023
96539ff
Attempt revamp of saving entities in modal overlays
Jul 24, 2023
e3a8fac
Try turning off autosave in overlay
Jul 24, 2023
0dcf00f
Add timeout on authentication
Jul 24, 2023
20e584f
Try clearing session between logins
Jul 24, 2023
33982f9
Remove clear session
Jul 25, 2023
cb8f218
Remove clear session
Jul 25, 2023
56c0473
Remove Timeout
Jul 25, 2023
911a858
Update node version for e2e tests to use nvmrc
Jul 25, 2023
ff7a030
Update to setupnodev3
Jul 25, 2023
c2a60dc
Remove findByText for get and find in form stepdefs
Jul 25, 2023
18d3b57
Remove deprecated xpath and get rid of waitUntil in cypress
Jul 25, 2023
067d253
Update deploy for E2E tests
Jul 25, 2023
0273f76
Swap checkout in e2e test
Jul 25, 2023
564dd54
Remove node setup for e2e tests
Jul 25, 2023
5121172
Fix accessibility deployment
Jul 25, 2023
f960d1d
Add timeout to every get, wait, visit, find call
Jul 26, 2023
0fb9f7e
Remove xpath and waituntil dependencies
Jul 26, 2023
9dcfa0e
Swap out invoke function for get
Jul 26, 2023
af7c702
Reset default timeout to 4 seconds
Jul 26, 2023
7bff752
Remove individual timeouts on each cypress action
Jul 26, 2023
66803b9
Swap table button calls to get method
Jul 26, 2023
bcf6a0d
Add wait swapping between admin and user
Jul 26, 2023
9a32ebe
Turn back on autosave
Jul 27, 2023
c777343
Slightly longer wait on waiting for release
Jul 27, 2023
385246d
Slightly longer wait before setting login to make sure auth call goes…
Jul 27, 2023
7dd49ca
Add tests for submitting for the modaloverlaypage
Jul 27, 2023
6c80116
Add test for entering and closing the overlay for modaloverlay
Jul 27, 2023
a4e7175
Fix footer showing previous on first page and nowhere on mlr
Jul 28, 2023
8d588c3
Fix missing text on MLR Reporting page
Jul 29, 2023
82b20d5
Move EntityProvider to index for neater import
Jul 29, 2023
0ca73e1
Overhaul entire MLR Reporting Page
Jul 29, 2023
ef347c2
Fix up testing definitions
Jul 29, 2023
87867ef
PR cleanup
Jul 29, 2023
46995ad
Add back mobile/tablet view for modal overlay entities
Jul 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/deploy.yml
Expand Up @@ -22,12 +22,9 @@ jobs:
run: ./.github/build-vars.sh set_values
env:
CODE_CLIMATE_ID: ${{ secrets.CODE_CLIMATE_ID }}
- name: read .nvmrc
id: node_version
run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc)
- uses: actions/setup-node@v1
- uses: actions/setup-node@v3
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the deploy updates were an attempt to get Cypress to use the same node version we use. Unfortunately, Cypress doesn't respect the node version you give it. So setting up node doesn't matter. It seems its tied to the git actions node version. Heres a thread with all sorts of other threads to dig down the rabbit hole (cypress-io/github-action#637).

That being said, we were on v1 which was no longer supported, so swapping to v3 here is a solid upgrade.

with:
node-version: ${{ steps.node_version.outputs.NODE_VERSION }}
node-version-file: ".nvmrc"
- uses: actions/cache@v2
with:
path: |
Expand Down Expand Up @@ -89,12 +86,9 @@ jobs:
run: ./.github/github-lock.sh $branch_name
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: read .nvmrc
id: node_version
run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc)
- uses: actions/setup-node@v1
- uses: actions/setup-node@v3
with:
node-version: ${{ steps.node_version.outputs.NODE_VERSION }}
node-version-file: ".nvmrc"
- uses: actions/cache@v2
with:
path: |
Expand Down Expand Up @@ -131,9 +125,11 @@ jobs:
if: ${{ github.ref != 'refs/heads/production' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3

- name: Run Cypress Tests
uses: cypress-io/github-action@v4.2.0
uses: cypress-io/github-action@v5
Comment on lines +128 to +132
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above about attempting to get cypress to use our node version

with:
working-directory: tests/cypress
spec: |
Expand All @@ -148,6 +144,7 @@ jobs:
CYPRESS_STATE_USER_PASSWORD: ${{ secrets.CYPRESS_STATE_USER_PASSWORD }}
CYPRESS_ADMIN_USER_EMAIL: ${{ secrets.CYPRESS_ADMIN_USER_EMAIL }}
CYPRESS_ADMIN_USER_PASSWORD: ${{ secrets.CYPRESS_ADMIN_USER_PASSWORD }}

- name: Upload screenshots
uses: actions/upload-artifact@v2
if: failure()
Expand All @@ -163,9 +160,11 @@ jobs:
if: ${{ github.ref != 'refs/heads/production' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v3

- name: Check Project A11y
uses: cypress-io/github-action@v4.2.0
uses: cypress-io/github-action@v5
with:
working-directory: tests/cypress
spec: tests/accessibility/*.feature
Expand All @@ -179,6 +178,7 @@ jobs:
CYPRESS_ADMIN_USER_EMAIL: ${{ secrets.CYPRESS_ADMIN_USER_EMAIL }}
CYPRESS_ADMIN_USER_PASSWORD: ${{ secrets.CYPRESS_ADMIN_USER_PASSWORD }}
RUN_PA11Y: true

- name: Upload screenshots
uses: actions/upload-artifact@v2
if: failure()
Expand Down
Expand Up @@ -25,8 +25,8 @@ describe("ExportedEntityDetailsTable", () => {

const expectedTextContent = [
"N/A",
"mock modal overlay text field",
"1",
"mock text field",
"mock number field",
"Not answered; required",
];

Expand Down
1 change: 1 addition & 0 deletions services/ui-src/src/components/index.ts
Expand Up @@ -98,6 +98,7 @@ export { ModalDrawerReportPage } from "./reports/ModalDrawerReportPage";
export { ModalOverlayReportPage } from "./reports/ModalOverlayReportPage";
export { ReportPageFooter } from "./reports/ReportPageFooter";
export { ReportContext, ReportProvider } from "./reports/ReportProvider";
export { EntityContext, EntityProvider } from "./reports/EntityProvider";
// statusing
export { StatusTable } from "./statusing/StatusTable";
// tables
Expand Down
199 changes: 135 additions & 64 deletions services/ui-src/src/components/overlays/EntityDetailsOverlay.test.tsx
@@ -1,82 +1,153 @@
import { EntityProvider } from "components/reports/EntityProvider";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Total overhaul of this file. Everything in EntityDetails has been moved around/rewritten and thus needs tests to represent it!

// components
import { EntityDetailsOverlay } from "./EntityDetailsOverlay";
// utils
import {
mockMlrReportContext,
mockAdminUser,
mockEntityDetailsContext,
mockMLRReportEntityStartedFieldData,
mockModalOverlayForm,
mockStateUser,
RouterWrappedComponent,
} from "utils/testing/setupJest";
import { EntityDetailsOverlay } from "./EntityDetailsOverlay";
import form from "../../forms/mlr/mlr.json";
import { EntityType, FormJson } from "types";
import { render } from "@testing-library/react";
import { axe } from "jest-axe";
import userEvent from "@testing-library/user-event";
import { ReportContext } from "components/reports/ReportProvider";

const formJSON: FormJson = form.routes[1].overlayForm!;
const mockClose = jest.fn();
const mockSidebarHidden = jest.fn();

const overlayProps = {
entityType: "program" as EntityType,
verbiage: {},
form: formJSON,
selectedEntity: mockMlrReportContext.report.fieldData.program[1],
closeEntityDetailsOverlay: mockClose,
setSidebarHidden: mockSidebarHidden,
};

const mockUpdate = jest.fn();
const mockedReportContext = {
...mockMlrReportContext,
updateReport: mockUpdate,
};

const entityDetailsOverlay = (
import { useUser } from "utils";
// verbiage
import accordionVerbiage from "../../verbiage/pages/accordion";
import overlayVerbiage from "../../verbiage/pages/overlays";
import { EntityContext } from "components";

const mockCloseEntityDetailsOverlay = jest.fn();
const mockOnSubmit = jest.fn();

jest.mock("utils/auth/useUser");
const mockedUseUser = useUser as jest.MockedFunction<typeof useUser>;

const entityDetailsOverlayComponentStateUser = (
<RouterWrappedComponent>
<ReportContext.Provider value={mockedReportContext}>
<EntityProvider>
<EntityDetailsOverlay {...overlayProps} />
</EntityProvider>
</ReportContext.Provider>
<EntityContext.Provider value={mockEntityDetailsContext}>
<EntityDetailsOverlay
closeEntityDetailsOverlay={mockCloseEntityDetailsOverlay}
entityType={"program"}
entities={[mockMLRReportEntityStartedFieldData.program[0]]}
form={mockModalOverlayForm}
onSubmit={mockOnSubmit}
disabled={false}
selectedEntity={mockMLRReportEntityStartedFieldData.program[0]}
/>
</EntityContext.Provider>
</RouterWrappedComponent>
);

describe("Test EntityDetailsOverlay", () => {
it("Should show a close button", async () => {
const { findByText } = render(entityDetailsOverlay);
expect(await findByText("Return to MLR Reporting")).toBeVisible();
});
const entityDetailsOverlayComponentAdminUser = (
<RouterWrappedComponent>
<EntityContext.Provider value={mockEntityDetailsContext}>
<EntityDetailsOverlay
closeEntityDetailsOverlay={mockCloseEntityDetailsOverlay}
entityType={"program"}
entities={[mockMLRReportEntityStartedFieldData.program[0]]}
form={mockModalOverlayForm}
onSubmit={mockOnSubmit}
disabled={true}
selectedEntity={mockMLRReportEntityStartedFieldData.program[0]}
/>
</EntityContext.Provider>
</RouterWrappedComponent>
);

it("Should invoke the close function when you click the close button.", async () => {
const { findByText } = render(entityDetailsOverlay);
const closeButton = await findByText("Return to MLR Reporting");
await userEvent.click(closeButton);
expect(mockClose).toHaveBeenCalled();
describe("Test EntityDetailsOverlayV2 (empty state)", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("Should set the sidebar hidden on load", () => {
render(entityDetailsOverlay);
expect(mockSidebarHidden).toHaveBeenCalledWith(true);
const user = userEvent.setup();
const selectedEntity = mockMLRReportEntityStartedFieldData.program[0];

it("should render the initial view for a state user", async () => {
mockedUseUser.mockReturnValue(mockStateUser);
render(entityDetailsOverlayComponentStateUser);

// Close out of the Overlay it opened
const closeButton = screen.getByText("Return to MLR Reporting");
expect(closeButton).toBeVisible();

// Check if header is visible on load - H2
expect(
screen.getByText(overlayVerbiage.MLR.intro.subsection)
).toBeVisible();

// Check if accordion is showing
const accordionHeader = accordionVerbiage.MLR.formIntro.buttonLabel;
expect(screen.getByText(accordionHeader)).toBeVisible();

// Check if MLR Report For is showing the correct Entity Data
const reportPlanName = selectedEntity.report_planName;
const reportProgramName = selectedEntity.report_programName;
const eligibilityGroup = selectedEntity.report_eligibilityGroup[0].value;
const reportingPeriod = `${selectedEntity.report_reportingPeriodStartDate} to ${selectedEntity.report_reportingPeriodEndDate}`;

expect(screen.getByText(reportPlanName)).toBeVisible();
expect(screen.getByText(reportProgramName)).toBeVisible();
expect(screen.getByText(eligibilityGroup)).toBeVisible();
expect(screen.getByText(reportingPeriod)).toBeVisible();

// Make sure footer button appears correctly
const saveAndReturn = screen.getByText("Save & return");
expect(saveAndReturn).toBeVisible();
});

it("Should set the sidebar visible on unmount", () => {
const { unmount } = render(entityDetailsOverlay);
unmount();
expect(mockSidebarHidden).toHaveBeenCalledWith(false);
it("should render the initial view for an admin", async () => {
mockedUseUser.mockReturnValue(mockAdminUser);
render(entityDetailsOverlayComponentAdminUser);

// Close out of the Overlay it opened
const closeButton = screen.getByText("Return to MLR Reporting");
expect(closeButton).toBeVisible();

// Check if header is visible on load - H2
expect(
screen.getByText(overlayVerbiage.MLR.intro.subsection)
).toBeVisible();

// Check if accordion is showing
const accordionHeader = accordionVerbiage.MLR.formIntro.buttonLabel;
expect(screen.getByText(accordionHeader)).toBeVisible();

// Check if MLR Report For is showing the correct Entity Data
const reportPlanName = selectedEntity.report_planName;
const reportProgramName = selectedEntity.report_programName;
const eligibilityGroup = selectedEntity.report_eligibilityGroup[0].value;
const reportingPeriod = `${selectedEntity.report_reportingPeriodStartDate} to ${selectedEntity.report_reportingPeriodEndDate}`;

expect(screen.getByText(reportPlanName)).toBeVisible();
expect(screen.getByText(reportProgramName)).toBeVisible();
expect(screen.getByText(eligibilityGroup)).toBeVisible();
expect(screen.getByText(reportingPeriod)).toBeVisible();

// Make sure footer button appears correctly for admins
const returnButton = screen.getByText("Return");
expect(returnButton).toBeVisible();
});

it("Should submit entity info when clicking submit", async () => {
const { findByText } = render(entityDetailsOverlay);
const submitButton = await findByText("Save & return");
await userEvent.click(submitButton);
expect(mockSidebarHidden).toHaveBeenCalledWith(false);
expect(mockClose).toHaveBeenCalled();
it("should call the close overlay function when clicking Return to MLR", async () => {
// Set as State User
mockedUseUser.mockReturnValue(mockStateUser);
render(entityDetailsOverlayComponentStateUser);

// Close out of the Overlay it opened
const closeButton = screen.getByText("Return to MLR Reporting");
await user.click(closeButton);
expect(mockCloseEntityDetailsOverlay).toBeCalled();
});
});

describe("Test EntityDetailsOverlay accessibility", () => {
it("Should not have basic accessibility issues", async () => {
const { container } = render(entityDetailsOverlay);
const results = await axe(container);
expect(results).toHaveNoViolations();
it("should call the close overlay function when clicking Return to MLR as an Admin", async () => {
// Set as State User
mockedUseUser.mockReturnValue(mockAdminUser);
render(entityDetailsOverlayComponentAdminUser);

// Close out of the Overlay it opened
const closeButton = screen.getByText("Return to MLR Reporting");
await user.click(closeButton);
expect(mockCloseEntityDetailsOverlay).toBeCalled();
});
});